UNPKG

@atomiqlabs/sdk

Version:

atomiq labs SDK for cross-chain swaps between smart chains and bitcoin

175 lines (174 loc) 6.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSenderAddress = exports.getVoutIndex = exports.parsePsbtTransaction = exports.getDummyAddress = exports.getDummyOutputScript = exports.toCoinselectAddressType = exports.toOutputScript = exports.fromOutputScript = void 0; const utils_1 = require("@scure/btc-signer/utils"); const buffer_1 = require("buffer"); const btc_signer_1 = require("@scure/btc-signer"); const Utils_1 = require("./Utils"); function fromOutputScript(network, outputScriptHex) { return (0, btc_signer_1.Address)(network).encode(btc_signer_1.OutScript.decode(buffer_1.Buffer.from(outputScriptHex, "hex"))); } exports.fromOutputScript = fromOutputScript; function toOutputScript(network, address) { const outputScript = (0, btc_signer_1.Address)(network).decode(address); switch (outputScript.type) { case "pkh": case "sh": case "wpkh": case "wsh": return buffer_1.Buffer.from(btc_signer_1.OutScript.encode({ type: outputScript.type, hash: outputScript.hash })); case "tr": try { return buffer_1.Buffer.from(btc_signer_1.OutScript.encode({ type: "tr", pubkey: outputScript.pubkey })); } catch (e) { let msg = ""; if (e.name != null) msg += ": " + e.name; if (e.message != null) msg += ": " + e.message; if (typeof (e) === "string") msg += ": " + e; msg += ", isBytes: " + (0, utils_1.isBytes)(outputScript.pubkey); try { (0, utils_1.validatePubkey)(outputScript.pubkey, utils_1.PubT.schnorr); msg += ", validatePubkey: success"; } catch (e) { msg += ", validatePubkeyError: "; if (e.name != null) msg += ": " + e.name; if (e.message != null) msg += ": " + e.message; if (typeof (e) === "string") msg += ": " + e; } throw new Error(msg); } } throw new Error(`Unrecognized output script type: ${outputScript.type}`); } exports.toOutputScript = toOutputScript; function toCoinselectAddressType(outputScript) { const data = btc_signer_1.OutScript.decode(outputScript); switch (data.type) { case "pkh": return "p2pkh"; case "sh": return "p2sh-p2wpkh"; case "wpkh": return "p2wpkh"; case "wsh": return "p2wsh"; case "tr": return "p2tr"; } throw new Error("Unrecognized address type!"); } exports.toCoinselectAddressType = toCoinselectAddressType; function getDummySpec(type) { switch (type) { case "p2pkh": return { type: "pkh", hash: (0, Utils_1.randomBytes)(20) }; case "p2sh-p2wpkh": return { type: "sh", hash: (0, Utils_1.randomBytes)(20) }; case "p2wpkh": return { type: "wpkh", hash: (0, Utils_1.randomBytes)(20) }; case "p2wsh": return { type: "wsh", hash: (0, Utils_1.randomBytes)(32) }; case "p2tr": return { type: "tr", pubkey: buffer_1.Buffer.from("0101010101010101010101010101010101010101010101010101010101010101", "hex") }; } throw new Error("Unrecognized address type!"); } function getDummyOutputScript(type) { return btc_signer_1.OutScript.encode(getDummySpec(type)); } exports.getDummyOutputScript = getDummyOutputScript; function getDummyAddress(network, type) { return (0, btc_signer_1.Address)(network).encode(getDummySpec(type)); } exports.getDummyAddress = getDummyAddress; /** * General parsers for PSBTs, can parse hex or base64 encoded PSBTs * @param _psbt */ function parsePsbtTransaction(_psbt) { if (typeof (_psbt) === "string") { let rawPsbt; if (/^(?:[0-9a-fA-F]{2})+$/.test(_psbt)) { //Hex rawPsbt = buffer_1.Buffer.from(_psbt, "hex"); } else if (/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(_psbt)) { //Base64 rawPsbt = buffer_1.Buffer.from(_psbt, "base64"); } else { throw new Error("Provided psbt string not base64 nor hex encoded!"); } return btc_signer_1.Transaction.fromPSBT(rawPsbt, { allowUnknownOutputs: true, allowUnknownInputs: true, allowLegacyWitnessUtxo: true, }); } else { return _psbt; } } exports.parsePsbtTransaction = parsePsbtTransaction; function getVoutIndex(psbt, network, address, amount) { const script = toOutputScript(network, address); for (let i = 0; i < psbt.outputsLength; i++) { const output = psbt.getOutput(i); if (output.amount === amount && output.script != null && script.equals(buffer_1.Buffer.from(output.script))) { return i; } } } exports.getVoutIndex = getVoutIndex; function getSenderAddress(psbt, network, inputIndex = 0) { if (psbt.inputsLength <= inputIndex) return undefined; const input = psbt.getInput(inputIndex); let script; if (input.witnessUtxo?.script != null) { script = input.witnessUtxo.script; } else if (input.nonWitnessUtxo != null && input.index != null) { script = input.nonWitnessUtxo.outputs[input.index]?.script; } if (script == null) return undefined; try { return (0, btc_signer_1.Address)(network).encode(btc_signer_1.OutScript.decode(script)); } catch (e) { return buffer_1.Buffer.from(script).toString("hex"); } } exports.getSenderAddress = getSenderAddress;