add tabs to export, create wallet and import wallet

This commit is contained in:
Gabriel Bazán 2016-08-19 16:16:24 -03:00
parent b247bfdcc6
commit 588550120a
14 changed files with 738 additions and 545 deletions

View File

@ -10,7 +10,7 @@
<ion-content>
<ion-list>
<ion-item class="item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="add.create">
<ion-item class="item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="add.create.personal">
<h2 translate>Create new wallet</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>
@ -20,7 +20,7 @@
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>
<ion-item class="item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="add.import">
<ion-item class="item-remove-animate item-icon-right" type="item-text-wrap" ui-sref="add.import.phrase">
<h2 translate>Import wallet</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>

View File

@ -1,183 +1,13 @@
<ion-view>
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Create new wallet</ion-nav-title>
</ion-nav-bar>
<ion-view cache-view="false">
<ion-tabs class="tabs-striped tabs-color-positive tabs-color-active-positive tabs-top">
<ion-content ng-controller="createController as create" ng-init="create.setTotalCopayers(1)">
<ion-tab title="Personal Wallet" ui-sref="add.create.personal">
<ion-nav-view name="tab-create-personal"></ion-nav-view>
</ion-tab>
<div class="row" ng-hide="create.hideTabs">
<div class="col">
<button
ng-class="{'button-dark': totalCopayers == 1, 'button-stable': totalCopayers != 1}"
class="button button-full button-clear"
ng-click="create.setTotalCopayers(1)" translate>
Personal Wallet
</button>
</div>
<div class="col">
<button
ng-class="{'button-stable': totalCopayers == 1, 'button-dark': totalCopayers != 1}"
class="button button-full button-clear"
ng-click="create.setTotalCopayers(3)" translate>
Shared Wallet
</button>
</div>
</div>
<ion-tab title="Shared Wallet" ui-sref="add.create.shared">
<ion-nav-view name="tab-create-shared"></ion-nav-view>
</ion-tab>
<div class="padding assertive" ng-show="create.error">
{{create.error|translate}}
</div>
<form name="setupForm" ng-submit="create.create(setupForm)" novalidate>
<div class="list">
<label ng-hide="create.hideWalletName" class="item item-input item-stacked-label">
<span class="input-label" translate>Wallet name</span>
<input type="text"
placeholder="{{'Family vacation funds'|translate}}"
name="walletName"
ng-model="walletName"
ng-required="true"
ng-focus="create.formFocus('wallet-name')"
ng-blur="create.formFocus(false)">
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-stacked-label">
<span class="input-label" translate>Your nickname</span>
<input type="text"
placeholder="{{'John'|translate}}"
name="myName"
ng-model="myName"
ng-required="totalCopayers != 1"
ng-disabled="totalCopayers == 1"
ng-focus="create.formFocus('my-name')"
ng-blur="create.formFocus(false)">
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-select">
<div class="input-label" translate>
Total number of copayers
</div>
<select class="m10t"
ng-model="totalCopayers"
ng-options="totalCopayers as totalCopayers for totalCopayers in create.TCValues"
ng-change="create.setTotalCopayers(totalCopayers)">
</select>
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-select">
<div class="input-label" translate>
Required number of signatures
</div>
<select class="m10t"
ng-model="requiredCopayers"
ng-options="requiredCopayers as requiredCopayers for requiredCopayers in create.RCValues"
ng-disabled="totalCopayers == 1">
</select>
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
<label class="item item-input item-select">
<div class="input-label" translate>
Wallet Key
</div>
<select class="m10t"
ng-model="seedSource"
ng-options="seed as seed.label for seed in create.seedOptions"
ng-change="create.setSeedSource()">
</select>
</label>
<label class="item item-input item-stacked-label"
ng-show="create.seedSourceId == 'trezor' || create.seedSourceId == 'ledger'">
<span class="input-label" translate>Account Number</span>
<input type="number" id="account" ng-model="account" ignore-mouse-wheel>
</label>
<div class="card" ng-show="create.seedSourceId=='new' && createPassphrase">
<div class="item item-text-wrap" translate>
WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password.
</div>
</div>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='new'">
<span class="input-label" translate>Add a Password</span>
<input type="text"
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}"
autocapitalize="off"
name="createPassphrase"
ng-model="createPassphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Wallet Recovery Phrase</span>
<input id="ext-master"
placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
autocapitalize="off"
type="text"
name="privateKey"
ng-model="privateKey">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
name="passphrase"
ng-model="passphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId == 'set'">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
name="derivationPath"
ng-model="derivationPath">
</label>
<ion-toggle ng-show="create.seedSourceId == 'new'" ng-model="testnetEnabled" toggle-class="toggle-positive">
Testnet
</ion-toggle>
<ion-toggle ng-model="singleAddressEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers != 1" ng-disabled="setupForm.$invalid">
<span translate>Create {{requiredCopayers}}-of-{{totalCopayers}} wallet</span>
</button>
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers == 1" ng-disabled="setupForm.$invalid">
<span translate>Create new wallet</span>
</button>
</form>
</ion-content>
</ion-tabs>
</ion-view>

