Using wallets like XVerse, users can sign a message using their ordinal btc address, let’s say bc1XXX, the message is hashed based on BIP0322.

So I have:

  • User wallet: bc1XXX
  • Message hash: YYY
  • Signature signed by bc1XXX: ZZZ

So this data is sent to my backend server, and I want to verify that ZZZ was indeed signed by bc1XXX (and contains YYY as message).

I’m using this so far:

 const msgHash = bip0322Hash(message); const signatureBuffer = Buffer.from(signatureStr, 'base64'); const decodedSignature = signatureBuffer.slice(2, 66); const recoveryId = signatureBuffer[0]; // Extract public key from the signature const recoveredPublicKeyBuffer = secp.recoverPublicKey( msgHash, decodedSignature, recoveryId, // Recovery ID (0 or 1) false ); console.log(publicKeyToTaprootAddress(recoveredPublicKeyBuffer)); //no match with my original pubkey that signed the message 

But I have a hard time getting the correct address from recoveredPublicKeyBuffer which I can’t match with the public key address of my test set.

I’m trying to use this function, but the output doesn’t match my pubkey:

 function publicKeyToTaprootAddress(publicKey: Uint8Array) { // Compute the SHA-256 hash of the public key const hash = sha256(Buffer.from(publicKey)); // Construct the human-readable part and the data part of the Bech32m string const hrp = 'bc'; const data = sha256(Buffer.from([0x01].concat(Array.from(hash)))); const data2 = bech32m.toWords(Buffer.from(data)); // Encode the Bech32m string return bech32m.encode(hrp, data2); } 

Leave a Reply

Your email address will not be published. Required fields are marked *