diff --git a/README.md b/README.md index 3c13418b9..b6fb5a5c4 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Frame is a web3 interface that lets you sign data, manage accounts, run your own › npm install # Run -› npm run alpha +› npm run prod ``` **On Windows:** Run `npm install --global --production windows-build-tools` as administrator **before** running the demo. You can find more info about this here: https://github.com/felixrieseberg/windows-build-tools. diff --git a/app/App/Panel/Local/index.js b/app/App/Panel/Local/index.js index dfddaa91a..f01effbd2 100644 --- a/app/App/Panel/Local/index.js +++ b/app/App/Panel/Local/index.js @@ -326,7 +326,7 @@ class Settings extends React.Component { ) : null} -
+ {/*
Hardware Derivation
Derive seperate sets of addresses based on use
-
-
+
*/} +
-
Ledger Type
+
Trezor Derivation
link.send('tray:action', 'setLedgerDerivation', value)} - options={[{ text: 'Legacy', value: 'legacy' }, { text: 'Live', value: 'live' }]} + syncValue={this.store('main.trezor.derivation')} + onChange={(value) => link.send('tray:action', 'setTrezorDerivation', value)} + options={[{ text: 'Standard', value: 'standard' }, { text: 'Legacy', value: 'legacy' }, { text: 'Testnet', value: 'testnet' }]} />
- {'Use Ledger\'s Legacy or Live derivation type'} + {'Derivation path for connected Trezor devices'}
-
+
-
Ledger Live Accounts
+
Ledger Derivation
link.send('tray:action', 'setLiveAccountLimit', value)} - options={[ - { text: '5', value: 5 }, - { text: '10', value: 10 }, - { text: '20', value: 20 }, - { text: '40', value: 40 } - ]} + syncValue={this.store('main.ledger.derivation')} + onChange={(value) => link.send('tray:action', 'setLedgerDerivation', value)} + options={[{ text: 'Live', value: 'live' }, { text: 'Legacy', value: 'legacy' }, { text: 'Standard', value: 'standard' }, { text: 'Testnet', value: 'testnet' }]} />
- The number of live accounts to derive + {'Derivation path for connected Ledger devices'}
+ {this.store('main.ledger.derivation') === 'live' ? ( +
+
+
Ledger Live Accounts
+ link.send('tray:action', 'setLiveAccountLimit', value)} + options={[ + { text: '5', value: 5 }, + { text: '10', value: 10 }, + { text: '20', value: 20 }, + { text: '40', value: 40 } + ]} + /> +
+
+ The number of live accounts to derive +
+
+ ) : null}
Lock Hot Signers on
diff --git a/main/signers/ledger/Ledger/index.js b/main/signers/ledger/Ledger/index.js index 76619f5cf..3ef7483e0 100644 --- a/main/signers/ledger/Ledger/index.js +++ b/main/signers/ledger/Ledger/index.js @@ -9,11 +9,17 @@ const Signer = require('../../Signer') const { v5: uuid } = require('uuid') const ns = '3bbcee75-cecc-5b56-8031-b6641c1ed1f1' +// Base Paths const BASE_PATH_LEGACY = '44\'/60\'/0\'/' -const BASE_PATH_LEGACY_TEST = '44\'/1\'/0\'/' +const BASE_PATH_STANDARD = `44\'/60\'/0\'/0/` +const BASE_PATH_TESTNET = '44\'/1\'/0\'/0/' +// Live Path const BASE_PATH_LIVE = '44\'/60\'/' -const BASE_PATH_LIVE_TEST = '44\'/1\'/' + +// const BASE_PATH_LIVE_TEST = '44\'/1\'/' +// const BASE_PATH_STANDARD = `44\'/60\'/0\'/0/` +// const BASE_PATH_STANDARD_TEST = `44\'/1\'/0\'/0/` class Ledger extends Signer { constructor (devicePath, signers, scan) { @@ -33,12 +39,10 @@ class Ledger extends Signer { this.network = store('main.currentNetwork.id') this.derivation = store('main.ledger.derivation') this.liveAccountLimit = store('main.ledger.liveAccountLimit') - this.hardwareDerivation = store('main.hardwareDerivation') this.varObserver = store.observer(() => { if ( this.derivation !== store('main.ledger.derivation') || this.liveAccountLimit !== store('main.ledger.liveAccountLimit') || - this.hardwareDerivation !== store('main.hardwareDerivation') || this.network !== store('main.currentNetwork.id') ) { this.reset() @@ -49,21 +53,14 @@ class Ledger extends Signer { getPath (i = 0) { if (this.derivation === 'legacy') { - if (store('main.hardwareDerivation') === 'mainnet') { - return (BASE_PATH_LEGACY + i) - } else { - return (BASE_PATH_LEGACY_TEST + i) - } + return (BASE_PATH_LEGACY + i) + } else if (this.derivation === 'standard') { + return (BASE_PATH_STANDARD + i) + } else if (this.derivation === 'testnet') { + return (BASE_PATH_TESTNET + i) } else { - if (store('main.hardwareDerivation') === 'mainnet') { - return (BASE_PATH_LIVE + i + '\'/0/0') - } else { - return (BASE_PATH_LIVE_TEST + i + '\'/0/0') - } + return (BASE_PATH_LIVE + i + '\'/0/0') } - // if (store('main.hardwareDerivation') !== 'mainnet') return (BASE_PATH_LEGACY_TEST + i) - // if (this.derivation === 'legacy') return (BASE_PATH_LEGACY + i) - // else return (BASE_PATH_LIVE + i + '\'/0/0') } getId () { @@ -109,7 +106,6 @@ class Ledger extends Signer { this.network = store('main.currentNetwork.id') this.derivation = store('main.ledger.derivation') this.liveAccountLimit = store('main.ledger.liveAccountLimit') - this.hardwareDerivation = store('main.hardwareDerivation') this.status = 'loading' this.addresses = [] this.update() @@ -171,6 +167,10 @@ class Ledger extends Signer { // Derive addresses if (this.derivation === 'legacy') { addresses = await this._deriveLegacyAddresses() + } else if (this.derivation === 'standard') { + addresses = await this._deriveStandardAddresses() + } else if (this.derivation === 'testnet') { + addresses = await this._deriveTestnetAddresses() } else { addresses = await this._deriveLiveAddresses() } @@ -394,13 +394,37 @@ class Ledger extends Signer { _deriveLegacyAddresses () { const executor = async (resolve, reject) => { try { - let path - if (store('main.hardwareDerivation') === 'mainnet') { - path = BASE_PATH_LEGACY - } else { - path = BASE_PATH_LEGACY_TEST - } - const result = await this.getAddress(path, false, true) + const result = await this.getAddress(BASE_PATH_LEGACY, false, true) + this.deriveHDAccounts(result.publicKey, result.chainCode, (err, addresses) => { + if (err) reject(err) + else resolve(addresses) + }) + } catch (err) { + reject(err) + } + } + return new Promise(executor) + } + + _deriveStandardAddresses () { + const executor = async (resolve, reject) => { + try { + const result = await this.getAddress(BASE_PATH_STANDARD, false, true) + this.deriveHDAccounts(result.publicKey, result.chainCode, (err, addresses) => { + if (err) reject(err) + else resolve(addresses) + }) + } catch (err) { + reject(err) + } + } + return new Promise(executor) + } + + _deriveTestnetAddresses () { + const executor = async (resolve, reject) => { + try { + const result = await this.getAddress(BASE_PATH_TESTNET, false, true) this.deriveHDAccounts(result.publicKey, result.chainCode, (err, addresses) => { if (err) reject(err) else resolve(addresses) diff --git a/main/signers/trezor-connect/Trezor/index.js b/main/signers/trezor-connect/Trezor/index.js index c618a450c..e74544423 100644 --- a/main/signers/trezor-connect/Trezor/index.js +++ b/main/signers/trezor-connect/Trezor/index.js @@ -7,6 +7,11 @@ const flex = require('../../../flex') const { v5: uuid } = require('uuid') const ns = '3bbcee75-cecc-5b56-8031-b6641c1ed1f1' +// Base Paths +const BASE_PATH_STANDARD = 'm/44\'/60\'/0\'/0' +const BASE_PATH_LEGACY = 'm/44\'/60\'/0' +const BASE_PATH_TESTNET = 'm/44\'/1\'/0\'/0' + class Trezor extends Signer { constructor (device, signers) { super() @@ -17,8 +22,16 @@ class Trezor extends Signer { this.type = 'trezor' this.status = 'loading' this.network = store('main.currentNetwork.id') - this.hardwareDerivation = store('main.hardwareDerivation') - this.basePath = () => this.hardwareDerivation === 'mainnet' ? 'm/44\'/60\'/0\'/0' : 'm/44\'/1\'/0\'/0' + this.derivationPath = store('main.trezor.derivation') + this.basePath = () => { + if (this.derivationPath === 'testnet') { + return BASE_PATH_TESTNET + } else if (this.derivationPath === 'legacy') { + return BASE_PATH_LEGACY + } else { + return BASE_PATH_STANDARD + } + } this.getPath = (i = 0) => this.basePath() + '/' + i this.handlers = {} this.deviceStatus() @@ -28,9 +41,9 @@ class Trezor extends Signer { this.deviceStatus() } }) - this.hardwareDerivationObserver = store.observer(() => { - if (this.hardwareDerivation !== store('main.hardwareDerivation')) { - this.hardwareDerivation = store('main.hardwareDerivation') + this.derivationPathObserver = store.observer(() => { + if (this.derivationPath !== store('main.trezor.derivation')) { + this.derivationPath = store('main.trezor.derivation') this.reset() this.deviceStatus() } @@ -84,7 +97,7 @@ class Trezor extends Signer { close () { this.networkObserver.remove() - this.hardwareDerivationObserver.remove() + this.derivationPathObserver.remove() this.closed = true store.removeSigner(this.id) super.close() diff --git a/main/store/actions/index.js b/main/store/actions/index.js index 72593b2a1..2106bb20a 100644 --- a/main/store/actions/index.js +++ b/main/store/actions/index.js @@ -134,6 +134,9 @@ module.exports = { setLedgerDerivation: (u, value) => { u('main.ledger.derivation', () => value) }, + setTrezorDerivation: (u, value) => { + u('main.trezor.derivation', () => value) + }, setLiveAccountLimit: (u, value) => { u('main.ledger.liveAccountLimit', () => value) }, diff --git a/main/store/state/index.js b/main/store/state/index.js index 1788cb621..fc99fb270 100644 --- a/main/store/state/index.js +++ b/main/store/state/index.js @@ -98,9 +98,12 @@ const initial = { hardwareDerivation: main('hardwareDerivation', 'mainnet'), menubarGasPrice: main('menubarGasPrice', false), ledger: { - derivation: main('ledger.derivation', 'legacy'), + derivation: main('ledger.derivation', 'live'), liveAccountLimit: main('ledger.liveAccountLimit', 5) }, + trezor: { + derivation: main('trezor.derivation', 'standard') + }, accounts: main('accounts', {}), addresses: main('addresses', {}), // New persisted address permissions signers: {}, @@ -401,7 +404,7 @@ if (initial.main._version < 5) { id: 137, type: 'ethereum', symbol: 'MATIC', - name: 'Matic', + name: 'Polygon', explorer: 'https://explorer.matic.network', gas: { price: { @@ -418,4 +421,13 @@ if (initial.main._version < 5) { initial.main._version = 5 } +// State transition for derevation paths +if (initial.main._version < 6) { + if (initial.main.hardwareDerivation === 'testnet') { + initial.main.ledger.derivation = 'testnet' + initial.main.trezor.derivation = 'testnet' + } + initial.main._version = 6 +} + module.exports = () => initial diff --git a/package-lock.json b/package-lock.json index 40ef7231a..3c3911036 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "frame", - "version": "0.4.3", + "version": "0.4.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e797eafac..263c4aa94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frame", - "version": "0.4.3", + "version": "0.4.4", "description": "System-wide web3", "main": "main", "build": {