Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
txTmp.network = bitcoin.networks.testnet;
}
for (var i = 0; i < outputs.length; i++) {
txTmp.addOutput(outputs[i].address, outputs[i].amountSats.toNumber());
}
for (var j = 0; j < inputs.length; j++) {
txTmp.addInput(inputs[j].txid, inputs[j].index)
}
let txToSign = txTmp.buildIncomplete();
const txHex = txToSign.toHex()
const addressType = multisigAddressType(inputs[0].multisig); // TODO: multiple inputs?
const segwit = addressType == MULTISIG_ADDRESS_TYPES.P2SH_P2WSH || addressType == MULTISIG_ADDRESS_TYPES.P2WSH
let splitTx = await ledgerbtc.splitTransaction(txHex, segwit);
let outputScriptHex = await ledgerbtc.serializeTransactionOutputs(splitTx).toString('hex');
const ledgerIns = inputs.map(input => ledgerInput(ledgerbtc, input));
// BIP32 PATH
let ledger_bip32_path = path.split("/").slice(1).join("/");
let ledgerKeySets = Array(inputs.length).fill(ledger_bip32_path); //array[bip32]
// SIGN
let signatures = await ledgerbtc.signP2SHTransaction(
ledgerIns,
ledgerKeySets,
}
for (var i = 0; i < outputs.length; i++) {
txTmp.addOutput(outputs[i].address, outputs[i].amountSats.toNumber());
}
for (var j = 0; j < inputs.length; j++) {
txTmp.addInput(inputs[j].txid, inputs[j].index)
}
let txToSign = txTmp.buildIncomplete();
const txHex = txToSign.toHex()
const addressType = multisigAddressType(inputs[0].multisig); // TODO: multiple inputs?
const segwit = addressType == MULTISIG_ADDRESS_TYPES.P2SH_P2WSH || addressType == MULTISIG_ADDRESS_TYPES.P2WSH
let splitTx = await ledgerbtc.splitTransaction(txHex, segwit);
let outputScriptHex = await ledgerbtc.serializeTransactionOutputs(splitTx).toString('hex');
const ledgerIns = inputs.map(input => ledgerInput(ledgerbtc, input));
// BIP32 PATH
let ledger_bip32_path = path.split("/").slice(1).join("/");
let ledgerKeySets = Array(inputs.length).fill(ledger_bip32_path); //array[bip32]
// SIGN
let signatures = await ledgerbtc.signP2SHTransaction(
ledgerIns,
ledgerKeySets,
outputScriptHex
messages() {
const messages = super.messages();
const bip32PathSegments = (this.bip32Path || '').split('/');
if (bip32PathSegments.length < 4) { // m, 45', 0', 0', ...
messages[PENDING].push({level: ERROR, text: "BIP32 path must be at least depth 3.", code: "trezor.bip32_path.minimum"});
} else {
const coinPath = bip32PathSegments[2];
if (this.network === NETWORKS.MAINNET) {
if (! coinPath.match(/^0'/)) {
messages[ACTIVE].push({level: WARNING, text: "On Trezor model T the screen may display a 'Confirm path' warning message.", code: "trezor.bip32_path.mismatch"});
}
}
if (this.network === NETWORKS.TESTNET) {
if (! coinPath.match(/^1'/)) {
messages[ACTIVE].push({level: WARNING, text: "On Trezor model T the screen may display a 'Confirm path' warning message.'", code: "trezor.bip32_path.mismatch"});
}
}
}
messages[ACTIVE].push({level: INFO, text: "Confirm in the Trezor Connect window that you want to 'Export public key'. You may be prompted to enter your PIN.", code: "trezor.popup.export_hdnode"});
return messages;
}
messages() {
const messages = super.messages();
const bip32PathSegments = (this.bip32Path || '').split('/');
if (bip32PathSegments.length < 4) { // m, 45', 0', 0', ...
messages[PENDING].push({level: ERROR, text: "BIP32 path must be at least depth 3.", code: "trezor.bip32_path.minimum"});
} else {
const coinPath = bip32PathSegments[2];
if (this.network === NETWORKS.MAINNET) {
if (! coinPath.match(/^0'/)) {
messages[ACTIVE].push({level: WARNING, text: "On Trezor model T the screen may display a 'Confirm path' warning message.", code: "trezor.bip32_path.mismatch"});
}
}
if (this.network === NETWORKS.TESTNET) {
if (! coinPath.match(/^1'/)) {
messages[ACTIVE].push({level: WARNING, text: "On Trezor model T the screen may display a 'Confirm path' warning message.'", code: "trezor.bip32_path.mismatch"});
}
}
}
messages[ACTIVE].push({level: INFO, text: "Confirm in the Trezor Connect window that you want to 'Export public key'. You may be prompted to enter your PIN.", code: "trezor.popup.export_hdnode"});
return messages;
}
function ledgerInput(ledgerbtc, input) {
const addressType = multisigAddressType(input.multisig);
const tx = ledgerbtc.splitTransaction(input.transactionHex, true)
if (addressType == MULTISIG_ADDRESS_TYPES.P2SH) {
return [tx, input.index, scriptToHex(multisigRedeemScript(input.multisig))];
} else {
return [tx, input.index, scriptToHex(multisigWitnessScript(input.multisig))];
}
}
function trezorInput(input, bip32Path) {
const requiredSigners = multisigRequiredSigners(input.multisig);
const addressType = multisigAddressType(input.multisig)
const spendType = addressScriptTypes[addressType]
return {
script_type: spendType,
multisig: {
m: requiredSigners,
pubkeys: multisigPublicKeys(input.multisig).map((publicKey) => trezorPublicKey(publicKey)),
signatures: Array(requiredSigners).fill(''),
},
prev_hash: input.txid,
prev_index: input.index,
address_n: bip32PathToSequence(bip32Path),
amount: input.amountSats.toString()
};
}
inputsAreSupported() {
if (this.inputs && this.inputs.length) {
for (let i=0; i < this.inputs.length; i++) {
const input = this.inputs[i];
const inputAddressType = multisigAddressType(input.multisig);
if (inputAddressType !== MULTISIG_ADDRESS_TYPES.P2SH) {
this.inputAddressType = inputAddressType
return false;
}
}
}
return true
}
{this.renderScript("Script", multisig)}
{redeemScript && this.renderScript("Redeem Script", redeemScript)}
{witnessScript && this.renderScript("Witness Script", witnessScript)}
);
}
function ledgerInput(ledgerbtc, input) {
const addressType = multisigAddressType(input.multisig);
const tx = ledgerbtc.splitTransaction(input.transactionHex, true)
if (addressType == MULTISIG_ADDRESS_TYPES.P2SH) {
return [tx, input.index, scriptToHex(multisigRedeemScript(input.multisig))];
} else {
return [tx, input.index, scriptToHex(multisigWitnessScript(input.multisig))];
}
}
signatureRequestData() {
const hermitInputsByRedeemScript = {};
for (let i=0; i < this.inputs.length; i++) {
const input = this.inputs[i];
const bip32Path = this.bip32Paths[i];
const redeemScriptHex = scriptToHex(multisigRedeemScript(input.multisig));
if (! hermitInputsByRedeemScript[redeemScriptHex]) {
hermitInputsByRedeemScript[redeemScriptHex] = [redeemScriptHex, bip32Path];
}
hermitInputsByRedeemScript[redeemScriptHex].push({
txid: input.txid,
index: input.index,
amount: input.amountSats.toNumber(),
});
}
return {
inputs: Object.values(hermitInputsByRedeemScript),
outputs: this.outputs.map((output) => ({
address: output.address,
amount: output.amountSats.toNumber(),
})),
};