UNPKG

@exodus/bip322-js

Version:

A Javascript library that provides utility functions related to the BIP-322 signature scheme

69 lines (68 loc) 2.25 kB
import { hashSync } from '@exodus/crypto/hash'; import * as bitcoin from '@exodus/bitcoinjs'; class BIP322 { static TAG = Buffer.from('BIP0322-signed-message'); static hashMessage(message) { const tagHash = hashSync('sha256', this.TAG); return hashSync('sha256', [tagHash, tagHash, Buffer.from(message)]); } static buildToSpendTx(message, scriptPublicKey) { const psbt = new bitcoin.Psbt(); psbt.setVersion(0); psbt.setLocktime(0); const messageHash = this.hashMessage(message); const scriptSigPartOne = new Uint8Array([0x00, 0x20]); const scriptSig = new Uint8Array(scriptSigPartOne.length + messageHash.length); scriptSig.set(scriptSigPartOne); scriptSig.set(messageHash, scriptSigPartOne.length); psbt.addInput({ hash: '0'.repeat(64), index: 0xff_ff_ff_ff, sequence: 0, finalScriptSig: Buffer.from(scriptSig), witnessScript: Buffer.from([]), }); psbt.addOutput({ value: 0, script: scriptPublicKey, }); return psbt.extractTransaction(); } static buildToSignTx(toSpendTxId, witnessScript, isRedeemScript = false, tapInternalKey) { const psbt = new bitcoin.Psbt(); psbt.setVersion(0); psbt.setLocktime(0); psbt.addInput({ hash: toSpendTxId, index: 0, sequence: 0, witnessUtxo: { script: witnessScript, value: 0, }, }); if (isRedeemScript) { psbt.updateInput(0, { redeemScript: witnessScript, }); } if (tapInternalKey) { psbt.updateInput(0, { tapInternalKey, }); } psbt.addOutput({ value: 0, script: Buffer.from([0x6a]), }); return psbt; } static encodeWitness(signedPsbt) { const witness = signedPsbt.data.inputs[0]?.finalScriptWitness; if (witness) { return witness.toString('base64'); } throw new Error('Cannot encode empty witness stack.'); } } export default BIP322;