Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
ledger backup and recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
jkup committed Sep 30, 2016
1 parent 45b3e64 commit 3d9d3c2
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 3 deletions.
18 changes: 18 additions & 0 deletions app/extensions/brave/locales/en-US/preferences.properties
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ bitcoinVisitAccount=Transfer BTC
bitcoinBalance=Please transfer: 
bitcoinWalletNotAvailable=Wallet information not available. :(
usd=$
cancel=Cancel
done=Done
off=off
on=on
Expand All @@ -71,6 +72,9 @@ add=Fund with debit/credit
transferTime=Transfer may take up to 40 minutes
addFundsTitle=Add funds…
addFunds=Three ways to add funds to your Brave Wallet
copy=Copy
firstKey=Key 1
secondKey=Key 2
copyToClipboard=Copy to clipboard
smartphoneTitle=Use your smartphone app to transfer Bitcoin
displayQRCode=Display QR code
Expand Down Expand Up @@ -110,6 +114,20 @@ offerSearchSuggestions=Autocomplete search term as you type
doNotTrackTitle=Do Not Track
doNotTrack=Send a 'Do Not Track' header with browsing requests (requires browser restart)
blockCanvasFingerprinting=Fingerprinting Protection (may break some websites)
advancedSettings=Advanced Settings...
advancedSettingsTitle=Advanced Settings for Brave Payments
ledgerRecoveryTitle=Recover your Brave wallet
ledgerRecoverySubtitle=Enter your recovery keys below
ledgerRecoveryContent=The balance of the recovered wallet will be transferred to your new Brave wallet. The old wallet will still exist as an empty wallet.
ledgerBackupTitle=Backup your Brave wallet
ledgerBackupContent=Below, you will find the anonymized recovery keys that are required if you ever lose access to this computer. We recommend that you print or save these keys and store them in a safe place, like your local safe deposit box, or under your mattress. It's really up to you!
minimumPageTimeSetting=Minimum page time before logging a visit
minimumVisitsSetting=Minimum visits for publisher relevancy
backupLedger=Backup your wallet
recoverLedger=Recover your wallet
recover=Recover
printKeys=Print keys
saveRecoveryFile=Save recovery file...
advancedPrivacySettings=Advanced Privacy Settings:
braveryDefaults=Bravery Defaults
blockAttackSites=Block reported attack sites (not available yet)
Expand Down
12 changes: 11 additions & 1 deletion app/ledger.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ const doAction = (action) => {
case settings.PAYMENTS_CONTRIBUTION_AMOUNT:
setPaymentInfo(action.value)
break
case settings.MINIMUM_VISIT_TIME:
break
case settings.MINIMUM_VISTS:
break
default:
break
}
Expand Down Expand Up @@ -869,6 +873,10 @@ var ledgerInfo = {
buyURL: undefined,
bravery: undefined,

// wallet credentials
paymentId: undefined,
passphrase: undefined,

hasBitcoinHandler: false,

// geoIP/exchange information
Expand Down Expand Up @@ -1107,6 +1115,9 @@ var getStateInfo = (state) => {
var info = state.paymentInfo
var then = underscore.now() - msecs.year

ledgerInfo.paymentId = state.properties.wallet.paymentId
ledgerInfo.passphrase = state.properties.wallet.keychains.passphrase

ledgerInfo.created = !!state.properties.wallet
ledgerInfo.creating = !ledgerInfo.created

Expand Down Expand Up @@ -1228,7 +1239,6 @@ var getPaymentInfo = () => {

info = underscore.extend(info, underscore.pick(body, [ 'buyURL', 'buyURLExpires', 'balance', 'unconfirmed', 'satoshis' ]))
info.address = client.getWalletAddress()
info.passphrase = client.getWalletPassphrase()
if ((amount) && (currency)) {
info = underscore.extend(info, { amount: amount, currency: currency })
if ((body.rates) && (body.rates[currency])) {
Expand Down
146 changes: 145 additions & 1 deletion js/about/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ class TabsTab extends ImmutableComponent {
class PaymentsTab extends ImmutableComponent {
constructor () {
super()
this.printKeys = this.printKeys.bind(this)
this.createWallet = this.createWallet.bind(this)
}

Expand All @@ -730,6 +731,23 @@ class PaymentsTab extends ImmutableComponent {
}
}

copyToClipboard (text) {
aboutActions.setClipboard(text)
}

printKeys () {
const paymentId = this.props.ledgerData.get('paymentId')
const passphrase = this.props.ledgerData.get('passphrase')

aboutActions.newFrame({
location: `data:text/html,Brave Wallet Recovery keys
Date created:
Recovery Key 1: ${paymentId}
Recovery Key 2: ${passphrase}
Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your brave browser.`
}, true)
}

get enabled () {
return getSetting(settings.PAYMENTS_ENABLED, this.props.settings)
}
Expand Down Expand Up @@ -839,6 +857,111 @@ class PaymentsTab extends ImmutableComponent {
</div>
}

get advancedSettingsContent () {
return <div className='board'>
<div className='panel'>
<div className='settingsPanelDivider'>
<div data-l10n-id='minimumPageTimeSetting' />
<SettingsList>
<SettingItem>
<select id='fundsSelectBox'>
<option>5 seconds</option>
<option>10 seconds</option>
<option>1 minute</option>
</select>
</SettingItem>
</SettingsList>
<div data-l10n-id='minimumVisitsSetting' />
<SettingsList>
<SettingItem>
<select id='fundsSelectBox'>
<option>2 visits</option>
<option>5 visits</option>
<option>10 visits</option>
</select>
</SettingItem>
</SettingsList>
</div>
{this.enabled
? <SettingCheckbox
dataL10nId='notifications'
prefKey={settings.PAYMENTS_NOTIFICATIONS}
settings={this.props.settings}
onChangeSetting={this.props.onChangeSetting} />
: null}
</div>
</div>
}

get advancedSettingsFooter () {
return <div className='panel advancedSettingsFooter'>
<Button l10nId='backupLedger' className='primaryButton' onClick={this.props.showOverlay.bind(this, 'ledgerBackup')} />
<Button l10nId='recoverLedger' className='primaryButton' onClick={this.props.showOverlay.bind(this, 'ledgerRecovery')} />
<Button l10nId='done' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'advancedSettings')} />
</div>
}

get ledgerBackupContent () {
const paymentId = this.props.ledgerData.get('paymentId')
const passphrase = this.props.ledgerData.get('passphrase')

return <div className='board'>
<div className='panel'>
<span data-l10n-id='ledgerBackupContent' />
<div>
<div className='copyContainer'>
<Button l10nId='copy' className='whiteButton inlineButton' onClick={this.copyToClipboard.bind(this, paymentId)} />
</div>
<div className='keyContainer'>
<h2 data-l10n-id='firstKey' />
<span>{paymentId}</span>
</div>
</div>
<div>
<div className='copyContainer'>
<Button l10nId='copy' className='whiteButton inlineButton' onClick={this.copyToClipboard.bind(this, passphrase)} />
</div>
<div className='keyContainer'>
<h2 data-l10n-id='secondKey' />
<span>{passphrase}</span>
</div>
</div>
</div>
</div>
}

get ledgerBackupFooter () {
return <div className='panel advancedSettingsFooter'>
<Button l10nId='printKeys' className='primaryButton' onClick={this.printKeys} />
<Button l10nId='saveRecoveryFile' className='primaryButton' />
<Button l10nId='done' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
</div>
}

get ledgerRecoveryContent () {
return <div className='board'>
<div className='panel'>
<h3 data-l10n-id='ledgerRecoverySubtitle' />
<span data-l10n-id='ledgerRecoveryContent' />
<SettingsList>
<SettingItem>
<h2>Key 1</h2>
<input type='text' />
<h2>Key 2</h2>
<input type='text' />
</SettingItem>
</SettingsList>
</div>
</div>
}

get ledgerRecoveryFooter () {
return <div className='panel advancedSettingsFooter'>
<Button l10nId='cancel' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
<Button l10nId='recover' className='primaryButton' />
</div>
}

get nextReconcileDate () {
const ledgerData = this.props.ledgerData
if (!ledgerData.get('reconcileStamp')) {
Expand Down Expand Up @@ -947,6 +1070,21 @@ class PaymentsTab extends ImmutableComponent {
? <ModalOverlay title={'paymentHistoryTitle'} customTitleClasses={'paymentHistory'} content={this.paymentHistoryContent} footer={this.paymentHistoryFooter} onHide={this.props.hideOverlay.bind(this, 'paymentHistory')} />
: null
}
{
this.enabled && this.props.advancedSettingsOverlayVisible
? <ModalOverlay title={'advancedSettingsTitle'} content={this.advancedSettingsContent} footer={this.advancedSettingsFooter} onHide={this.props.hideOverlay.bind(this, 'advancedSettings')} />
: null
}
{
this.enabled && this.props.ledgerBackupOverlayVisible
? <ModalOverlay title={'ledgerBackupTitle'} content={this.ledgerBackupContent} footer={this.ledgerBackupFooter} onHide={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
: null
}
{
this.enabled && this.props.ledgerRecoveryOverlayVisible
? <ModalOverlay title={'ledgerRecoveryTitle'} content={this.ledgerRecoveryContent} footer={this.ledgerRecoveryFooter} onHide={this.props.hideOverlay.bind(this, 'ledgerRecovery')} />
: null
}
<div className='titleBar'>
<div className='sectionTitleWrapper pull-left'>
<span className='sectionTitle'>Brave Payments</span>
Expand All @@ -957,7 +1095,7 @@ class PaymentsTab extends ImmutableComponent {
<span data-l10n-id='off' />
<SettingCheckbox dataL10nId='on' prefKey={settings.PAYMENTS_ENABLED} settings={this.props.settings} onChangeSetting={this.props.onChangeSetting} />
</div>
{this.enabled ? <SettingCheckbox dataL10nId='notifications' prefKey={settings.PAYMENTS_NOTIFICATIONS} settings={this.props.settings} onChangeSetting={this.props.onChangeSetting} /> : null}
<Button l10nId='advancedSettings' className='whiteButton inlineButton' onClick={this.props.showOverlay.bind(this, 'advancedSettings')} />
</div>
</div>
{
Expand Down Expand Up @@ -1361,6 +1499,9 @@ class AboutPreferences extends React.Component {
bitcoinOverlayVisible: false,
qrcodeOverlayVisible: false,
paymentHistoryOverlayVisible: false,
advancedSettingsOverlayVisible: false,
ledgerBackupOverlayVisible: false,
ledgerRecoveryOverlayVisible: false,
addFundsOverlayVisible: false,
preferenceTab: hash.toUpperCase() in preferenceTabs ? hash : preferenceTabs.GENERAL,
hintNumber: this.getNextHintNumber(),
Expand Down Expand Up @@ -1491,6 +1632,9 @@ class AboutPreferences extends React.Component {
bitcoinOverlayVisible={this.state.bitcoinOverlayVisible}
qrcodeOverlayVisible={this.state.qrcodeOverlayVisible}
paymentHistoryOverlayVisible={this.state.paymentHistoryOverlayVisible}
advancedSettingsOverlayVisible={this.state.advancedSettingsOverlayVisible}
ledgerBackupOverlayVisible={this.state.ledgerBackupOverlayVisible}
ledgerRecoveryOverlayVisible={this.state.ledgerRecoveryOverlayVisible}
addFundsOverlayVisible={this.state.addFundsOverlayVisible}
showOverlay={this.setOverlayVisible.bind(this, true)}
hideOverlay={this.setOverlayVisible.bind(this, false)} />
Expand Down
4 changes: 3 additions & 1 deletion js/constants/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ const settings = {
HARDWARE_ACCELERATION_ENABLED: 'advanced.hardware-acceleration-enabled',
PDFJS_ENABLED: 'advanced.pdfjs-enabled',
DEFAULT_ZOOM_LEVEL: 'advanced.default-zoom-level',
SMOOTH_SCROLL_ENABLED: 'advanced.smooth-scroll-enabled'
SMOOTH_SCROLL_ENABLED: 'advanced.smooth-scroll-enabled',
MINIMUM_VISIT_TIME: 'advanced.minimum-visit-time',
MINIMUM_VISTS: 'advanced.minimum-visits'
}

module.exports = settings
4 changes: 4 additions & 0 deletions less/about/preferences.less
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,10 @@ div.nextPaymentSubmission {
}
}

.advancedSettingsFooter {
padding: 20px 100px;
}

#flashInfoIcon {
padding: 5px 5px 5px 0;
}
Expand Down
4 changes: 4 additions & 0 deletions less/button.less
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ span.browserButton,
padding: 3px 35px;
}

&.inlineButton {
display: inline;
}

&.secondaryButton {
background-color: #eee;
}
Expand Down

0 comments on commit 3d9d3c2

Please sign in to comment.