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

Commit df5b17b

Browse files
committed
ledger backup and recovery
1 parent 45b3e64 commit df5b17b

File tree

5 files changed

+163
-2
lines changed

5 files changed

+163
-2
lines changed

app/extensions/brave/locales/en-US/preferences.properties

+13
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ add=Fund with debit/credit
7171
transferTime=Transfer may take up to 40 minutes
7272
addFundsTitle=Add funds…
7373
addFunds=Three ways to add funds to your Brave Wallet
74+
copy=Copy
75+
firstKey=Key 1
76+
secondKey=Key 2
7477
copyToClipboard=Copy to clipboard
7578
smartphoneTitle=Use your smartphone app to transfer Bitcoin
7679
displayQRCode=Display QR code
@@ -110,6 +113,16 @@ offerSearchSuggestions=Autocomplete search term as you type
110113
doNotTrackTitle=Do Not Track
111114
doNotTrack=Send a 'Do Not Track' header with browsing requests (requires browser restart)
112115
blockCanvasFingerprinting=Fingerprinting Protection (may break some websites)
116+
advancedSettings=Advanced Settings...
117+
advancedSettingsTitle=Advanced Settings for Brave Payments
118+
ledgerBackupTitle=Backup your Brave wallet
119+
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!
120+
minimumPageTimeSetting=Minimum page time before logging a visit
121+
minimumVisitsSetting=Minimum visits for publisher relevancy
122+
backupLedger=Backup your wallet
123+
recoverLedger=Recover your wallet
124+
printKeys=Print keys
125+
saveRecoveryFile=Save recovery file...
113126
advancedPrivacySettings=Advanced Privacy Settings:
114127
braveryDefaults=Bravery Defaults
115128
blockAttackSites=Block reported attack sites (not available yet)

