web3dart
web3dart copied to clipboard
Credentials.signToUint8List fails with RangeError
Hi there,
I'm looking to sign a message to create an AuthSig for LitProtocol. I've been testing the signToUint8List (and signPersonalMessageToUint8List) functions for that.
Unfortunately both of them fail with a Range error:
RangeError (RangeError (start): Invalid value: Not in inclusive range 0..32: -32)
Seems like some internal problem with the pointycastle/signers/ecdsa_signer.dart.
I've been generating my Wallet from a mnemonic like this:
// Function to handle mnemonic phrase creation
Future<String> createMnemonicPhrase() async {
final mnemonic = bip39.generateMnemonic();
return mnemonic;
}
// Function to handle the creation of an Ethereum wallet from a mnemonic phrase
Future<EthPrivateKey> createEthWalletFromMnemonic(String mnemonic) async {
// Generate a seed from the mnemonic phrase
final seedHex = bip39.mnemonicToSeedHex(mnemonic);
// Create a new Ethereum wallet from the seed
final EthPrivateKey credentials = EthPrivateKey.fromHex(seedHex);
return credentials;
}
This yields a seemingly correct 64 byte private key, and normal looking address:
Eth Wallet Address: 0xe2895995b51f6509c4d1814e13bfc80925dc67ed
Then, to sign, I'm running this:
String message = "Hello World";
final messageBytes = ascii.encode(message);
// Sign the payload using the user's Ethereum wallet (credentials is type EthPrivateKey)
final signature = credentials.signPersonalMessageToUint8List(messageBytes);
This fails with the above mentioned error message. I've also tried hashing the message to a 32 byte Uint8List using keccak256, that has yielded the same result:
// Convert the message to bytes
final messageBytes = ascii.encode(message);
// hash the payload using keccak256
final digest = KeccakDigest(256);
final payload = digest.process(messageBytes);
final signature = credentials.signPersonalMessageToUint8List(messageBytes);
Any ideas what might be wrong here? I'm a little out of my depth here 🙃
For some more context, this is a screenshot of the entire call stack for the error:
Found the Issue myself. It wasn't actually a problem with constructing the signature, the failure was with creating the Wallet from the mnemonic phrase. Here's the right way to do that.
// Function to handle the creation of an Ethereum wallet from a mnemonic phrase
Future<EthPrivateKey> createEthWalletFromMnemonic(String mnemonic) async {
// Constants
String hdPath = "m/44'/60'/0'/0";
final isValidMnemonic = bip39.validateMnemonic(mnemonic);
if (!isValidMnemonic) {
throw 'Invalid mnemonic';
}
final seed = bip39.mnemonicToSeed(mnemonic);
final root = bip32.BIP32.fromSeed(seed);
const first = 0;
final firstChild = root.derivePath("$hdPath/$first");
final privateKey = HEX.encode(firstChild.privateKey as List<int>);
// Create a new Ethereum wallet from the seed
final EthPrivateKey credentials = EthPrivateKey.fromHex(privateKey);
return credentials;
}