Jump to content

How to sign with a hex private key


robmdee

Recommended Posts

New to XRP I made the mistake of importing a hex private key (not the secret key beginning with an "s") from ian coleman's BIP39 tool into a wallet that accepted the key producing the corresponding public key leading me to believe I was good-to-go but the wallet fails to sent. Apparently I'm not the first to make this mistake but the most recent solution I can find is from 4 years ago referencing a tool that enabled signing with a hex key however the tool is not presently active on the main network.
https://ripplerm.github.io/ripple-wallet/

Any insight on how to sign a transition with a hex key would be greatly appreciated. thx

Link to comment
Share on other sites

2 hours ago, robmdee said:

New to XRP I made the mistake of importing a hex private key (not the secret key beginning with an "s") from ian coleman's BIP39 tool into a wallet that accepted the key producing the corresponding public key leading me to believe I was good-to-go but the wallet fails to sent. Apparently I'm not the first to make this mistake but the most recent solution I can find is from 4 years ago referencing a tool that enabled signing with a hex key however the tool is not presently active on the main network.
https://ripplerm.github.io/ripple-wallet/

Any insight on how to sign a transition with a hex key would be greatly appreciated. thx

Man, I really love your avatar ! :D

With regards to your question, I'm not sure there is a tool available, you could try Bithomp or Xumm if they have this built in. Meanwhile, if you know a tiny little of how to run a node-js script you could try the following code (replace with your own privKey and regularKey and set to mainnet), it will set a regular key to your account, so thereafter you can use this regular key for signing:

const xrpl = require('xrpl');
const secp256k1 = require ('secp256k1');

// sample 24 words used in bip39
// convince squirrel hint suggest neither venture quantum enroll vibrant topple cross cliff maid empty love bundle unfold end eight resource basic police wave lawsuit

const privKey = '91452c7398fda2a299cb5ab6764d1af0ec7af4c52a168eec780d7869db77e706'; // hex private key
const regularKey = 'r48snMtYsbQdHX6JZvYkvQNBZ5BinKzMHQ'; // address from the new signing key

async function main () {
  // derive public key
  const pubKey = Buffer.from(secp256k1.publicKeyCreate(Buffer.from(privKey, 'hex'))).toString('hex');
  const wallet = new xrpl.Wallet(pubKey, privKey);
  // check wallet address
  console.log(wallet.address);

  const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233'); // testnet
  // const client = new xrpl.Client('wss://xrpl.ws'); // mainnet
  await client.connect();

  const prepared = await client.autofill({
    TransactionType: 'SetRegularKey',
    Account: wallet.address,
    RegularKey: regularKey
  })
  const signed = wallet.sign(prepared);
  const tx = await client.submitAndWait(signed.tx_blob);
  // show transaction result
  console.log(tx);

  client.disconnect();
}
main();

 

Link to comment
Share on other sites

Update: Xumm founder "Pepperew" responded in reddit with this solution!
"Good news: we added (hidden) support for this in Xumm wallet. If you import an account and select "family seed", you can also paste / enter a hex private key there as obtained from other tools. If you have a 64 hex char private key, prefix 00 (two zeroes).
-----
Close w/Xumm which allows using a mnemonic and even tweaking the derivation stating with m/44'/144'/ but unfortunately in my haste I went with the m/0 derivation so all I have is the 64 digit privkey, Bithomp seems a bit of a black-box.

re: node-js..  relative newb but contrasting your code sample to another solution from 4 yrs ago I noted the library changed to xrpl from ripplenet which I presume is deprecated so that's one addt. piece of the puzzle.
https://runkit.com/wietsewind/sign-xrp-tx-using-hex-privatekey/2.0.0

I can see recovering the account will be a summer project, but would it be safe to say that with 64 digit prikey in-hand it's doable, perhaps in a runkit environment?

btw, like your version of the stealth kryptonite avatar!

Edited by robmdee
Link to comment
Share on other sites

1 hour ago, robmdee said:

close w/xumm which allows using a mnemonic and even tweaking the derivation stating with m/44'/144'/ but unfortunately in my haste I went with the m/0 derivation so all I have is the 64 digit privkey, Bithomp seems a bit of a black-box.

re: node-js..  relative newb but contrasting your code sample to another solution from 4 yrs ago I noted the library changed to xrpl from ripplenet which I presume is deprecated so that's one addt. piece of the puzzle.
https://runkit.com/wietsewind/sign-xrp-tx-using-hex-privatekey/2.0.0

I can see recovering the account will be a summer project, but would it be safe to say that with 64 digit prikey in-hand it's doable, perhaps in a runkit environment?

btw, like your version of the stealth kryptonite avatar!

I think it might work in a runkit environment, as long as it can run nodejs.

It's a bit of a rainy boring Sunday, so I built a quick html page. You can use this also (copy/paste the code in a file e.g. "setregkey.html" and open it in your browser. You must then set the 3 fields, private key, regular key and connectWSS:

<head>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">

  <script src="https://unpkg.com/xrpl@2.0.0/build/xrpl-latest-min.js"></script>
  <script src="https://unpkg.com/bn.js@4.11.8/lib/bn.js" type="text/javascript"></script>
  <script src="https://unpkg.com/@enumatech/secp256k1-js@1.0.0/src/secp256k1.js" type="text/javascript"></script>
  <script>
    async function main() {
      const privKey = document.getElementById("privateHexKey").value
      const connectWss = document.getElementById("connectWss").value
      const regularKey = document.getElementById("regularKeyAddress").value
      // derive public key
      const publicKeyRaw = Secp256k1.generatePublicKeyFromPrivateKeyData(Secp256k1.uint256(privKey, 16))
      const parity = Secp256k1.uint256(publicKeyRaw.y).isEven() ? '02' : '03';
      const pubKey = parity + publicKeyRaw.x;

      const wallet = new xrpl.Wallet(pubKey, privKey);
      // check wallet address
      console.log(wallet.address);

      const client = new xrpl.Client(connectWss);
      await client.connect();

      const prepared = await client.autofill({
        TransactionType: 'SetRegularKey',
        Account: wallet.address,
        RegularKey: regularKey
      })
      const signed = wallet.sign(prepared);
      const tx = await client.submitAndWait(signed.tx_blob);
      // show transaction result
      console.log(tx);
      document.getElementById("result").innerText = JSON.stringify(tx.result, null, 2);
      client.disconnect();
    }
  </script>
</head>

<body>
  <br>
  <div class="container">
    <div class="input-group mb-3">
      <span class="input-group-text" id="private-hex-key">Private hexadecimal key</span>
      <input type="text" class="form-control" id="privateHexKey">
    </div>

    <div class="input-group mb-3">
      <span class="input-group-text" id="regular-key-address">Regular key address</span>
      <input type="text" class="form-control" id="regularKeyAddress">
    </div>

    <div class="input-group mb-3">
      <span class="input-group-text" id="connect-wss">Connect WSS</span>
      <input type="text" class="form-control" id="connectWss">
    </div>

    <button type="button" class="btn btn-primary" onclick="main()">Go</button>
  </div>
  <br>
  <div class="container">
    <div id="result"></div>
  </div>
</body>

 

Link to comment
Share on other sites

The quick and easy way to reuse that hex key to sign transactions is to use Xumm. They support importing a 64 bit hex key from the Ian coleman bip39 tool although it's a hidden feature.

Just make sure you add two hex zeroes in front to make it 66 characters long for Xumm as this is their way of ensuring you don't make a mistake opting to import a raw key.

This is a log from the tweet from Xumm Support

Quote

Quote Tweet

I exported the hex private key from coinomi wallet.. they don’t use family seed. This is the tweet from Xumm support that says using a hex private key is possible:

Yes there is, it's a hidden feature. When importing a new account choose the family seed and fill in your HEX private key. XUMM will recognize the key and import your account with full functions.

This feature was put in this release: XUMM Beta 3 (0.4.1) — wietse

