Skip to content

Commit

Permalink
Derivation path updates (#429)
Browse files Browse the repository at this point in the history
  • Loading branch information
floating committed May 12, 2021
1 parent c8a61bc commit c5f12f2
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
53 changes: 34 additions & 19 deletions app/App/Panel/Local/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ class Settings extends React.Component {
</div>
</div>
) : null}
<div className='signerPermission' style={{ zIndex: 4 }}>
{/* <div className='signerPermission' style={{ zIndex: 4 }}>
<div className='signerPermissionControls'>
<div className='signerPermissionOrigin'>Hardware Derivation</div>
<Dropdown
Expand All @@ -338,38 +338,53 @@ class Settings extends React.Component {
<div className='signerPermissionDetails'>
Derive seperate sets of addresses based on use
</div>
</div>
<div className='signerPermission' style={{ zIndex: 3 }}>
</div> */}
<div className='signerPermission' style={{ zIndex: 4 }}>
<div className='signerPermissionControls'>
<div className='signerPermissionOrigin'>Ledger Type</div>
<div className='signerPermissionOrigin'>Trezor Derivation</div>
<Dropdown
syncValue={this.store('main.ledger.derivation')}
onChange={(value) => 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' }]}
/>
</div>
<div className='signerPermissionDetails'>
{'Use Ledger\'s Legacy or Live derivation type'}
{'Derivation path for connected Trezor devices'}
</div>
</div>
<div className='signerPermission' style={{ zIndex: 2 }}>
<div className='signerPermission' style={{ zIndex: 3 }}>
<div className='signerPermissionControls'>
<div className='signerPermissionOrigin'>Ledger Live Accounts</div>
<div className='signerPermissionOrigin'>Ledger Derivation</div>
<Dropdown
syncValue={this.store('main.ledger.liveAccountLimit')}
onChange={(value) => 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' }]}
/>
</div>
<div className='signerPermissionDetails'>
The number of live accounts to derive
{'Derivation path for connected Ledger devices'}
</div>
</div>
{this.store('main.ledger.derivation') === 'live' ? (
<div className='signerPermission' style={{ zIndex: 2 }}>
<div className='signerPermissionControls'>
<div className='signerPermissionOrigin'>Ledger Live Accounts</div>
<Dropdown
syncValue={this.store('main.ledger.liveAccountLimit')}
onChange={(value) => link.send('tray:action', 'setLiveAccountLimit', value)}
options={[
{ text: '5', value: 5 },
{ text: '10', value: 10 },
{ text: '20', value: 20 },
{ text: '40', value: 40 }
]}
/>
</div>
<div className='signerPermissionDetails'>
The number of live accounts to derive
</div>
</div>
) : null}
<div className='signerPermission' style={{ zIndex: 1 }}>
<div className='signerPermissionControls'>
<div className='signerPermissionOrigin'>Lock Hot Signers on</div>
Expand Down
74 changes: 49 additions & 25 deletions main/signers/ledger/Ledger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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()
Expand All @@ -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 () {
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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)
Expand Down
25 changes: 19 additions & 6 deletions main/signers/trezor-connect/Trezor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand All @@ -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()
}
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions main/store/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
},
Expand Down
16 changes: 14 additions & 2 deletions main/store/state/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {},
Expand Down Expand Up @@ -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: {
Expand All @@ -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
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frame",
"version": "0.4.3",
"version": "0.4.4",
"description": "System-wide web3",
"main": "main",
"build": {
Expand Down

0 comments on commit c5f12f2

Please sign in to comment.