View File

@ -1,131 +1,13 @@
<ion-view cache-view="false">
<ion-tabs class="tabs-striped tabs-color-positive tabs-color-active-positive tabs-top">
<ion-view>
<ion-nav-bar class="bar-stable">
<ion-nav-title>Export Wallet</ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="wallet.preferencesAdvanced">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content ng-controller="exportController" cache-view="false" ng-init="init()">
<ion-tab title="File/Text" ui-sref="wallet.export.file">
<ion-nav-view name="tab-export-file"></ion-nav-view>
</ion-tab>
<div ng-show="!canSign"><h4></h4></div>
<div class="row" ng-show="canSign">
<div class="col"
ng-class="{'selected':!exportQR}"
ng-style="{'border-color':!exportQR ? wallet.color: 'inherit'}"
ng-click="exportQR = false">
<a class="button button-full button-clear" ng-style="{'color':!exportQR ? wallet.color: 'inherit'}" translate>File/Text</a>
</div>
<div class="col"
ng-class="{'selected':exportQR}"
ng-style="{'border-color':exportQR ? wallet.color: 'inherit'}"
ng-click="exportQR = true">
<a class="button button-full button-clear" ng-style="{'color':exportQR ? wallet.color: 'inherit'}" translate>QR Code</a>
</div>
</div>
<ion-tab title="QR Code" ui-sref="wallet.export.qrCode">
<ion-nav-view name="tab-export-qrCode"></ion-nav-view>
</ion-tab>
<div ng-show="!backupWalletPlainText">
<div class="text-warning size-14 m20b" ng-show="error">
<i class="fi-alert size-12"></i>
<span translate>Failed to export</span>
</div>
<form name="exportForm" ng-show="!exportQR" novalidate>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Set up a password</span>
<input type="password" placeholder="{{'Your password'|translate}}" name="password" ng-model="password">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Repeat the password</span>
<input type="password" class="form-control" placeholder="{{'Repeat password'|translate}}" name="password" ng-model="repeatpassword">
</label>
</form>
<div class="m20t text-gray" ng-show="exportQR && supported">
<div class="text-center m20b">
<qrcode size="220" version="8" error-correction-level="M" data="{{exportWalletInfo}}"></qrcode>
</div>
<div class="text-center size-12 m10" translate>From the destination device, go to Add wallet &gt; Import wallet and scan this QR code</div>
</div>
<div class="m20t text-gray" ng-show="exportQR && !supported">
<div class="text-center size-12 m10" translate>Exporting via QR not supported for this wallet</div>
</div>
<ion-toggle ng-show="!exportQR && canSign" ng-model="showAdvanced" toggle-class="toggle-balanced">
<span translate ng-show="!showAdvanced">Show advanced options</span>
<span translate ng-show="showAdvanced">Hide advanced options</span>
</ion-toggle>
<ion-toggle ng-model="noSignEnabled" ng-show="showAdvanced && !exportQR" toggle-class="toggle-balanced" class="r0" ng-change="noSignEnabledChange()">
<span class="toggle-label" translate>Do not include private key</span>
</ion-toggle>
<div class="box-notification p15l" ng-show="!canSign">
<span class="text-warning size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: The private key of this wallet is not available. The export allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<div class="box-notification p15l" ng-show="noSignEnabled && !exportQR">
<span class="text-warning size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: Not including the private key allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<button ng-show="!exportQR"
ng-click="downloadWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="!isSafari && !isCordova">
<i class="fi-download"></i>
<span translate>Download</span>
</button>
<button ng-show="!exportQR"
ng-click="viewWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="isSafari && !isCordova">
<i class="fi-eye"></i>
<span translate>View</span>
</button>
<div ng-show="isCordova">
<h4 translate>Export options</h4>
<button class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':index.backgroundColor}"
ng-click="copyWalletBackup()">
<i class="fi-clipboard-pencil"></i>
<span translate>Copy to clipboard</span></button>
<button class="button button-block button-positive" ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':index.backgroundColor}"
ng-click="sendWalletBackup()"><i class="fi-mail"></i>
<span translate>Send by email</span></button>
</div>
</div>
<div class="row" ng-show="backupWalletPlainText">
<div class="large-12 columns">
<h3 translate>Wallet Export</h3>
<div class="input">
<textarea rows="12">{{backupWalletPlainText}}</textarea>
</div>
<div class="size-12 text-gray text-right">
<i class="icon-compose"></i>
<span translate>Copy this text as it is to a safe place (notepad or email)</span>
</div>
</div>
</div>
</ion-content>
</ion-tabs>
</ion-view>

View File

@ -1,239 +1,17 @@
<ion-view>
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Import wallet</ion-nav-title>
</ion-nav-bar>
<ion-view cache-view="false">
<ion-tabs class="tabs-striped tabs-color-positive tabs-color-active-positive tabs-top">
<ion-content ng-controller="importController" ng-init="type='12'">
<ion-tab title="Recovery Phrare" ui-sref="add.import.phrase">
<ion-nav-view name="tab-import-phrase"></ion-nav-view>
</ion-tab>
<div class="row">
<div class="col">
<button
ng-class="{'button-dark': type == '12', 'button-stable': type != '12'}"
class="button button-full button-clear"
ng-click="setType('12')" translate>
Recovery Phrase
</button>
</div>
<div class="col">
<button
ng-class="{'button-dark': type == 'file', 'button-stable': type != 'file'}"
class="button button-full button-clear"
ng-click="setType('file')" translate>
File/Text
</button>
</div>
<div class="col">
<button
ng-class="{'button-dark': type == 'hwWallet', 'button-stable': type != 'hwWallet'}"
class="button button-full button-clear"
ng-click="setType('hwWallet')" translate>
Hardware Wallet
</button>
</div>
</div>
<ion-tab title="File/Text" ui-sref="add.import.file">
<ion-nav-view name="tab-import-file"></ion-nav-view>
</ion-tab>
<div ng-show="type == '12'">
<ion-tab title="Hardware Wallet" ui-sref="add.import.hardware">
<ion-nav-view name="tab-import-hardware"></ion-nav-view>
</ion-tab>
<div ng-show="importErr || error" class="padding assertive" ng-click="importErr = error = null">
<div ng-show="importErr">
<div translate>Could not access the wallet at the server. Please check:</div>
<ul>
<li translate>The password of the recovery phrase (if set)</li>
<li translate>The derivation path</li>
<li translate>The wallet service URL</li>
</ul>
<div translate>
NOTE: To import a wallet from a 3rd party software, please go to Add Wallet &gt; Create Wallet, and specify the Recovery Phrase there.
</div>
</div>
<div ng-show="error">
{{error|translate}}
</div>
</div>
<form name="importForm12" ng-submit="importMnemonic(importForm12)" novalidate>
<div class="list">
<div class="row">
<div class="col col-90">
<label class="item item-input item-stacked-label no-border">
<span class="input-label" translate>Type the Recovery Phrase (usually 12 words)</span>
<textarea name="words"
ng-model="words"
rows="3"
autocapitalize="off"
spellcheck="false"></textarea>
</label>
</div>
<div class="col text-center">
<qr-scanner class="qr-icon size-24" on-scan="processWalletInfo(data)"></qr-scanner>
</div>
</div>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
name="passphrase"
ng-model="passphrase">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
name="derivationPath"
ng-model="derivationPath">
</label>
<ion-toggle ng-model="testnetEnabled" ng-change="setDerivationPath(testnetEnabled)" toggle-class="toggle-positive">
Testnet
</ion-toggle>
</div>
</div>
<button type="submit"
class="button button-block button-positive"
ng-disabled="importForm12.$invalid" translate>Import</button>
</form>
</div>
<div ng-show="type == 'file'">
<div class="padding assertive" ng-show="error">
{{error|translate}}
</div>
<form name="importForm" ng-submit="importBlob(importForm)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label no-border" ng-show="!isSafari && !isCordova">
<div class="input-label" translate>Choose a backup file from your computer</div>
<div>
<input type="file"
placeholder="{{'Select a backup file'|translate}}"
name="backupFile"
ng-model="backupFile" ng-file-select>
</div>
</label>
<label class="item item-input item-stacked-label" ng-show="isSafari || isCordova">
<span class="input-label" translate>Paste the backup plain text code</span>
<textarea name="backupText" ng-model="backupText" rows="5"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Password</span>
<input type="password"
placeholder="{{'Your password'|translate}}"
name="password"
ng-model="password">
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
</div>
</div>
<button type="submit"
class="button round expand black"
ng-disabled="importForm.$invalid || !password " translate>
Import backup
</button>
</form>
</div>
<div ng-show="type == 'hwWallet'">
<div class="padding assertive" ng-show="error">
{{error|translate}}
</div>
<form name="importForm3" ng-submit="importHW(importForm3)" novalidate>
<div class="card" ng-show="!seedOptions[0]">
<div class="item item-text-wrap" translate>
No hardware wallets supported on this device
</div>
</div>
<div ng-show="seedOptions[0]">
<div class="list">
<label class="item item-input item-select">
<div class="input-label" translate>
Wallet Type
</div>
<select ng-model="seedSource"
ng-options="seed as seed.label for seed in seedOptions"
ng-change="setSeedSource()">
</select>
</label>
<label class="item item-input item-stacked-label"
ng-show="seedSourceId == 'trezor' || seedSourceId == 'ledger'">
<span class="input-label" translate>Account Number</span>
<input type="number" id="account" ng-model="account" ignore-mouse-wheel>
</label>
<ion-toggle ng-show="seedSourceId == 'trezor'"
ng-model="isMultisig"
toggle-class="toggle-positive">
<span translate>Shared Wallet</span>
</ion-toggle>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
</div>
</div>
<button translate type="submit" class="button button-block button-positive">
Import
</button>
</div> <!-- seedoptions show -->
</form>
</div>
</ion-content>
</ion-tabs>
</ion-view>

View File

@ -19,7 +19,7 @@
<span translate>Sweep paper wallet</span>
<i class="icon ion-ios-arrow-right"></i>
</div>
<div class="item item-icon-right" href ui-sref="wallet.export">
<div class="item item-icon-right" href ui-sref="wallet.export.file">
<span translate>Export Wallet</span>
<i class="icon ion-ios-arrow-right"></i>
</div>

View File

@ -0,0 +1,129 @@
<ion-view>
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Create new wallet</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="createController as create" ng-init="create.setTotalCopayers(1)">
<div class="padding assertive" ng-show="create.error">
{{create.error|translate}}
</div>
<form name="setupForm" ng-submit="create.create(setupForm)" novalidate>
<div class="list">
<label ng-hide="create.hideWalletName" class="item item-input item-stacked-label">
<span class="input-label" translate>Wallet name</span>
<input type="text"
placeholder="{{'Family vacation funds'|translate}}"
name="walletName"
ng-model="walletName"
ng-required="true"
ng-focus="create.formFocus('wallet-name')"
ng-blur="create.formFocus(false)">
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
<label class="item item-input item-select">
<div class="input-label" translate>
Wallet Key
</div>
<select class="m10t"
ng-model="seedSource"
ng-options="seed as seed.label for seed in create.seedOptions"
ng-change="create.setSeedSource()">
</select>
</label>
<label class="item item-input item-stacked-label"
ng-show="create.seedSourceId == 'trezor' || create.seedSourceId == 'ledger'">
<span class="input-label" translate>Account Number</span>
<input type="number" id="account" ng-model="account" ignore-mouse-wheel>
</label>
<div class="card" ng-show="create.seedSourceId=='new' && createPassphrase">
<div class="item item-text-wrap" translate>
WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password.
</div>
</div>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='new'">
<span class="input-label" translate>Add a Password</span>
<input type="text"
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}"
autocapitalize="off"
name="createPassphrase"
ng-model="createPassphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Wallet Recovery Phrase</span>
<input id="ext-master"
placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
autocapitalize="off"
type="text"
name="privateKey"
ng-model="privateKey">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
name="passphrase"
ng-model="passphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId == 'set'">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
name="derivationPath"
ng-model="derivationPath">
</label>
<ion-toggle ng-show="create.seedSourceId == 'new'" ng-model="testnetEnabled" toggle-class="toggle-positive">
Testnet
</ion-toggle>
<ion-toggle ng-model="singleAddressEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers != 1" ng-disabled="setupForm.$invalid">
<span translate>Create {{requiredCopayers}}-of-{{totalCopayers}} wallet</span>
</button>
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers == 1" ng-disabled="setupForm.$invalid">
<span translate>Create new wallet</span>
</button>
</form>
</ion-content>
</ion-view>

View File

@ -0,0 +1,161 @@
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Create new wallet</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="createController as create" ng-init="create.setTotalCopayers(3)">
<div class="padding assertive" ng-show="create.error">
{{create.error|translate}}
</div>
<form name="setupForm" ng-submit="create.create(setupForm)" novalidate>
<div class="list">
<label ng-hide="create.hideWalletName" class="item item-input item-stacked-label">
<span class="input-label" translate>Wallet name</span>
<input type="text"
placeholder="{{'Family vacation funds'|translate}}"
name="walletName"
ng-model="walletName"
ng-required="true"
ng-focus="create.formFocus('wallet-name')"
ng-blur="create.formFocus(false)">
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-stacked-label">
<span class="input-label" translate>Your nickname</span>
<input type="text"
placeholder="{{'John'|translate}}"
name="myName"
ng-model="myName"
ng-required="totalCopayers != 1"
ng-disabled="totalCopayers == 1"
ng-focus="create.formFocus('my-name')"
ng-blur="create.formFocus(false)">
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-select">
<div class="input-label" translate>
Total number of copayers
</div>
<select class="m10t"
ng-model="totalCopayers"
ng-options="totalCopayers as totalCopayers for totalCopayers in create.TCValues"
ng-change="create.setTotalCopayers(totalCopayers)">
</select>
</label>
<label ng-show="totalCopayers != 1" class="item item-input item-select">
<div class="input-label" translate>
Required number of signatures
</div>
<select class="m10t"
ng-model="requiredCopayers"
ng-options="requiredCopayers as requiredCopayers for requiredCopayers in create.RCValues"
ng-disabled="totalCopayers == 1">
</select>
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
<label class="item item-input item-select">
<div class="input-label" translate>
Wallet Key
</div>
<select class="m10t"
ng-model="seedSource"
ng-options="seed as seed.label for seed in create.seedOptions"
ng-change="create.setSeedSource()">
</select>
</label>
<label class="item item-input item-stacked-label"
ng-show="create.seedSourceId == 'trezor' || create.seedSourceId == 'ledger'">
<span class="input-label" translate>Account Number</span>
<input type="number" id="account" ng-model="account" ignore-mouse-wheel>
</label>
<div class="card" ng-show="create.seedSourceId=='new' && createPassphrase">
<div class="item item-text-wrap" translate>
WARNING: The password cannot be recovered. <b>Be sure to write it down</b>. The wallet can not be restored without the password.
</div>
</div>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='new'">
<span class="input-label" translate>Add a Password</span>
<input type="text"
placeholder="{{'Add an optional password to secure the recovery phrase'|translate}}"
autocapitalize="off"
name="createPassphrase"
ng-model="createPassphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Wallet Recovery Phrase</span>
<input id="ext-master"
placeholder="{{'Enter the recovery phrase (BIP39)'|translate}}"
autocapitalize="off"
type="text"
name="privateKey"
ng-model="privateKey">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId=='set'">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
name="passphrase"
ng-model="passphrase">
</label>
<label class="item item-input item-stacked-label" ng-show="create.seedSourceId == 'set'">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
name="derivationPath"
ng-model="derivationPath">
</label>
<ion-toggle ng-show="create.seedSourceId == 'new'" ng-model="testnetEnabled" toggle-class="toggle-positive">
Testnet
</ion-toggle>
<ion-toggle ng-model="singleAddressEnabled" toggle-class="toggle-positive">
<span translate>Single Address Wallet</span>
<small translate>For audit purposes</small>
</ion-toggle>
</div> <!-- advanced -->
</div> <!-- list -->
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers != 1" ng-disabled="setupForm.$invalid">
<span translate>Create {{requiredCopayers}}-of-{{totalCopayers}} wallet</span>
</button>
<button type="submit"
class="button button-block button-positive"
ng-show="totalCopayers == 1" ng-disabled="setupForm.$invalid">
<span translate>Create new wallet</span>
</button>
</form>
</ion-content>

View File

@ -0,0 +1,102 @@
<ion-nav-bar class="bar-stable">
<ion-nav-title>Export Wallet</ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="wallet.preferencesAdvanced">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content ng-controller="exportController" ng-init="init()" cache-view="true">
<div ng-show="!backupWalletPlainText">
<div class="size-14" ng-show="error">
<i class="ion-alert-circled"></i>
<span translate>Failed to export</span>
</div>
<form name="exportForm" novalidate>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Set up a password</span>
<input type="password" placeholder="{{'Your password'|translate}}" name="password" ng-model="password">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" transalate>Repeat the password</span>
<input type="password" class="form-control" placeholder="{{'Repeat password'|translate}}" name="password" ng-model="repeatpassword">
</label>
</form>
<ion-toggle ng-show="canSign" ng-model="showAdvanced" toggle-class="toggle-balanced">
<span translate ng-show="!showAdvanced">Show advanced options</span>
<span translate ng-show="showAdvanced">Hide advanced options</span>
</ion-toggle>
<ion-toggle ng-model="noSignEnabled" ng-show="showAdvanced" toggle-class="toggle-balanced" class="r0" ng-change="noSignEnabledChange()">
<span class="toggle-label" translate>Do not include private key</span>
</ion-toggle>
<div class="box-notification" ng-show="!canSign">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: The private key of this wallet is not available. The export allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<div class="box-notification" ng-show="noSignEnabled">
<span class="size-14">
<i class="ion-alert-circled"></i>
<span translate>
WARNING: Not including the private key allows to check the wallet balance, transaction history, and create spend proposals from the export. However, does not allow to approve (sign) proposals, so <b>funds will not be accessible from the export</b>.
</span>
</span>
</div>
<button
ng-click="downloadWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="!isSafari && !isCordova">
<i class="fi-download"></i>
<span translate>Download</span>
</button>
<button
ng-click="viewWalletBackup()"
class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':wallet.color}"
ng-show="isSafari && !isCordova">
<i class="fi-eye"></i>
<span translate>View</span>
</button>
<div ng-show="isCordova">
<h4 translate>Export options</h4>
<button class="button button-block button-positive"
ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':index.backgroundColor}"
ng-click="copyWalletBackup()">
<i class="fi-clipboard-pencil"></i>
<span translate>Copy to clipboard</span></button>
<button class="button button-block button-positive" ng-disabled="(!password || password != repeatpassword)"
ng-style="{'background-color':index.backgroundColor}"
ng-click="sendWalletBackup()"><i class="fi-mail"></i>
<span translate>Send by email</span></button>
</div>
</div>
<div class="row" ng-show="backupWalletPlainText">
<div class="large-12 columns">
<h3 translate>Wallet Export</h3>
<div class="input">
<textarea rows="12">{{backupWalletPlainText}}</textarea>
</div>
<div class="size-12 text-gray text-right">
<i class="icon-compose"></i>
<span translate>Copy this text as it is to a safe place (notepad or email)</span>
</div>
</div>
</div>
</ion-content>

View File

@ -0,0 +1,23 @@
<ion-nav-bar class="bar-stable">
<ion-nav-title>Export Wallet</ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="wallet.preferencesAdvanced">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content ng-controller="exportController" ng-init="init()">
<div class="m20t text-gray" ng-show="supported">
<div class="text-center m20b">
<qrcode size="220" version="8" error-correction-level="M" data="{{exportWalletInfo}}"></qrcode>
</div>
<div class="text-center size-12 m10" translate>From the destination device, go to Add wallet &gt; Import wallet and scan this QR code</div>
</div>
<div class="m20t text-gray" ng-show="!supported">
<div class="text-center size-12 m10" translate>Exporting via QR not supported for this wallet</div>
</div>
</ion-content>

View File

@ -0,0 +1,65 @@
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Import wallet</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="importController" ng-init="type='file'">
<div class="padding assertive" ng-show="error">
{{error|translate}}
</div>
<form name="importForm" ng-submit="importBlob(importForm)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label no-border" ng-show="!isSafari && !isCordova">
<div class="input-label" translate>Choose a backup file from your computer</div>
<div>
<input type="file"
placeholder="{{'Select a backup file'|translate}}"
name="backupFile"
ng-model="backupFile" ng-file-select>
</div>
</label>
<label class="item item-input item-stacked-label" ng-show="isSafari || isCordova">
<span class="input-label" translate>Paste the backup plain text code</span>
<textarea name="backupText" ng-model="backupText" rows="5"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Password</span>
<input type="password"
placeholder="{{'Your password'|translate}}"
name="password"
ng-model="password">
</label>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
</div>
</div>
<button type="submit"
class="button round expand black"
ng-disabled="importForm.$invalid || !password " translate>
Import backup
</button>
</form>
</ion-content>

View File

@ -0,0 +1,71 @@
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Import wallet</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="importController" ng-init="type='hwWallet'">
<div class="padding assertive" ng-show="error">
{{error|translate}}
</div>
<form name="importForm3" ng-submit="importHW(importForm3)" novalidate>
<div class="card" ng-show="!seedOptions[0]">
<div class="item item-text-wrap" translate>
No hardware wallets supported on this device
</div>
</div>
<div ng-show="seedOptions[0]">
<div class="list">
<label class="item item-input item-select">
<div class="input-label" translate>
Wallet Type
</div>
<select ng-model="seedSource"
ng-options="seed as seed.label for seed in seedOptions"
ng-change="setSeedSource()">
</select>
</label>
<label class="item item-input item-stacked-label"
ng-show="seedSourceId == 'trezor' || seedSourceId == 'ledger'">
<span class="input-label" translate>Account Number</span>
<input type="number" id="account" ng-model="account" ignore-mouse-wheel>
</label>
<ion-toggle ng-show="seedSourceId == 'trezor'"
ng-model="isMultisig"
toggle-class="toggle-positive">
<span translate>Shared Wallet</span>
</ion-toggle>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
</div>
</div>
<button translate type="submit" class="button button-block button-positive">
Import
</button>
</div> <!-- seedoptions show -->
</form>
</ion-content>

View File

@ -0,0 +1,88 @@
<ion-nav-bar class="bar-stable">
<ion-nav-buttons side="primary">
<button class="button no-border" ui-sref="add.main">
<i class="icon ion-chevron-left"></i> Back
</button>
</ion-nav-buttons>
<ion-nav-title>Import wallet</ion-nav-title>
</ion-nav-bar>
<ion-content ng-controller="importController" ng-init="type='12'">
<div ng-show="importErr || error" class="padding assertive" ng-click="importErr = error = null">
<div ng-show="importErr">
<div translate>Could not access the wallet at the server. Please check:</div>
<ul>
<li translate>The password of the recovery phrase (if set)</li>
<li translate>The derivation path</li>
<li translate>The wallet service URL</li>
</ul>
<div translate>
NOTE: To import a wallet from a 3rd party software, please go to Add Wallet &gt; Create Wallet, and specify the Recovery Phrase there.
</div>
</div>
<div ng-show="error">
{{error|translate}}
</div>
</div>
<form name="importForm12" ng-submit="importMnemonic(importForm12)" novalidate>
<div class="list">
<div class="row">
<div class="col col-90">
<label class="item item-input item-stacked-label no-border">
<span class="input-label" translate>Type the Recovery Phrase (usually 12 words)</span>
<textarea name="words"
ng-model="words"
rows="3"
autocapitalize="off"
spellcheck="false"></textarea>
</label>
</div>
<div class="col text-center">
<qr-scanner class="qr-icon size-24" on-scan="processWalletInfo(data)"></qr-scanner>
</div>
</div>
<ion-toggle ng-model="showAdv" toggle-class="toggle-stable">
<span translate ng-show="!showAdv">Show advanced options</span>
<span translate ng-show="showAdv">Hide advanced options</span>
</ion-toggle>
<div ng-show="showAdv">
<label class="item item-input item-stacked-label">
<span class="input-label">Wallet Service URL</span>
<input type="text" id="bwsurl" name="bwsurl" ng-model="bwsurl">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Password</span>
<input type="text"
placeholder="{{'The recovery phrase could require a password to be imported'|translate}}"
autocapitalize="off"
name="passphrase"
ng-model="passphrase">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label" translate>Derivation Path</span>
<input type="text"
placeholder="{{'BIP32 path for address derivation'|translate}}"
name="derivationPath"
ng-model="derivationPath">
</label>
<ion-toggle ng-model="testnetEnabled" ng-change="setDerivationPath(testnetEnabled)" toggle-class="toggle-positive">
Testnet
</ion-toggle>
</div>
</div>
<button type="submit"
class="button button-block button-positive"
ng-disabled="importForm12.$invalid" translate>Import</button>
</form>
</ion-content>

View File

@ -199,6 +199,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('wallet.export', {
abstract: true,
url: '/export',
views: {
'wallet': {
@ -206,6 +207,24 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
.state('wallet.export.file', {
url: '/tab-export-file',
needProfile: true,
views: {
'tab-export-file': {
templateUrl: 'views/tab-export-file.html',
},
}
})
.state('wallet.export.qrCode', {
url: '/tab-export-qrCode',
needProfile: true,
views: {
'tab-export-qrCode': {
templateUrl: 'views/tab-export-qrCode.html',
},
}
})
.state('wallet.preferencesBwsUrl', {
url: '/preferencesBwsUrl',
views: {
@ -371,21 +390,63 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
})
.state('add.import', {
url: '/import',
abstract: true,
views: {
'add': {
templateUrl: 'views/import.html'
},
}
})
.state('add.import.phrase', {
url: '/tab-import-phrase',
views: {
'tab-import-phrase': {
templateUrl: 'views/tab-import-phrase.html',
},
}
})
.state('add.import.file', {
url: '/tab-import-file',
views: {
'tab-import-file': {
templateUrl: 'views/tab-import-file.html',
},
}
})
.state('add.import.hardware', {
url: '/tab-import-hardware',
views: {
'tab-import-hardware': {
templateUrl: 'views/tab-import-hardware.html',
},
}
})
.state('add.create', {
url: '/create',
abstract: true,
templateUrl: 'views/create.html',
views: {
'add': {
templateUrl: 'views/create.html'
},
}
})
.state('add.create.personal', {
url: '/tab-create-personal',
views: {
'tab-create-personal': {
templateUrl: 'views/tab-create-personal.html',
},
}
})
.state('add.create.shared', {
url: '/tab-create-shared',
views: {
'tab-create-shared': {
templateUrl: 'views/tab-create-shared.html',
},
}
})
/*
*

View File

@ -1027,6 +1027,10 @@ input[type="number"] {
}
}
.tab-item {
max-width: 100%;
}
@media all and (max-height: 480px) {
.calculator .button-calc .columns { padding: 10px; }
.calculator .header-calc { top: 11%; }
@ -1041,4 +1045,3 @@ input[type="number"] {
.calculator .button-calc .columns { padding: 20px; }
.calculator .header-calc { top: 18%; }
}