I create my signer wallet as follows:

const seed = bip39.mnemonicToSeedSync(WALLET_MNEMONIC, WALLET_PASSWORD);
const privateKeyBuffer = bip32
const keyring = new Keyring({ss58Format: 2});
return keyring.addFromAddress('0x'+privateKeyBuffer.toString("hex"));

and I try to transfer KSM from that account into another one:

const unsub = await api.tx.balances
    .transfer(recipientAddress, amount)
    .signAndSend(signerWallet, (result) => {
        console.log(`Current status is ${result.status}`);
        if (result.status.isInBlock) {
            console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
        } else if (result.status.isFinalized) {
            console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);

However I get that error:

Cannot sign with a locked key pair

What is the problem with my code?

1 Answer 1


You need a private key for the account with which you want to sign a transaction. Signing is done with the private key, verification with the public key.

In the above code an address is added to the keyring with no information about the private key. The addFromAddress is for addressbook functionality or pairs where you don't need the private key at all, for instance a proxied account.

Use addFromPair and supply a Keypair that has both the private and public keys.

  • Thanks, I will try it. Btw, is my Kusama network address creation part is correct?
    – kamaci
    Commented Apr 11, 2022 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.