Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
} else {
msg.setOutputsList([currentTx.getOutputsList()[txRequest.getDetails().getRequestIndex()]])
msg.setOutputsCnt(1)
}
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
if (txRequest.getRequestType() === RequestType.TXEXTRADATA) {
let offset = txRequest.getDetails().getExtraDataOffset()
let length = txRequest.getDetails().getExtraDataLen()
msg = new TransactionType()
msg.setExtraData(currentTx.getExtraData_asU8().slice(offset, offset + length))
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
}
} catch (error) {
console.error({ error })
throw new Error('Failed to sign BTC transaction')
}
if (signatures.includes(null)) {
throw new Error('Some signatures are missing!')
est.setAddressNList(msg.addressNList)
est.setNonce(arrayify(msg.nonce))
est.setGasPrice(arrayify(msg.gasPrice))
est.setGasLimit(arrayify(msg.gasLimit))
if (msg.value.match('^0x0*$') === null) {
est.setValue(arrayify(msg.value))
}
if (msg.toAddressNList) {
est.setAddressType(OutputAddressType.SPEND)
est.setToAddressNList(msg.toAddressNList)
} else if (msg.exchangeType) {
est.setAddressType(OutputAddressType.EXCHANGE)
const signedHex = base64toHEX(msg.exchangeType.signedExchangeResponse)
const signedExchangeOut = SignedExchangeResponse.deserializeBinary(arrayify(signedHex))
const exchangeType = new ExchangeType()
exchangeType.setSignedExchangeResponse(signedExchangeOut)
exchangeType.setWithdrawalCoinName(msg.exchangeType.withdrawalCoinName) // KeepKey firmware will complain if this doesn't match signed exchange response
exchangeType.setWithdrawalAddressNList(msg.exchangeType.withdrawalAddressNList)
exchangeType.setWithdrawalScriptType(translateInputScriptType(
msg.exchangeType.withdrawalScriptType || BTCInputScriptType.SpendAddress))
exchangeType.setReturnAddressNList(msg.exchangeType.returnAddressNList)
exchangeType.setReturnScriptType(translateInputScriptType(
msg.exchangeType.returnScriptType || BTCInputScriptType.SpendAddress))
est.setExchangeType(exchangeType)
} else {
est.setAddressType(OutputAddressType.SPEND)
}
if (msg.to) {
est.setTo(arrayify(msg.to))
est.setNonce(arrayify(msg.nonce))
est.setGasPrice(arrayify(msg.gasPrice))
est.setGasLimit(arrayify(msg.gasLimit))
if (msg.value.match('^0x0*$') === null) {
est.setValue(arrayify(msg.value))
}
if (msg.toAddressNList) {
est.setAddressType(OutputAddressType.SPEND)
est.setToAddressNList(msg.toAddressNList)
} else if (msg.exchangeType) {
est.setAddressType(OutputAddressType.EXCHANGE)
const signedHex = base64toHEX(msg.exchangeType.signedExchangeResponse)
const signedExchangeOut = SignedExchangeResponse.deserializeBinary(arrayify(signedHex))
const exchangeType = new ExchangeType()
exchangeType.setSignedExchangeResponse(signedExchangeOut)
exchangeType.setWithdrawalCoinName(msg.exchangeType.withdrawalCoinName) // KeepKey firmware will complain if this doesn't match signed exchange response
exchangeType.setWithdrawalAddressNList(msg.exchangeType.withdrawalAddressNList)
exchangeType.setWithdrawalScriptType(translateInputScriptType(
msg.exchangeType.withdrawalScriptType || BTCInputScriptType.SpendAddress))
exchangeType.setReturnAddressNList(msg.exchangeType.returnAddressNList)
exchangeType.setReturnScriptType(translateInputScriptType(
msg.exchangeType.returnScriptType || BTCInputScriptType.SpendAddress))
est.setExchangeType(exchangeType)
} else {
est.setAddressType(OutputAddressType.SPEND)
}
if (msg.to) {
est.setTo(arrayify(msg.to))
}
return transport.lockDuring(async () => {
const est: EthereumSignTx = new EthereumSignTx()
est.setAddressNList(msg.addressNList)
est.setNonce(arrayify(msg.nonce))
est.setGasPrice(arrayify(msg.gasPrice))
est.setGasLimit(arrayify(msg.gasLimit))
if (msg.value.match('^0x0*$') === null) {
est.setValue(arrayify(msg.value))
}
if (msg.toAddressNList) {
est.setAddressType(OutputAddressType.SPEND)
est.setToAddressNList(msg.toAddressNList)
} else if (msg.exchangeType) {
est.setAddressType(OutputAddressType.EXCHANGE)
const signedHex = base64toHEX(msg.exchangeType.signedExchangeResponse)
const signedExchangeOut = SignedExchangeResponse.deserializeBinary(arrayify(signedHex))
const exchangeType = new ExchangeType()
exchangeType.setSignedExchangeResponse(signedExchangeOut)
exchangeType.setWithdrawalCoinName(msg.exchangeType.withdrawalCoinName) // KeepKey firmware will complain if this doesn't match signed exchange response
exchangeType.setWithdrawalAddressNList(msg.exchangeType.withdrawalAddressNList)
exchangeType.setWithdrawalScriptType(translateInputScriptType(
msg.exchangeType.withdrawalScriptType || BTCInputScriptType.SpendAddress))
exchangeType.setReturnAddressNList(msg.exchangeType.returnAddressNList)
exchangeType.setReturnScriptType(translateInputScriptType(
msg.exchangeType.returnScriptType || BTCInputScriptType.SpendAddress))
est.setExchangeType(exchangeType)
} else {
est.setAddressType(OutputAddressType.SPEND)
}
return transport.lockDuring(async () => {
const est: EthereumSignTx = new EthereumSignTx()
est.setAddressNList(msg.addressNList)
est.setNonce(arrayify(msg.nonce))
est.setGasPrice(arrayify(msg.gasPrice))
est.setGasLimit(arrayify(msg.gasLimit))
if (msg.value.match('^0x0*$') === null) {
est.setValue(arrayify(msg.value))
}
if (msg.toAddressNList) {
est.setAddressType(OutputAddressType.SPEND)
est.setToAddressNList(msg.toAddressNList)
} else if (msg.exchangeType) {
est.setAddressType(OutputAddressType.EXCHANGE)
const signedHex = base64toHEX(msg.exchangeType.signedExchangeResponse)
const signedExchangeOut = SignedExchangeResponse.deserializeBinary(arrayify(signedHex))
const exchangeType = new ExchangeType()
exchangeType.setSignedExchangeResponse(signedExchangeOut)
exchangeType.setWithdrawalCoinName(msg.exchangeType.withdrawalCoinName) // KeepKey firmware will complain if this doesn't match signed exchange response
exchangeType.setWithdrawalAddressNList(msg.exchangeType.withdrawalAddressNList)
exchangeType.setWithdrawalScriptType(translateInputScriptType(
msg.exchangeType.withdrawalScriptType || BTCInputScriptType.SpendAddress))
exchangeType.setReturnAddressNList(msg.exchangeType.returnAddressNList)
exchangeType.setReturnScriptType(translateInputScriptType(
msg.exchangeType.returnScriptType || BTCInputScriptType.SpendAddress))
est.setExchangeType(exchangeType)
break
}
let currentTx: TransactionType = null
let msg: TransactionType = null
let txAck: TxAck = null
// Device asked for one more information, let's process it.
if (txRequest.hasDetails() && !txRequest.getDetails().hasTxHash()) {
currentTx = txmap['unsigned']
} else {
currentTx = txmap[toHexString(txRequest.getDetails().getTxHash_asU8())]
}
if (txRequest.getRequestType() === RequestType.TXMETA) {
msg = new TransactionType()
msg.setVersion(currentTx.getVersion())
msg.setLockTime(currentTx.getLockTime())
msg.setInputsCnt(currentTx.getInputsCnt())
if (txRequest.getDetails().hasTxHash()) {
msg.setOutputsCnt(currentTx.getBinOutputsList().length)
} else {
msg.setOutputsCnt(currentTx.getOutputsList().length)
}
if (currentTx.hasExtraData()) {
msg.setExtraDataLen(currentTx.getExtraData_asU8().length)
} else {
msg.setExtraDataLen(0)
}
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
continue
}
if (txRequest.getRequestType() === RequestType.TXINPUT) {
msg = new TransactionType()
msg.setInputsList([currentTx.getInputsList()[txRequest.getDetails().getRequestIndex()]])
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
if (txRequest.getRequestType() === RequestType.TXOUTPUT) {
msg = new TransactionType()
if (txRequest.getDetails().hasTxHash()) {
msg.setBinOutputsList([currentTx.getBinOutputsList()[txRequest.getDetails().getRequestIndex()]])
} else {
msg.setOutputsList([currentTx.getOutputsList()[txRequest.getDetails().getRequestIndex()]])
msg.setOutputsCnt(1)
}
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
if (txRequest.getRequestType() === RequestType.TXEXTRADATA) {
let offset = txRequest.getDetails().getExtraDataOffset()
}
if (currentTx.hasExtraData()) {
msg.setExtraDataLen(currentTx.getExtraData_asU8().length)
} else {
msg.setExtraDataLen(0)
}
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
if (txRequest.getRequestType() === RequestType.TXINPUT) {
msg = new TransactionType()
msg.setInputsList([currentTx.getInputsList()[txRequest.getDetails().getRequestIndex()]])
txAck = new TxAck()
txAck.setTx(msg)
let message = await transport.call(MessageType.MESSAGETYPE_TXACK, txAck, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message.message_enum
response = message.proto
continue
}
if (txRequest.getRequestType() === RequestType.TXOUTPUT) {
msg = new TransactionType()
if (txRequest.getDetails().hasTxHash()) {
msg.setBinOutputsList([currentTx.getBinOutputsList()[txRequest.getDetails().getRequestIndex()]])
} else {
msg.setOutputsList([currentTx.getOutputsList()[txRequest.getDetails().getRequestIndex()]])
msg.setOutputsCnt(1)
tx.setLockTime(msg.locktime || 0)
let responseType: number
let response: any
const { message_enum, proto } = await transport.call(MessageType.MESSAGETYPE_SIGNTX, tx, LONG_TIMEOUT, /*omitLock=*/true) as Event // 5 Minute timeout
responseType = message_enum
response = proto
// Prepare structure for signatures
const signatures: string[] = new Array(msg.inputs.length).fill(null)
let serializedTx: string = ''
try {
// Begin callback loop
while (true) {
if (responseType === MessageType.MESSAGETYPE_FAILURE) {
const errorResponse = response as Failure
throw new Error(`Signing failed: ${errorResponse.getMessage()}`)
}
if (responseType !== MessageType.MESSAGETYPE_TXREQUEST) {
throw new Error(`Unexpected message type: ${responseType}`)
}
let txRequest = response as TxRequest
// If there's some part of signed transaction, add it
if (txRequest.hasSerialized() && txRequest.getSerialized().hasSerializedTx()) {
serializedTx += toHexString(txRequest.getSerialized().getSerializedTx_asU8())
}
if (txRequest.hasSerialized() && txRequest.getSerialized().hasSignatureIndex()) {
outputs.forEach((o, k) => {
const output: BTCSignTxOutput = o
const newOutput = new TxOutputType()
newOutput.setAmount(Number(output.amount))
if (output.exchangeType) {
// convert the base64 encoded signedExchangeResponse message into the correct object
const signedHex = base64toHEX(output.exchangeType.signedExchangeResponse)
const signedExchange = SignedExchangeResponse.deserializeBinary(arrayify(signedHex))
// decode the deposit amount from a little-endian Uint8Array into an unsigned uint64
let depAmt = signedExchange.getResponsev2().getDepositAmount_asU8()
let val = 0
for (let jj = depAmt.length - 1; jj >= 0; jj--) {
val += depAmt[jj] * Math.pow(2,(8 * (depAmt.length - jj - 1)))
// TODO validate is uint64
}
const outExchangeType = new ExchangeType()
outExchangeType.setSignedExchangeResponse(signedExchange)
outExchangeType.setWithdrawalCoinName(output.exchangeType.withdrawalCoinName)
outExchangeType.setWithdrawalAddressNList(output.exchangeType.withdrawalAddressNList)
outExchangeType.setWithdrawalScriptType(translateInputScriptType(
output.exchangeType.withdrawalScriptType || BTCInputScriptType.SpendAddress))
outExchangeType.setReturnAddressNList(output.exchangeType.returnAddressNList)
outExchangeType.setReturnScriptType(translateInputScriptType(