eth-lattice-keyring
Advanced tools
Comparing version 0.3.5 to 0.4.0
113
index.js
@@ -33,3 +33,5 @@ const crypto = require('crypto'); | ||
if (opts.accountIndices) | ||
this.accountIndices = opts.accountIndices | ||
this.accountIndices = opts.accountIndices; | ||
if (opts.accountOpts) | ||
this.accountOpts = opts.accountOpts; | ||
if (opts.walletUID) | ||
@@ -57,2 +59,3 @@ this.walletUID = opts.walletUID; | ||
accountIndices: this.accountIndices, | ||
accountOpts: this.accountOpts, | ||
walletUID: this.walletUID, | ||
@@ -72,4 +75,16 @@ appName: this.appName, | ||
// Initialize a session with the Lattice1 device using the GridPlus SDK | ||
unlock(updateData=true) { | ||
unlock() { | ||
return new Promise((resolve, reject) => { | ||
// Force compatability. `this.accountOpts` were added after other | ||
// state params and must be synced in order for this keyring to function. | ||
if ((!this.accountOpts) || | ||
(this.accounts.length > 0 && this.accountOpts.length != this.accounts.length)) | ||
{ | ||
this.forgetDevice(); | ||
return reject(new Error( | ||
'You can now add multiple Lattice and SafeCard accounts at the same time! ' + | ||
'Your accounts have been cleared. Please press Continue to add them back in.' | ||
)); | ||
} | ||
this._getCreds() | ||
@@ -85,3 +100,3 @@ .then((creds) => { | ||
.then(() => { | ||
return this._connect(updateData); | ||
return this._connect(); | ||
}) | ||
@@ -115,8 +130,20 @@ .then(() => { | ||
.then((addrs) => { | ||
const walletUID = this._getCurrentWalletUID(); | ||
// Add these indices | ||
addrs.forEach((addr, i) => { | ||
if (this.accounts.indexOf(addr) === -1) { | ||
this.accounts.push(addr) | ||
this.accountIndices.push(this.unlockedAccount+i) | ||
let alreadySaved = false; | ||
for (let j = 0; j < this.accounts.length; j++) { | ||
if ((this.accounts[j] === addr) && | ||
(this.accountOpts[j].walletUID === walletUID) && | ||
(this.accountOpts[j].hdPath === this.hdPath)) | ||
alreadySaved = true; | ||
} | ||
if (!alreadySaved) { | ||
this.accounts.push(addr); | ||
this.accountIndices.push(this.unlockedAccount+i); | ||
this.accountOpts.push({ | ||
walletUID, | ||
hdPath: this.hdPath, | ||
}) | ||
} | ||
}) | ||
@@ -140,5 +167,6 @@ return resolve(this.accounts); | ||
this._unlockAndFindAccount(address) | ||
.then((addrIdx) => { | ||
.then((accountIdx) => { | ||
if (!tx.to) { | ||
return reject('Contract deployment is not supported by the Lattice at this time. `to` field must be included.') | ||
return reject('Contract deployment is not supported by the Lattice at this time. ' + | ||
'`to` field must be included.') | ||
} | ||
@@ -148,2 +176,4 @@ // Build the Lattice request data and make request | ||
// To ensure everything plays nicely with gridplus-sdk, we convert everything to hex strings | ||
const addressIdx = this.accountIndices[accountIdx]; | ||
const addressParentPath = this.accountOpts[accountIdx].hdPath; | ||
const txData = { | ||
@@ -156,3 +186,3 @@ chainId: `0x${this._getEthereumJsChainId(tx).toString('hex')}` || 1, | ||
data: tx.data.length === 0 ? null : `0x${tx.data.toString('hex')}`, | ||
signerPath: this._getHDPathIndices(addrIdx), | ||
signerPath: this._getHDPathIndices(addressParentPath, addressIdx), | ||
} | ||
@@ -254,3 +284,3 @@ switch (tx._type) { | ||
this._unlockAndFindAccount(address) | ||
.then((addrIdx) => { | ||
.then((accountIdx) => { | ||
let { payload, protocol } = msg; | ||
@@ -262,2 +292,4 @@ // If the message is not an object we assume it is a legacy signPersonal request | ||
} | ||
const addressIdx = this.accountIndices[accountIdx]; | ||
const addressParentPath = this.accountOpts[accountIdx].hdPath; | ||
const req = { | ||
@@ -268,3 +300,3 @@ currency: 'ETH_MSG', | ||
payload, | ||
signerPath: this._getHDPathIndices(addrIdx), | ||
signerPath: this._getHDPathIndices(addressParentPath, addressIdx), | ||
} | ||
@@ -301,6 +333,10 @@ } | ||
removeAccount(address) { | ||
// We only allow one account at a time, so removing any account | ||
// should result in a state reset. The user will need to reconnect | ||
// to the Lattice | ||
this.forgetDevice(); | ||
this.accounts.forEach((account, i) => { | ||
if (account.toLowerCase() === address.toLowerCase()) { | ||
this.accounts.splice(i, 1); | ||
this.accountIndices.splice(i, 1); | ||
this.accountOpts.splice(i, 1); | ||
return; | ||
} | ||
}) | ||
} | ||
@@ -336,8 +372,3 @@ | ||
return new Promise((resolve, reject) => { | ||
// NOTE: We are passing `false` here because we do NOT want | ||
// state data to be updated as a result of a transaction request. | ||
// It is possible the user inserted or removed a SafeCard and | ||
// will not be able to sign this transaction. If that is the | ||
// case, we just want to return an error message | ||
this.unlock(false) | ||
this.unlock() | ||
.then(() => { | ||
@@ -349,10 +380,15 @@ return this.getAccounts() | ||
// If we can't find it, return an error | ||
let addrIdx = null; | ||
let accountIdx = null; | ||
addrs.forEach((addr, i) => { | ||
if (address.toLowerCase() === addr.toLowerCase()) | ||
addrIdx = i; | ||
accountIdx = i; | ||
}) | ||
if (addrIdx === null) | ||
if (accountIdx === null) | ||
return reject('Signer not present'); | ||
return resolve(this.accountIndices[addrIdx]); | ||
// Make sure the account is associated with the current wallet | ||
if (this.accountOpts[accountIdx].walletUID !== this._getCurrentWalletUID()) { | ||
return reject(new Error('Account on a different wallet. ' + | ||
'Please switch to the correct wallet on your Lattice.')); | ||
} | ||
return resolve(accountIdx); | ||
}) | ||
@@ -365,4 +401,4 @@ .catch((err) => { | ||
_getHDPathIndices(insertIdx=0) { | ||
const path = this.hdPath.split('/').slice(1); | ||
_getHDPathIndices(hdPath, insertIdx=0) { | ||
const path = hdPath.split('/').slice(1); | ||
const indices = []; | ||
@@ -401,2 +437,3 @@ let usedX = false; | ||
this.accountIndices = []; | ||
this.accountOpts = []; | ||
this.isLocked = true; | ||
@@ -554,7 +591,3 @@ this.creds = { | ||
// This will handle SafeCard insertion/removal events. | ||
// updateData - true if you want to overwrite walletUID and accounts in | ||
// the event that we find we are not synced. | ||
// If left false and we notice a new walletUID, we will | ||
// return an error. | ||
_connect(updateData) { | ||
_connect() { | ||
return new Promise((resolve, reject) => { | ||
@@ -572,10 +605,2 @@ this.sdkSession.connect(this.creds.deviceID, (err) => { | ||
if (newUID != this.walletUID) { | ||
// If we don't want to update data, return an error | ||
if (updateData === false) | ||
return reject(new Error('Wallet has changed! Please reconnect.')); | ||
// By default we should clear out accounts and update with | ||
// the new walletUID. We should NOT fill in the accounts yet, | ||
// as we reserve that functionality to `addAccounts` | ||
this.accounts = []; | ||
this.walletUID = newUID; | ||
@@ -637,3 +662,3 @@ } | ||
currency: 'ETH', | ||
startPath: this._getHDPathIndices(i), | ||
startPath: this._getHDPathIndices(this.hdPath, i), | ||
n: shouldRecurse ? 1 : n, | ||
@@ -755,2 +780,8 @@ skipCache: true, | ||
_getCurrentWalletUID() { | ||
if (!this.sdkSession) | ||
return null; | ||
return this.sdkSession.getActiveWallet().uid.toString('hex'); | ||
} | ||
} | ||
@@ -757,0 +788,0 @@ |
{ | ||
"name": "eth-lattice-keyring", | ||
"version": "0.3.5", | ||
"version": "0.4.0", | ||
"description": "Keyring for connecting to the Lattice1 hardware wallet", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
28635
720