app/ledger.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,10 @@ var ledgerInfo = {
869869
buyURL: undefined,
870870
bravery: undefined,
871871

872+
// wallet credentials
873+
paymentId: undefined,
874+
passphrase: undefined,
875+
872876
hasBitcoinHandler: false,
873877

874878
// geoIP/exchange information
@@ -1107,6 +1111,9 @@ var getStateInfo = (state) => {
11071111
var info = state.paymentInfo
11081112
var then = underscore.now() - msecs.year
11091113

1114+
ledgerInfo.paymentId = state.properties.wallet.paymentId
1115+
ledgerInfo.passphrase = state.properties.wallet.keychains.passphrase
1116+
11101117
ledgerInfo.created = !!state.properties.wallet
11111118
ledgerInfo.creating = !ledgerInfo.created
11121119

@@ -1228,7 +1235,6 @@ var getPaymentInfo = () => {
12281235

12291236
info = underscore.extend(info, underscore.pick(body, [ 'buyURL', 'buyURLExpires', 'balance', 'unconfirmed', 'satoshis' ]))
12301237
info.address = client.getWalletAddress()
1231-
info.passphrase = client.getWalletPassphrase()
12321238
if ((amount) && (currency)) {
12331239
info = underscore.extend(info, { amount: amount, currency: currency })
12341240
if ((body.rates) && (body.rates[currency])) {

js/about/preferences.js

+135-1
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ class TabsTab extends ImmutableComponent {
721721
class PaymentsTab extends ImmutableComponent {
722722
constructor () {
723723
super()
724+
this.printKeys = this.printKeys.bind(this)
724725
this.createWallet = this.createWallet.bind(this)
725726
}
726727

@@ -730,6 +731,23 @@ class PaymentsTab extends ImmutableComponent {
730731
}
731732
}
732733

734+
copyToClipboard (text) {
735+
aboutActions.setClipboard(text)
736+
}
737+
738+
printKeys () {
739+
const paymentId = this.props.ledgerData.get('paymentId')
740+
const passphrase = this.props.ledgerData.get('passphrase')
741+
742+
aboutActions.newFrame({
743+
location: `data:text/html,Brave Wallet Recovery keys
744+
Date created:
745+
Recovery Key 1: ${paymentId}
746+
Recovery Key 2: ${passphrase}
747+
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.`
748+
}, true)
749+
}
750+
733751
get enabled () {
734752
return getSetting(settings.PAYMENTS_ENABLED, this.props.settings)
735753
}
@@ -839,6 +857,103 @@ class PaymentsTab extends ImmutableComponent {
839857
</div>
840858
}
841859

860+
get advancedSettingsContent () {
861+
return <div className='board'>
862+
<div className='panel'>
863+
<div className='settingsPanelDivider'>
864+
<div data-l10n-id='minimumPageTimeSetting' />
865+
<SettingsList>
866+
<SettingItem>
867+
<select id='fundsSelectBox'>
868+
<option>5 seconds</option>
869+
<option>10 seconds</option>
870+
<option>1 minute</option>
871+
</select>
872+
</SettingItem>
873+
</SettingsList>
874+
<div data-l10n-id='minimumVisitsSetting' />
875+
<SettingsList>
876+
<SettingItem>
877+
<select id='fundsSelectBox'>
878+
<option>2 visits</option>
879+
<option>5 visits</option>
880+
<option>10 visits</option>
881+
</select>
882+
</SettingItem>
883+
</SettingsList>
884+
</div>
885+
{this.enabled
886+
? <SettingCheckbox
887+
dataL10nId='notifications'
888+
prefKey={settings.PAYMENTS_NOTIFICATIONS}
889+
settings={this.props.settings}
890+
onChangeSetting={this.props.onChangeSetting} />
891+
: null}
892+
</div>
893+
</div>
894+
}
895+
896+
get advancedSettingsFooter () {
897+
return <div className='panel advancedSettingsFooter'>
898+
<Button l10nId='backupLedger' className='primaryButton' onClick={this.props.showOverlay.bind(this, 'ledgerBackup')} />
899+
<Button l10nId='recoverLedger' className='primaryButton' onClick={this.props.showOverlay.bind(this, 'advancedSettings')} />
900+
<Button l10nId='done' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'advancedSettings')} />
901+
</div>
902+
}
903+
904+
get ledgerBackupContent () {
905+
const paymentId = this.props.ledgerData.get('paymentId')
906+
const passphrase = this.props.ledgerData.get('passphrase')
907+
908+
return <div className='board'>
909+
<div className='panel'>
910+
<span data-l10n-id='ledgerBackupContent' />
911+
<div>
912+
<div className='copyContainer'>
913+
<Button l10nId='copy' className='whiteButton inlineButton' onClick={this.copyToClipboard.bind(this, paymentId)} />
914+
</div>
915+
<div className='keyContainer'>
916+
<h2 data-l10n-id='firstKey' />
917+
<span>{paymentId}</span>
918+
</div>
919+
</div>
920+
<div>
921+
<div className='copyContainer'>
922+
<Button l10nId='copy' className='whiteButton inlineButton' onClick={this.copyToClipboard.bind(this, passphrase)} />
923+
</div>
924+
<div className='keyContainer'>
925+
<h2 data-l10n-id='secondKey' />
926+
<span>{passphrase}</span>
927+
</div>
928+
</div>
929+
</div>
930+
</div>
931+
}
932+
933+
get ledgerBackupFooter () {
934+
return <div className='panel advancedSettingsFooter'>
935+
<Button l10nId='printKeys' className='primaryButton' onClick={this.printKeys} />
936+
<Button l10nId='saveRecoveryFile' className='primaryButton' />
937+
<Button l10nId='done' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
938+
</div>
939+
}
940+
941+
get ledgerRecoveryContent () {
942+
return <div className='board'>
943+
<div className='panel'>
944+
<span data-l10n-id='ledgerRecoveryContent' />
945+
</div>
946+
</div>
947+
}
948+
949+
get ledgerRecoveryFooter () {
950+
return <div className='panel advancedSettingsFooter'>
951+
<Button l10nId='printKeys' className='primaryButton' />
952+
<Button l10nId='saveRecoveryFile' className='primaryButton' />
953+
<Button l10nId='done' className='whiteButton inlineButton' onClick={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
954+
</div>
955+
}
956+
842957
get nextReconcileDate () {
843958
const ledgerData = this.props.ledgerData
844959
if (!ledgerData.get('reconcileStamp')) {
@@ -947,6 +1062,21 @@ class PaymentsTab extends ImmutableComponent {
9471062
? <ModalOverlay title={'paymentHistoryTitle'} customTitleClasses={'paymentHistory'} content={this.paymentHistoryContent} footer={this.paymentHistoryFooter} onHide={this.props.hideOverlay.bind(this, 'paymentHistory')} />
9481063
: null
9491064
}
1065+
{
1066+
this.enabled && this.props.advancedSettingsOverlayVisible
1067+
? <ModalOverlay title={'advancedSettingsTitle'} content={this.advancedSettingsContent} footer={this.advancedSettingsFooter} onHide={this.props.hideOverlay.bind(this, 'advancedSettings')} />
1068+
: null
1069+
}
1070+
{
1071+
this.enabled && this.props.ledgerBackupOverlayVisible
1072+
? <ModalOverlay title={'ledgerBackupTitle'} content={this.ledgerBackupContent} footer={this.ledgerBackupFooter} onHide={this.props.hideOverlay.bind(this, 'ledgerBackup')} />
1073+
: null
1074+
}
1075+
{
1076+
this.enabled && this.props.ledgerRecoveryOverlayVisible
1077+
? <ModalOverlay title={'ledgerRecoveryTitle'} content={this.ledgerRecoveryContent} footer={this.ledgerRecoveryFooter} onHide={this.props.hideOverlay.bind(this, 'ledgerRecovery')} />
1078+
: null
1079+
}
9501080
<div className='titleBar'>
9511081
<div className='sectionTitleWrapper pull-left'>
9521082
<span className='sectionTitle'>Brave Payments</span>
@@ -957,7 +1087,7 @@ class PaymentsTab extends ImmutableComponent {
9571087
<span data-l10n-id='off' />
9581088
<SettingCheckbox dataL10nId='on' prefKey={settings.PAYMENTS_ENABLED} settings={this.props.settings} onChangeSetting={this.props.onChangeSetting} />
9591089
</div>
960-
{this.enabled ? <SettingCheckbox dataL10nId='notifications' prefKey={settings.PAYMENTS_NOTIFICATIONS} settings={this.props.settings} onChangeSetting={this.props.onChangeSetting} /> : null}
1090+
<Button l10nId='advancedSettings' className='whiteButton inlineButton' onClick={this.props.showOverlay.bind(this, 'advancedSettings')} />
9611091
</div>
9621092
</div>
9631093
{
@@ -1361,6 +1491,8 @@ class AboutPreferences extends React.Component {
13611491
bitcoinOverlayVisible: false,
13621492
qrcodeOverlayVisible: false,
13631493
paymentHistoryOverlayVisible: false,
1494+
advancedSettingsOverlayVisible: false,
1495+
ledgerBackupOverlayVisible: false,
13641496
addFundsOverlayVisible: false,
13651497
preferenceTab: hash.toUpperCase() in preferenceTabs ? hash : preferenceTabs.GENERAL,
13661498
hintNumber: this.getNextHintNumber(),
@@ -1491,6 +1623,8 @@ class AboutPreferences extends React.Component {
14911623
bitcoinOverlayVisible={this.state.bitcoinOverlayVisible}
14921624
qrcodeOverlayVisible={this.state.qrcodeOverlayVisible}
14931625
paymentHistoryOverlayVisible={this.state.paymentHistoryOverlayVisible}
1626+
advancedSettingsOverlayVisible={this.state.advancedSettingsOverlayVisible}
1627+
ledgerBackupOverlayVisible={this.state.ledgerBackupOverlayVisible}
14941628
addFundsOverlayVisible={this.state.addFundsOverlayVisible}
14951629
showOverlay={this.setOverlayVisible.bind(this, true)}
14961630
hideOverlay={this.setOverlayVisible.bind(this, false)} />

less/about/preferences.less

+4
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,10 @@ div.nextPaymentSubmission {
897897
}
898898
}
899899

900+
.advancedSettingsFooter {
901+
padding: 20px 100px;
902+
}
903+
900904
#flashInfoIcon {
901905
padding: 5px 5px 5px 0;
902906
}

less/button.less

+4
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ span.browserButton,
118118
padding: 3px 35px;
119119
}
120120

121+
&.inlineButton {
122+
display: inline;
123+
}
124+
121125
&.secondaryButton {
122126
background-color: #eee;
123127
}

0 commit comments

Comments
 (0)