If it's 32 pairs (64 chars) long it's not a valid XRPL HEX private key. XPRL private keys in HEX format are 66 chars long. The XRPL HEX private keys always start with two leading zeroes. To prevent users from making mistakes, we block importing private keys in non XRPL format.

 

 

Link to comment
Share on other sites

29 minutes ago, richxrp said:

The quick and easy way to reuse that hex key to sign transactions is to use Xumm. They support importing a 64 bit hex key from the Ian coleman bip39 tool although it's a hidden feature.

Just make sure you add two hex zeroes in front to make it 66 characters long for Xumm as this is their way of ensuring you don't make a mistake opting to import a raw key.

This is a log from the tweet from Xumm Support

 

indeed 64 digit keys from the BIP39 tool prefaced by '00' import into Xumm which, unlike the "other" wallet that accepted the hex key but couldn't sign, xumm was able to sign. very nice software and helpful culture over at xumm, and here. thx

Edited by robmdee
Link to comment
Share on other sites

On 5/29/2022 at 11:19 AM, jn_r said:

I think it might work in a runkit environment, as long as it can run nodejs.

It's a bit of a rainy boring Sunday, so I built a quick html page. You can use this also (copy/paste the code in a file e.g. "setregkey.html" and open it in your browser. You must then set the 3 fields, private key, regular key and connectWSS:

<head>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">

  <script src="https://unpkg.com/xrpl@2.0.0/build/xrpl-latest-min.js"></script>
  <script src="https://unpkg.com/bn.js@4.11.8/lib/bn.js" type="text/javascript"></script>
  <script src="https://unpkg.com/@enumatech/secp256k1-js@1.0.0/src/secp256k1.js" type="text/javascript"></script>
  <script>
    async function main() {
      const privKey = document.getElementById("privateHexKey").value
      const connectWss = document.getElementById("connectWss").value
      const regularKey = document.getElementById("regularKeyAddress").value
      // derive public key
      const publicKeyRaw = Secp256k1.generatePublicKeyFromPrivateKeyData(Secp256k1.uint256(privKey, 16))
      const parity = Secp256k1.uint256(publicKeyRaw.y).isEven() ? '02' : '03';
      const pubKey = parity + publicKeyRaw.x;

      const wallet = new xrpl.Wallet(pubKey, privKey);
      // check wallet address
      console.log(wallet.address);

      const client = new xrpl.Client(connectWss);
      await client.connect();

      const prepared = await client.autofill({
        TransactionType: 'SetRegularKey',
        Account: wallet.address,
        RegularKey: regularKey
      })
      const signed = wallet.sign(prepared);
      const tx = await client.submitAndWait(signed.tx_blob);
      // show transaction result
      console.log(tx);
      document.getElementById("result").innerText = JSON.stringify(tx.result, null, 2);
      client.disconnect();
    }
  </script>
</head>

<body>
  <br>
  <div class="container">
    <div class="input-group mb-3">
      <span class="input-group-text" id="private-hex-key">Private hexadecimal key</span>
      <input type="text" class="form-control" id="privateHexKey">
    </div>

    <div class="input-group mb-3">
      <span class="input-group-text" id="regular-key-address">Regular key address</span>
      <input type="text" class="form-control" id="regularKeyAddress">
    </div>

    <div class="input-group mb-3">
      <span class="input-group-text" id="connect-wss">Connect WSS</span>
      <input type="text" class="form-control" id="connectWss">
    </div>

    <button type="button" class="btn btn-primary" onclick="main()">Go</button>
  </div>
  <br>
  <div class="container">
    <div id="result"></div>
  </div>
</body>

 

much appreciated your taking the time to create that page which I'll keep for a rainy day to exam in my sandbox now that the turnkey Xumm solution panned-out. thx.

Edited by robmdee
Link to comment
Share on other sites

In Xumm we use our own https://www.npmjs.com/package/xrpl-accountlib - this lib. supports deriving & signing with:

- Secret numbers

- Family seed

- Mnemonic

- Hex Private Key 

https://github.com/WietseWind/xrpl-accountlib#private-key-libderiveprivatekeyhex

This lib. also works browserified.

Edited by Wietse
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...