Socket
Socket
Sign inDemoInstall

@binance-chain/bsc-ledger-bridge-keyring

Package Overview
Dependencies
73
Maintainers
4
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.2 to 0.6.3

290

index.js
const { EventEmitter } = require('events')
const HDKey = require('hdkey')
const ethUtil = require('ethereumjs-util')
const sigUtil = require('eth-sig-util')
const { TransactionFactory } = require('@ethereumjs/tx')
// const sigUtil = require('eth-sig-util')
// const { TransactionFactory } = require('@ethereumjs/tx')

@@ -56,6 +56,2 @@ const pathBase = 'm'

this.accountDetails = opts.accountDetails || {}
if (!opts.accountDetails) {
this._migrateAccountDetails(opts)
}
this.implementFullBIP44 = opts.implementFullBIP44 || false

@@ -70,29 +66,2 @@

_migrateAccountDetails (opts) {
if (this._isLedgerLiveHdPath() && opts.accountIndexes) {
for (const account of Object.keys(opts.accountIndexes)) {
this.accountDetails[account] = {
bip44: true,
hdPath: this._getPathForIndex(opts.accountIndexes[account]),
}
}
}
// try to migrate non-LedgerLive accounts too
if (!this._isLedgerLiveHdPath()) {
this.accounts
.filter((account) => !Object.keys(this.accountDetails).includes(ethUtil.toChecksumAddress(account)))
.forEach((account) => {
try {
this.accountDetails[ethUtil.toChecksumAddress(account)] = {
bip44: false,
hdPath: this._pathFromAddress(account),
}
} catch (e) {
console.log(`failed to migrate account ${account}`)
}
})
}
}
isUnlocked () {

@@ -138,35 +107,2 @@ return Boolean(this.hdk && this.hdk.publicKey)

addAccounts (n = 1) {
return new Promise((resolve, reject) => {
this.unlock()
.then(async (_) => {
const from = this.unlockedAccount
const to = from + n
for (let i = from; i < to; i++) {
const path = this._getPathForIndex(i)
let address
if (this._isLedgerLiveHdPath()) {
address = await this.unlock(path)
} else {
address = this._addressFromIndex(pathBase, i)
}
this.accountDetails[ethUtil.toChecksumAddress(address)] = {
// TODO: consider renaming this property, as the current name is misleading
// It's currently used to represent whether an account uses the Ledger Live path.
bip44: this._isLedgerLiveHdPath(),
hdPath: path,
}
if (!this.accounts.includes(address)) {
this.accounts.push(address)
}
this.page = 0
}
resolve(this.accounts)
})
.catch(reject)
})
}
getFirstPage () {

@@ -185,14 +121,2 @@ this.page = 0

getAccounts () {
return Promise.resolve(this.accounts.slice())
}
removeAccount (address) {
if (!this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())) {
throw new Error(`Address ${address} not found in this keyring`)
}
this.accounts = this.accounts.filter((a) => a.toLowerCase() !== address.toLowerCase())
delete this.accountDetails[ethUtil.toChecksumAddress(address)]
}
updateTransportMethod (useLedgerLive = false) {

@@ -224,55 +148,19 @@ return new Promise((resolve, reject) => {

// tx is an instance of the ethereumjs-transaction class.
signTransaction (address, tx) {
// transactions built with older versions of ethereumjs-tx have a
// getChainId method that newer versions do not. Older versions are mutable
// while newer versions default to being immutable. Expected shape and type
// of data for v, r and s differ (Buffer (old) vs BN (new))
if (typeof tx.getChainId === 'function') {
// In this version of ethereumjs-tx we must add the chainId in hex format
// to the initial v value. The chainId must be included in the serialized
// transaction which is only communicated to ethereumjs-tx in this
// value. In newer versions the chainId is communicated via the 'Common'
// object.
tx.v = ethUtil.bufferToHex(tx.getChainId())
tx.r = '0x00'
tx.s = '0x00'
return this._signTransaction(address, tx, tx.to, (payload) => {
tx.v = Buffer.from(payload.v, 'hex')
tx.r = Buffer.from(payload.r, 'hex')
tx.s = Buffer.from(payload.s, 'hex')
return tx
})
}
// For transactions created by newer versions of @ethereumjs/tx
// Note: https://github.com/ethereumjs/ethereumjs-monorepo/issues/1188
// It is not strictly necessary to do this additional setting of the v
// value. We should be able to get the correct v value in serialization
// if the above issue is resolved. Until then this must be set before
// calling .serialize(). Note we are creating a temporarily mutable object
// forfeiting the benefit of immutability until this happens. We do still
// return a Transaction that is frozen if the originally provided
// transaction was also frozen.
const unfrozenTx = TransactionFactory.fromTxData(tx.toJSON(), { common: tx.common, freeze: false })
unfrozenTx.v = new ethUtil.BN(ethUtil.addHexPrefix(tx.common.chainId()), 'hex')
return this._signTransaction(address, unfrozenTx, tx.to.buf, (payload) => {
// Because tx will be immutable, first get a plain javascript object that
// represents the transaction. Using txData here as it aligns with the
// nomenclature of ethereumjs/tx.
const txData = tx.toJSON()
// The fromTxData utility expects v,r and s to be hex prefixed
txData.v = ethUtil.addHexPrefix(payload.v)
txData.r = ethUtil.addHexPrefix(payload.r)
txData.s = ethUtil.addHexPrefix(payload.s)
// Adopt the 'common' option from the original transaction and set the
// returned object to be frozen if the original is frozen.
return TransactionFactory.fromTxData(txData, { common: tx.common, freeze: Object.isFrozen(tx) })
})
}
signTransaction (address, tx, accountIndex) {
return new Promise((resolve, reject) => {
this.unlock().then((_) => {
tx.v = ethUtil.bufferToHex(tx.getChainId())
tx.r = '0x00'
tx.s = '0x00'
_signTransaction (address, tx, toAddress, handleSigning) {
return new Promise((resolve, reject) => {
this.unlockAccountByAddress(address)
.then((hdPath) => {
this._sendMessage({
let hdPath
if (this._isLedgerLiveHdPath()) {
const index = accountIndex
hdPath = this._getPathForIndex(index)
} else {
hdPath = this._toLedgerPath(this._pathFromAddress(address))
}
this._sendMessage(
{
action: 'ledger-sign-transaction',

@@ -282,3 +170,3 @@ params: {

hdPath,
to: ethUtil.bufferToHex(toAddress).toLowerCase(),
to: ethUtil.bufferToHex(tx.to).toLowerCase(),
},

@@ -288,134 +176,23 @@ },

if (success) {
tx.v = Buffer.from(payload.v, 'hex')
tx.r = Buffer.from(payload.r, 'hex')
tx.s = Buffer.from(payload.s, 'hex')
const newOrMutatedTx = handleSigning(payload)
const valid = newOrMutatedTx.verifySignature()
if (valid) {
resolve(newOrMutatedTx)
} else {
reject(new Error('Ledger: The transaction signature is not valid'))
}
resolve(tx)
} else {
reject(new Error(payload.error || 'Ledger: Unknown error while signing transaction'))
reject(
new Error(
payload.error ||
'Ledger: Unknown error while signing transaction',
),
)
}
})
})
.catch(reject)
})
}
signMessage (withAccount, data) {
return this.signPersonalMessage(withAccount, data)
}
// For personal_sign, we need to prefix the message:
signPersonalMessage (withAccount, message) {
return new Promise((resolve, reject) => {
this.unlockAccountByAddress(withAccount)
.then((hdPath) => {
this._sendMessage({
action: 'ledger-sign-personal-message',
params: {
hdPath,
message: ethUtil.stripHexPrefix(message),
},
},
({ success, payload }) => {
if (success) {
let v = payload.v - 27
v = v.toString(16)
if (v.length < 2) {
v = `0${v}`
}
const signature = `0x${payload.r}${payload.s}${v}`
const addressSignedWith = sigUtil.recoverPersonalSignature({ data: message, sig: signature })
if (ethUtil.toChecksumAddress(addressSignedWith) !== ethUtil.toChecksumAddress(withAccount)) {
reject(new Error('Ledger: The signature doesnt match the right address'))
}
resolve(signature)
} else {
reject(new Error(payload.error || 'Ledger: Unknown error while signing message'))
}
})
})
.catch(reject)
)
}).catch((err) => {
throw err
})
})
}
async unlockAccountByAddress (address) {
const checksummedAddress = ethUtil.toChecksumAddress(address)
if (!Object.keys(this.accountDetails).includes(checksummedAddress)) {
throw new Error(`Ledger: Account for address '${checksummedAddress}' not found`)
}
const { hdPath } = this.accountDetails[checksummedAddress]
const unlockedAddress = await this.unlock(hdPath)
// unlock resolves to the address for the given hdPath as reported by the ledger device
// if that address is not the requested address, then this account belongs to a different device or seed
if (unlockedAddress.toLowerCase() !== address.toLowerCase()) {
throw new Error(`Ledger: Account ${address} does not belong to the connected device`)
}
return hdPath
}
async signTypedData (withAccount, data, options = {}) {
const isV4 = options.version === 'V4'
if (!isV4) {
throw new Error('Ledger: Only version 4 of typed data signing is supported')
}
const {
domain,
types,
primaryType,
message,
} = sigUtil.TypedDataUtils.sanitizeData(data)
const domainSeparatorHex = sigUtil.TypedDataUtils.hashStruct('EIP712Domain', domain, types, isV4).toString('hex')
const hashStructMessageHex = sigUtil.TypedDataUtils.hashStruct(primaryType, message, types, isV4).toString('hex')
const hdPath = await this.unlockAccountByAddress(withAccount)
const { success, payload } = await new Promise((resolve) => {
this._sendMessage({
action: 'ledger-sign-typed-data',
params: {
hdPath,
domainSeparatorHex,
hashStructMessageHex,
},
},
(result) => resolve(result))
})
if (success) {
let v = payload.v - 27
v = v.toString(16)
if (v.length < 2) {
v = `0${v}`
}
const signature = `0x${payload.r}${payload.s}${v}`
const addressSignedWith = sigUtil.recoverTypedSignature_v4({
data,
sig: signature,
})
if (ethUtil.toChecksumAddress(addressSignedWith) !== ethUtil.toChecksumAddress(withAccount)) {
throw new Error('Ledger: The signature doesnt match the right address')
}
return signature
}
throw new Error(payload.error || 'Ledger: Unknown error while signing message')
}
exportAccount () {
throw new Error('Not supported on this device')
}
forgetDevice () {
this.accounts = []
this.page = 0
this.unlockedAccount = 0
this.paths = {}
this.accountDetails = {}
this.hdk = new HDKey()
}
/* PRIVATE METHODS */

@@ -488,2 +265,3 @@

}
return accounts

@@ -490,0 +268,0 @@ }

2

package.json
{
"name": "@binance-chain/bsc-ledger-bridge-keyring",
"version": "0.6.2",
"version": "0.6.3",
"description": "A MetaMask compatible keyring, for ledger hardware wallets",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc