Skip to content

Commit

Permalink
refactor address derivation, discovery and crypto providers
Browse files Browse the repository at this point in the history
  • Loading branch information
refi93 committed Dec 10, 2018
1 parent aa60d9b commit 78fd2d9
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 487 deletions.
34 changes: 14 additions & 20 deletions app/frontend/actions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const {generateMnemonic} = require('./wallet/mnemonic')
const {ADALITE_CONFIG} = require('./config')
const {DERIVATION_SCHEMES} = require('./wallet/constants')
const derivationSchemes = require('./wallet/derivation-schemes')
const FileSaver = require('file-saver')
const {
sendAddressValidator,
Expand Down Expand Up @@ -67,20 +67,12 @@ module.exports = ({setState, getState}) => {
loadingAction(state, 'Loading wallet data...', {walletLoadingError: undefined})
switch (cryptoProvider) {
case 'trezor':
try {
wallet = await Cardano.CardanoWallet({
cryptoProvider: 'trezor',
config: ADALITE_CONFIG,
network: 'mainnet',
derivationScheme: DERIVATION_SCHEMES.v2,
})
} catch (e) {
debugLog(e)
return setState({
loading: false,
walletLoadingError: {code: 'TrezorRejected'},
})
}
wallet = await Cardano.CardanoWallet({
cryptoProvider: 'trezor',
config: ADALITE_CONFIG,
network: 'mainnet',
derivationScheme: derivationSchemes.v2,
})
break
case 'mnemonic':
secret = secret.trim()
Expand All @@ -89,7 +81,7 @@ module.exports = ({setState, getState}) => {
mnemonicOrHdNodeString: secret,
config: ADALITE_CONFIG,
network: 'mainnet',
derivationScheme: DERIVATION_SCHEMES.v1,
derivationScheme: derivationSchemes.v1,
})
break
default:
Expand All @@ -103,7 +95,7 @@ module.exports = ({setState, getState}) => {
}
try {
const walletIsLoaded = true
const ownAddressesWithMeta = await wallet.getOwnAddressesWithMeta()
const ownAddressesWithMeta = await wallet.getVisibleAddressesWithMeta()
const transactionHistory = await wallet.getHistory()
const balance = await wallet.getBalance()
const conversionRates = getConversionRates(state)
Expand Down Expand Up @@ -138,11 +130,12 @@ module.exports = ({setState, getState}) => {
})
}
} catch (e) {
debugLog(e.toString())
debugLog(e)
setState({
walletLoadingError: {
code: 'WalletInitializationError',
},
loading: false,
})
}
return true
Expand Down Expand Up @@ -238,7 +231,7 @@ module.exports = ({setState, getState}) => {
loadingAction(state, 'Reloading wallet info...')

const balance = await wallet.getBalance()
const ownAddressesWithMeta = await wallet.getOwnAddressesWithMeta()
const ownAddressesWithMeta = await wallet.getVisibleAddressesWithMeta()
const transactionHistory = await wallet.getHistory()
const conversionRates = getConversionRates(state)

Expand All @@ -254,9 +247,10 @@ module.exports = ({setState, getState}) => {
conversionRates: await conversionRates,
})
} catch (e) {
debugLog('Could not fetch conversion rates.')
debugLog(`Could not fetch conversion rates: ${e}`)
setState({
conversionRates: null,
loading: false,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const AddressContainer = connect(
h(
'div',
{class: 'address-wrap'},
h('b', {class: 'address address-start no-events'}, `/${bip32path.split('/')[5]}`),
h('b', {class: 'address address-start no-events'}, `/${bip32path.split('/').pop()}`),
h(
'span',
{class: 'address shrinked no-events'},
Expand Down
10 changes: 8 additions & 2 deletions app/frontend/helpers/debugLog.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
const ADALITE_CONFIG = require('../config').ADALITE_CONFIG

function debugLog(message) {
function debugLog(item) {
// patched to work with tests, added `ADALITE_CONFIG &&`,
// because config is loaded from html body, which is not present in tests
if (ADALITE_CONFIG && ADALITE_CONFIG.ADALITE_ENABLE_DEBUGGING) {
let msgToLog = ''
if (item instanceof Error) {
msgToLog = JSON.stringify(item, Object.getOwnPropertyNames(item))
} else {
msgToLog = item
}
// eslint-disable-next-line no-console
console.error(message)
console.error(msgToLog)
}
}

Expand Down
78 changes: 78 additions & 0 deletions app/frontend/wallet/address-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const range = require('./helpers/range')
const {toBip32StringPath} = require('./helpers/bip32')
const {packAddress} = require('cardano-crypto.js')

const AddressManager = ({
accountIndex,
addressLimit,
cryptoProvider,
derivationScheme,
disableCaching, // good for tests
isChange,
}) => {
const state = {
deriveAddressMemo: {},
}

function discoverAddresses() {
const childIndexBegin = derivationScheme.startAddressIndex
const childIndexEnd = childIndexBegin + addressLimit
const absDerivationPaths = range(childIndexBegin, childIndexEnd)
.map((i) => [accountIndex, isChange ? 1 : 0, i])
.map(derivationScheme.toAbsoluteDerivationPath)

return deriveAddresses(absDerivationPaths)
}

async function discoverAddressesWithMeta() {
return (await discoverAddresses()).map((address) => {
return {
address,
bip32StringPath: toBip32StringPath(getAddressToAbsPathMapping()[address]),
}
})
}

function deriveAddresses(absDerivationPaths) {
return Promise.all(absDerivationPaths.map(deriveAddress))
}

async function deriveAddress(absDerivationPath) {
// in derivation scheme 1, the middle part of the derivation path is skipped
const memoKey = JSON.stringify(absDerivationPath)

if (!state.deriveAddressMemo[memoKey] || disableCaching) {
const xpub = await cryptoProvider.deriveXpub(absDerivationPath)
const hdPassphrase =
derivationScheme.type === 'v1' ? await cryptoProvider.getHdPassphrase() : undefined

state.deriveAddressMemo[memoKey] = packAddress(
absDerivationPath,
xpub,
hdPassphrase,
derivationScheme.number
)
}

return state.deriveAddressMemo[memoKey]
}

function getAddressToAbsPathMapping() {
const result = {}
Object.keys(state.deriveAddressMemo).map((key) => {
result[state.deriveAddressMemo[key]] = JSON.parse(key)
})

return result
}

return {
discoverAddresses,
discoverAddressesWithMeta,
getAddressToAbsPathMapping,
_deriveAddress: deriveAddress,
_deriveAddresses: deriveAddresses,
}
}

module.exports = AddressManager
2 changes: 1 addition & 1 deletion app/frontend/wallet/blockchain-explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const blockchainExplorer = (ADALITE_CONFIG, walletState) => {

function getAddressInfo(address) {
const addressInfo = state.addressInfos[address]
const maxAddressInfoAge = 10000
const maxAddressInfoAge = 15000

if (!addressInfo || Date.now() - addressInfo.timestamp > maxAddressInfoAge) {
state.addressInfos[address] = {
Expand Down
Loading

0 comments on commit 78fd2d9

Please sign in to comment.