Merged latest changes.

# Conflicts:
#	src/js/controllers/review.controller.js
#	www/views/review.html
This commit is contained in:
Brendon Duncan 2018-08-14 16:15:05 +12:00
commit 9b5f4b3516
120 changed files with 6969 additions and 1882 deletions

View file

@ -163,7 +163,7 @@ module.exports = function(grunt) {
},
bitanalytics: {
src: [
'bitanalytics/bitanalytics-0.1.0.js'
'bitanalytics/bitanalytics.js'
],
dest: 'www/lib/bitanalytics.js'
},

View file

@ -24,9 +24,9 @@
"windowsAppId": "804636ee-b017-4cad-8719-e58ac97ffa5c",
"pushSenderId": "1036948132229",
"description": "A Secure Bitcoin Wallet",
"version": "4.13.0",
"fullVersion": "4.13-rc1",
"androidVersion": "413000",
"version": "4.13.2",
"fullVersion": "4.13-rc3",
"androidVersion": "413200",
"_extraCSS": "",
"_enabledExtensions": {
"coinbase": false,

View file

@ -268,5 +268,33 @@ div.onboarding-topic {
display: block;
float: left;
max-height: 100%;
max-width: 100%;
max-width: 100%;
}
.bitpay-banner {
background: #1A3A8B;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
}
.bitpay-logo {
display: block;
max-height: 100%;
width: 100%;
height: 4em;
}
.egifter-banner {
background: #1A3A8B;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
text-align: center;
}
.egifter-logo {
max-height: 100%;
max-width: 100%;
height: 4em;
}

View file

@ -72,7 +72,7 @@
<plugin name="cordova-plugin-queries-schemes" spec="~0.1.5" />
<plugin name="cordova-plugin-firebase" spec="https://github.com/arnesson/cordova-plugin-firebase.git" />
<plugin name="cordova-plugin-wkwebview-inputfocusfix" spec="https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfix.git" />
<plugin name="cordova-plugin-media" spec="~5.0.2">
<plugin name="cordova-plugin-media-fork" spec="~5.0.3">
<variable name="KEEP_AVAUDIOSESSION_ALWAYS_ACTIVE" value="NO" />
</plugin>
<!-- Supported Platforms -->

View file

@ -6256,7 +6256,6 @@ var ClickAction = /** @class */ (function (_super) {
// Add event listener to all the elements found
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
console.log('init ' + this.name);
element.addEventListener('click', this.listener);
}
};
@ -6276,7 +6275,7 @@ var ClickAction = /** @class */ (function (_super) {
}(action_1.default));
exports.default = ClickAction;
},{"../action":4,"../log-event":15,"../log-event-handlers":14}],6:[function(require,module,exports){
},{"../action":4,"../log-event":16,"../log-event-handlers":15}],6:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6315,7 +6314,7 @@ var BitAnalytics = /** @class */ (function () {
exports.default = BitAnalytics;
BitAnalytics.main();
},{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":15,"./log-event-handlers":14}],7:[function(require,module,exports){
},{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":16,"./log-event-handlers":15}],7:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6413,7 +6412,6 @@ var AdjustChannel = /** @class */ (function (_super) {
_this.eventTypes = config.eventTypes;
var os = _this.adjustedOs(config.os);
_this.advertisingId = _this.getAdvertisingId(os);
console.log('Advertising ID for adjust: ' + _this.advertisingId);
// TODO: Different initialisation for Cordova.
var sessionParams = {
app_version: config.appVersion,
@ -6560,11 +6558,10 @@ var FirebaseChannel = /** @class */ (function (_super) {
var keys = Object.keys(params);
var keysLength = keys.length;
var sanitized = {};
for (var i = 0; i < keysLength; i++) {
var key = keys[i];
keys.map(function (key) {
var cleanKey = key.replace('-', '_').replace(/[\W]+/g, '');
sanitized[cleanKey] = params[key];
}
});
return sanitized;
};
return FirebaseChannel;
@ -6588,13 +6585,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
var channel_1 = __importDefault(require("../channel"));
var ga_1 = __importDefault(require("../external-libs/ga"));
var GoogleAnalyticsChannel = /** @class */ (function (_super) {
__extends(GoogleAnalyticsChannel, _super);
function GoogleAnalyticsChannel(name, config) {
var _this = _super.call(this, name) || this;
_this.dataLayer = null;
_this.gaInstance = null;
_this.trackingId = '';
_this.eventLabels = ['id'];
if (!config.trackingId) {
throw new Error('[BitAnalytics] Google Analytics config is missing tracking ID.');
@ -6602,8 +6598,12 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
if (config.eventLabels) {
_this.eventLabels = config.eventLabels;
}
_this.trackingId = config.trackingId;
_this.setUpGa();
_this.gaInstance = new ga_1.default({
trackID: config.trackingId,
appVersion: config.appVersion,
appName: config.appName || 'App'
});
_this.isReady = true;
return _this;
}
/**
@ -6612,49 +6612,26 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
*
*/
GoogleAnalyticsChannel.prototype.postEvent = function (name, params) {
// Default Google Analytics Events
// https://developers.google.com/analytics/devguides/collection/gtagjs/events
// Useful to convert to these, or start with these?
if (this.isReady) {
params.event_category = name;
var category = name;
var action = name;
var label = name;
var value = params['value'] || '';
for (var _i = 0, _a = this.eventLabels; _i < _a.length; _i++) {
var eventLabel = _a[_i];
if (params[eventLabel]) {
params.event_label = params[eventLabel];
label = params[eventLabel];
break;
}
}
this.gtag('event', name, params);
this.gaInstance.event(category, action, label, value);
}
};
/**
*
* Private methods
*
*/
/**
* Mimics function in the tracking snippet
*/
GoogleAnalyticsChannel.prototype.gtag = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log(arguments);
window.dataLayer.push(arguments);
};
GoogleAnalyticsChannel.prototype.setUpGa = function () {
// From what GA recommends to insert into page
window.dataLayer = window.dataLayer || [];
this.gtag('js', new Date());
this.gtag('config', this.trackingId);
this.isReady = true;
};
return GoogleAnalyticsChannel;
}(channel_1.default));
exports.default = GoogleAnalyticsChannel;
},{"../channel":8}],12:[function(require,module,exports){
},{"../channel":8,"../external-libs/ga":14}],12:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@ -6677,7 +6654,7 @@ var MixpanelChannel = /** @class */ (function (_super) {
function MixpanelChannel(name, config) {
var _this = _super.call(this, name) || this;
if (!config.token) {
throw new DOMException('[BitAnalytics] Config incorrect.');
throw new Error('[BitAnalytics] Config incorrect.');
}
_this.mixpanelInstance = mixpanel;
mixpanel.init(config.token, config.config);
@ -6746,6 +6723,207 @@ exports.default = MixpanelChannel;
},{}],14:[function(require,module,exports){
"use strict";
/*
* name: nwjs-analytics -Node-Webkit Google Analytics integration
* version: 1.0.2
* github: https://github.com/Daaru00/nwjs-analytics
*/
function GA(opt) {
this.apiVersion = opt.apiVersion || '1';
this.trackID = opt.trackID || 'UA-XXXXXXXX-X';
this.clientID = opt.clientID || null;
this.userID = opt.userID || null;
this.appName = opt.appName || 'App';
this.appVersion = opt.appVersion || '1.0.0';
this.debug = opt.debug || false;
this.performanceTracking = opt.performanceTracking || true;
this.errorTracking = opt.errorTracking || true;
this.userLanguage = opt.userLanguage || "en";
this.currency = opt.currency || "EUR";
this.lastScreenName = opt.lastScreenName || '';
}
GA.prototype.sendRequest = function (data, callback) {
var ga = this;
if (!this.clientID || this.clientID == null)
this.clientID = this.generateClientID();
if (!this.userID || this.userID == null)
this.userID = this.generateClientID();
var postData = "v=" + this.apiVersion
+ "&an=" + this.appName
+ "&av=" + this.appVersion
+ "&tid=" + this.trackID
+ "&cid=" + this.clientID
+ "&sr=" + this.getScreenResolution()
+ "&vp=" + this.getViewportSize();
Object.keys(data).forEach(function (key) {
var val = data[key];
if (typeof val != "undefined")
postData += "&" + key + "=" + val;
});
var http = new XMLHttpRequest();
var url = "https://www.google-analytics.com";
if (!this.debug)
url += "/collect";
else
url += "/debug/collect";
http.open("GET", url + "?" + postData, true);
http.onreadystatechange = function () {
if (ga.debug)
console.log(http.response);
if (http.readyState == 4 && http.status == 200) {
if (callback)
callback(true);
}
else {
if (callback)
callback(false);
}
};
http.send();
};
GA.prototype.generateClientID = function () {
var id = "";
var possibilities = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
};
GA.prototype.getScreenResolution = function () {
return screen.width + "x" + screen.height;
};
GA.prototype.getColorDept = function () {
return screen.colorDepth + "-bits";
};
GA.prototype.getUserAgent = function () {
return navigator.userAgent;
};
GA.prototype.getViewportSize = function () {
return window.screen.availWidth + "x" + window.screen.availHeight;
};
/*
* Measurement Protocol
* [https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide]
*/
GA.prototype.screenView = function (screename) {
var data = {
't': 'screenview',
'cd': screename
};
this.sendRequest(data);
this.lastScreenName = screename;
};
GA.prototype.event = function (category, action, label, value) {
var data = {
't': 'event',
'ec': category,
'ea': action,
};
if (label) {
data['el'] = label;
}
if (value) {
data['ev'] = value;
}
if (this.lastScreenName) {
data['cd'] = this.lastScreenName;
}
this.sendRequest(data);
};
GA.prototype.exception = function (msg, fatal) {
var data = {
't': 'exception',
'exd': msg,
'exf': fatal || 0
};
this.sendRequest(data);
};
GA.prototype.timing = function (category, variable, time, label) {
var data = {
't': 'timing',
'utc': category,
'utv': variable,
'utt': time,
'utl': label,
};
this.sendRequest(data);
},
GA.prototype.ecommerce = {
transactionID: false,
generateTransactionID: function () {
var id = "";
var possibilities = "0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
},
transaction: function (total, items) {
var t_id = "";
if (!this.ecommerce.transactionID)
t_id = this.ecommerce.generateTransactionID();
else
t_id = this.ecommerce.transactionID;
var data = {
't': 'transaction',
'ti': t_id,
'tr': total,
'cu': this.currency,
};
this.sendRequest(data);
items.forEach(function (item) {
var data = {
't': 'item',
'ti': t_id,
'in': item.name,
'ip': item.price,
'iq': item.qty,
'ic': item.id,
'cu': this.currency
};
this.sendRequest(data);
});
}
},
GA.prototype.custom = function (data) {
this.sendRequest(data);
};
module.exports = GA;
/*
* Performance Tracking
*/
/*window.addEventListener("load", function() {
if(ga.performanceTracking) {
setTimeout(function() {
var timing = window.performance.timing;
var userTime = timing.loadEventEnd - timing.navigationStart;
ga.timing("performance", "pageload", userTime);
}, 0);
}
}, false);*/
/*
* Error Reporting
*/
/*window.onerror = function (msg, url, lineNo, columnNo, error) {
var message = [
'Message: ' + msg,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
if(ga.errorTracking)
{
setTimeout(function() {
ga.exception(message.toString());
}, 0);
}
return false;
};*/
},{}],15:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@ -6857,7 +7035,7 @@ var LogEventHandlers = /** @class */ (function () {
_this.channels.push(channel);
}
catch (error) {
console.log('[BitAnalytics] ' + error.name + ': ' + error.message);
console.log(error.message);
}
});
};
@ -6865,7 +7043,7 @@ var LogEventHandlers = /** @class */ (function () {
}());
exports.default = LogEventHandlers;
},{"./channel-factory":7}],15:[function(require,module,exports){
},{"./channel-factory":7}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LogEvent = /** @class */ (function () {

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Catalan\n"
"Language: ca\n"
"PO-Revision-Date: 2018-07-04 09:26\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Compra &amp; ven bitcoins"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Compra bitcoins"
@ -619,10 +620,14 @@ msgstr "S'està connectant a Glidera..."
msgid "Connection reset by peer"
msgstr "Connexió reiniciada per un parell"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contactes"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Adreces utilitzades freqüentment desades"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Continua"
@ -823,7 +828,7 @@ msgstr "Crea una cartera compartida"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Crea una cartera bitcoin"
@ -2533,6 +2538,14 @@ msgstr "Cerca transaccions"
msgid "Search or enter bitcoin address"
msgstr "Cerca o introdueix l'adreça bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Porta-retalls"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Teniu el porta-retalls buit"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Cerca transaccions"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Envia per correu electrònic"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Envia des de"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Enviat a"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Enganxa des del porta-retalls"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Enganxa l'adreça"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transferència de cartera a cartera"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Escaneja el codi QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envia bitcoins més ràpid!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envia bitcoins més ràpid!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Deseu adreces utilitzades freqüentment i envieu-los bitcoins d'un sol toc"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Afegiu el primer contacte"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "La vostra cartera bitcoin és buida"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Per començar, compreu Bitcoin Cash (BCH) o Bitcoin Core (BTC), o compartiu la vostra adreça."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Podeu rebre bitcoins des de qualsevol cartera o servei."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per començar, heu de crear una cartera bitcoin i obtenir uns quants bitcoins."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Compra Bitcoins ara"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Mostra la meva adreça"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Envia import màxim"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transaccions descarregades"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-de-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Comunitat"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Reddit de Bitcoin Cash"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Twitter de Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Explora Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Jocs de Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Notícies"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Xarxa minera"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Eines"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Gràfiques de preus del bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash gratis"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Les vostres carteres bitcoin ja estan a punt!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Czech\n"
"Language: cs\n"
"PO-Revision-Date: 2018-07-04 09:26\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Koupit &amp; prodat Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Koupit Bitcoin"
@ -619,10 +620,14 @@ msgstr "Připojování ke Glidera..."
msgid "Connection reset by peer"
msgstr "Připojení přerušeno druhou stranou"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Kontakty"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Uložené, často používané adresy"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Pokračovat"
@ -823,7 +828,7 @@ msgstr "Vytvořit sdílenou peněženku"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Vytvořit Bitcoin peněženku"
@ -2533,6 +2538,14 @@ msgstr "Vyhledávání transakcí"
msgid "Search or enter bitcoin address"
msgstr "Vyhledat nebo zadat Bitcoin adresu"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Schránka"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Vaše schránka je prázdná"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Vyhledávání transakcí"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Poslat e-mailem"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Odeslat z"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Odeslat"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Vložit ze schránky"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Vložit adresu"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Převod mezi peněženkami"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Skenovat QR kód"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Odesílejte Bitcoin rychleji!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Odesílejte Bitcoin rychleji!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Uložte si často používané adresy a posílejte jim Bitcoin jedním kliknutím"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Přidat váš první kontakt"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Vaše Bitcoin peněženka je prázdná"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Chcete-li začít, nakupte Bitcoin Cash (BCH) nebo Bitcoin Core (BTC), nebo sdílejte svou adresu."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Můžete přijímat Bitcoin z jakékoliv peněženky nebo služby."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Chcete-li začít, budete muset vytvořit Bitcoin peněženku a Bitcoin získat."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Koupit Bitcoin"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Zobrazit mou adresu"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Odeslat maximální částku"
@ -3030,7 +3104,7 @@ msgstr "Chcete-li začít, nakupte Bitcoin nebo sdílejte svou adresu. Můžete
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Chcete-li začít, budete muset vytvořit Bitcoin peněženku a Bitcoin získat."
msgstr "Chcete-li začít, budete potřebovat vytvořit Bitcoin peněženku a získat Bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transakcí staženo"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-z-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Komunita"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Prohlédnout Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash hry"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Novinky"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Těžební pool"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Nástroje"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Grafy cen Bitcoinu"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash zdarma"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Vaše Bitcoin peněženka je připravena!"

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Spanish\n"
"Language: es\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Comprar &amp; Vender Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Comprar Bitcoin"
@ -619,10 +620,14 @@ msgstr "Conectando a Glidera..."
msgid "Connection reset by peer"
msgstr "Conexión re establecida"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contactos"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Direcciones frecuentes guardadas"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Continuar"
@ -823,7 +828,7 @@ msgstr "Crear billetera compartida"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Crear billetera"
@ -2533,6 +2538,14 @@ msgstr "Buscar transacciones"
msgid "Search or enter bitcoin address"
msgstr "Buscar o introducir dirección bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Portapapeles"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Portapapeles vacío"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Buscar transacciones"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Enviar por correo electrónico"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Enviar desde"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Enviar a"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Pegar portapapeles"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Pegar dirección"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Billetera a billetera"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Escanear código QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "¡Envía Bitcoin más rápido!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "¡Envía Bitcoin más rápido!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Guardar las direcciones que usas frecuentemente y envía Bitcoin en un click"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Añadie tu primer contacto"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Tu billetera Bitcoin está vacía"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Para empezar, compra Bitcoin Cash (BCH) o Bitcoin Core (BTC), o comparte tu dirección."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Puedes recibir bitcoin desde cualquier billetera o servicio."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para empezar, necesitarás crear una billetera y obtener bitcoins."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Comprar Bitcoin ahora"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Ver mi dirección"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Enviar la máxima cantidad"
@ -3030,7 +3104,7 @@ msgstr "Para empezar, compra bitcoin o comparte tu dirección. Puedes recibir bi
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para empezar, necesitarás crear una billetera y obtener bitcoins."
msgstr "Para empezar, necesitarás crear una billetera y obtener Bitcoins."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transacciones descargadas"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-de-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift - Cambia BTC a BCH"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Comunidad"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Reddit de Bitcoin Cash"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Twitter de Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Explora Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Juegos de Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Noticias"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Minería en la nube"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Herramientas"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Gráfica de precios Bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash gratis"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "¡Tus billeteras Bitcoin están listas!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Persian\n"
"Language: fa\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "خرید &amp; فروش بیتکوین"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "خرید بیتکوین"
@ -619,10 +620,14 @@ msgstr "در حال اتصال به Glidera..."
msgid "Connection reset by peer"
msgstr "ریست اتصال توسط همکار"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "تماسها"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "آدرس های ذخیره شده که اغلب مورد استفاده قرار گرفته اند"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "ادامه"
@ -823,7 +828,7 @@ msgstr "ایجاد کیف پول مشترک"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "ایجاد کیف پول بیتکوین"
@ -2533,6 +2538,14 @@ msgstr "جستجوی تراکنش ها"
msgid "Search or enter bitcoin address"
msgstr "جستجو و یا وارد کردن آدرس بیتکوین"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "کلیپ بورد"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "کلیپ بورد شما خالی است"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "جستجوی تراکنش ها"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "ارسال توسط ایمیل"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "ارسال از"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "ارسال به"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "جای گذاری کلیپ برد"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "جای گذاری آدرس"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "انتقال پول از کیف پول به کیف پول"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "اسکن کد QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ارسال سریع تر بیت کوین!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ارسال سریع تر بیت کوین!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "ذخیره آدرس های اغلب استفاده شده و ارسال بیت کوین به آنها تنها با یک ضربه"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "اولین تماس خود اضافه کنید"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "کیف پول بیت کوین شما خالی است"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "برای شروع، Bitcoin Cash (BCH) یا Bitcoin Core (BTC) بخرید و یا آدرس خود را به اشتراک بگذارید."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "شما می توانید از هر کیف پول و یا خدمات بیت کوین دریافت کنید."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "برای شروع، شما نیاز دارید که یک کیف پول ایجاد کنید و مقداری بیتکوین تهیه کنید."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "خرید بیت کوین همین الان"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "نمایش آدرس من"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "ارسال حداکثر مقدار"
@ -3030,7 +3104,7 @@ msgstr "برای شروع، بیتکوین بخرید و یا آدرس خود ر
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "برای شروع، شما نیاز دارید که یک کیف پول ایجاد کنید و مقداری بیتکوین تهیه کنید."
msgstr "برای شروع، شما نیاز دارید که یک کیف پول بیت کوین ایجاد کرده و مقداری بیت کوین تهیه کنید."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} تراکنش دانلود شد"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}} از {{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "جامعه"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "توییتر Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "کاوش Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash Games"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "اخبار"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "استخر استخراج"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "ابزارها"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "نمودارهای قیمت بیت کوین"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "رایگان Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "کیف پول بیت کوین شما آماده است!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: French\n"
"Language: fr\n"
"PO-Revision-Date: 2018-07-04 09:26\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,7 @@ msgstr "Numéro de compte"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr "Transactions instantanées à bas frais"
msgstr "Instant transactions with low fees"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Acheter &amp; vendre des bitcoins"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Acheter des bitcoins"
@ -619,10 +620,14 @@ msgstr "Connexion à Glidera..."
msgid "Connection reset by peer"
msgstr "Connexion réinitialisée par un pair"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contacts"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Adresses fréquemment utilisées enregistrées"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Continuer"
@ -823,7 +828,7 @@ msgstr "Créer un portefeuille partagé"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Créer un portefeuille bitcoin"
@ -993,7 +998,7 @@ msgstr "Autoriser les notifications"
#: www/views/preferencesNotifications.html:33
msgid "Enable sound"
msgstr "Activer le son"
msgstr "Malayu"
#: www/views/tab-scan.html:18
msgid "Enable the camera to get started."
@ -2533,6 +2538,14 @@ msgstr "Rechercher des transactions"
msgid "Search or enter bitcoin address"
msgstr "Recherchez ou saisissez une adresse bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Presse-papiers"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Votre presse-papiers est vide"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Rechercher des transactions"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Envoyer par e-mail"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Envoyer à partir de"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Envoyer à"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Coller le contenu du presse-papiers"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Coller l'adresse"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transfert de portefeuille à portefeuille"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Numérisez le code QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envoyez des Bitcoin plus vite !"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envoyez des Bitcoin plus vite !"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Enregistrez les adresses fréquemment utilisées et envoyez-leurs des Bitcoins en un seul geste"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Ajoutez votre premier contact"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Votre portefeuille Bitcoin est vide"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Pour commencer, achetez des Bitcoins Cash (BCH) ou des Bitcoins Core (BTC), ou partagez votre adresse."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Vous pouvez recevoir des Bitcoins de n'importe quel portefeuille ou service."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Pour commencer, vous aurez besoin de créer un portefeuille bitcoin et d'obtenir quelques bitcoins."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Acheter des Bitcoins maintenant"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Afficher mon adresse"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Envoyer le montant maximal"
@ -3030,7 +3104,7 @@ msgstr "Pour commencer, achetez des bitcoins ou partagez votre adresse. Vous pou
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Pour commencer, vous aurez besoin de créer un portefeuille bitcoin et d'obtenir quelques bitcoins."
msgstr "Pour commencer, vous aurez besoin de créer un portefeuille Bitcoin et d'obtenir quelques bitcoins."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transactions téléchargées"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-sur-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Communauté"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Reddit Bitcoin Cash"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Twitter Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Explorez Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Jeux Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Nouvelles"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Coopératives de mineurs"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Outils"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Graphiques du prix du Bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash Gratuit"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Vos portefeuilles bitcoin sont prêts !"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Italian\n"
"Language: it\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Comprare &amp; Vendere Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Acquista Bitcoin"
@ -619,10 +620,14 @@ msgstr "Connessione a Glidera..."
msgid "Connection reset by peer"
msgstr "Connessione ripristinata dall'utente"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contatti"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Indirizzi più utilizzati salvati"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Continua"
@ -823,7 +828,7 @@ msgstr "Creare portafoglio condiviso"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Creare portafoglio bitcoin"
@ -2533,6 +2538,14 @@ msgstr "Cerca Transazioni"
msgid "Search or enter bitcoin address"
msgstr "Cerca o inserisci indirizzo bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Appunti"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Gli appunti sono vuoti"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Ricerca transazioni"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Invia via email"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Inviata Da"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Invia a"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Incolla appunti"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Incolla indirizzo"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Trasferimento da portafoglio a portafoglio"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Scansiona codice QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Invia Bitcoin più velocemente!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Invia Bitcoin più velocemente!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Salva gli indirizzi più utilizzati e invia Bitcoin con un solo tocco"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Aggiungi il tuo primo contatto"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Il tuo portafoglio Bitcoin è vuoto"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Per iniziare, acquista Bitcoin Cash (BCH) o Bitcoin Core (BTC), oppure condividi il tuo indirizzo."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Puoi ricevere Bitcoin da qualsiasi portafoglio o servizio."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per iniziare, è necessario che tu crei un portafoglio bitcoin e ottenerne qualcuno."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Acquista subito Bitcoin"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Visualizza il mio indirizzo"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Inviare l'importo massimo"
@ -3030,7 +3104,7 @@ msgstr "Per iniziare, acquista bitcoin o condividi il tuo indirizzo. È possibil
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per iniziare, è necessario che tu crei un portafoglio bitcoin e ottenerne qualcuno."
msgstr "Per iniziare, devi creare un portafoglio bitcoin e ottenere qualche bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transazioni scaricate"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-di-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Community"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash su Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com su Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Esplora Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Giochi Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "News"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Mining Pool"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Strumenti"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Tabella prezzi Bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash gratis"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "I tuoi portafogli Bitcoin sono pronti!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Japanese\n"
"Language: ja\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -406,7 +406,7 @@ msgstr "ビットコインは世界で<br>最も安全な仮想通貨。"
#: www/views/preferencesFee.html:11
msgid "Bitcoin transactions include a fee collected by miners on the network."
msgstr "ビットコインの取引はネットワークの安全を守る「採掘者」と呼ばれる達に送る手数料が含まれます。"
msgstr "ビットコインの取引はネットワークの安全を守る「採掘者」と呼ばれる達に送る手数料が含まれます。"
#: www/views/buyAmazon.html:108
msgid "Bought {{amountUnitStr}}"
@ -439,6 +439,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "ビットコインの購入&amp;売却"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "ビットコインを購入"
@ -621,10 +622,14 @@ msgstr "Glidera に接続中…"
msgid "Connection reset by peer"
msgstr "接続がピアによってリセットされました"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "連絡先"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "よく使う保存済みのアドレス"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "続ける"
@ -825,7 +830,7 @@ msgstr "共有ウォレットを作成"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "ビットコインウォレット作成"
@ -995,7 +1000,7 @@ msgstr "プッシュ通知を有効化"
#: www/views/preferencesNotifications.html:33
msgid "Enable sound"
msgstr "を有効にする"
msgstr "サウンドを有効にする"
#: www/views/tab-scan.html:18
msgid "Enable the camera to get started."
@ -1348,7 +1353,7 @@ msgstr "始めよう"
#: www/views/addressbook.html:20
msgid "Get started by adding your first one."
msgstr "初めての連絡先を追加しましょう。"
msgstr "連絡先を追加しましょう。"
#: src/js/services/onGoingProcess.js:23
msgid "Getting fee levels..."
@ -1873,7 +1878,7 @@ msgstr "バックアップは非常に重要です!"
#: www/views/addressbook.html:19
msgid "No contacts yet"
msgstr "連絡先が無い"
msgstr "連絡先はありません"
#: www/views/preferencesLogs.html:16
msgid "No entries for this log level"
@ -2006,7 +2011,7 @@ msgstr "今一度周りの環境をよく見てみましょう。隠しカメラ
#: src/js/services/popupService.js:72
#: www/views/modals/chooseFeeLevel.html:6
msgid "OK"
msgstr "わかりました"
msgstr "OK"
#: www/views/modals/tx-status.html:12
#: www/views/modals/tx-status.html:24
@ -2535,6 +2540,14 @@ msgstr "取引を検索"
msgid "Search or enter bitcoin address"
msgstr "連絡先検索かビットコインアドレスを指定"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "クリップボード"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "クリップボードは空です"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "取引を検索"
@ -2593,9 +2606,70 @@ msgid "Send by email"
msgstr "メールで送信"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "ここから送金"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "送金先:"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "クリップボードからペースト"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "アドレスをペースト"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "ウォレット間送金"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "QRコードを読み取る"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ビットコイン送金をより高速に!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ビットコイン送金をより高速に!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "よく使うアドレスを保存すればワンタップでビットコインを送金できます"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "最初の連絡先を追加"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "ビットコインウォレットが空です"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "始めるには、Bitcoin Cash (BCH) または Bitcoin Core (BTC) を購入するか、あなたのアドレスを共有してください。"
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "どのウォレットやサービスからでもビットコインを受け取ることができます。"
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "はじめに、ビットコインウォレットを作成し、ビットコインを入手する必要があります。"
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "今すぐビットコインを購入"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "自分のアドレスを表示"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "全残高を送金"
@ -3450,7 +3524,7 @@ msgstr "送金発生時のメール通知はどのメールアドレスで受け
#: www/views/addresses.html:19
msgid "Why?"
msgstr "なぜ?"
msgstr "なぜですか"
#: www/views/feedback/rateApp.html:10
msgid "Would you be willing to rate {{appName}} in the app store?"
@ -3642,3 +3716,51 @@ msgstr "{{updatingTxHistoryProgress}} 個の取引ダウンロード済み"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}} の{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "コミュニティ"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Bitcoin.com を参照"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash ゲーム"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "ニュース"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "マイニングプール"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "ツール"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "ビットコインの価格チャート"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "無料 Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "ビットコインウォレットが完成しました!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Korean\n"
"Language: ko\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "비트코인 구매 &amp; 판매"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "비트코인 구매"
@ -619,10 +620,14 @@ msgstr "Glidera에 연결 중..."
msgid "Connection reset by peer"
msgstr "연결 실패"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "연락처"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "자주 사용하는 저장된 주소"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "계속하기"
@ -823,7 +828,7 @@ msgstr "공유 지갑 만들기"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "비트코인 지갑 만들기"
@ -2533,6 +2538,14 @@ msgstr "거래 기록 검색하기"
msgid "Search or enter bitcoin address"
msgstr "비트코인 주소를 찾거나 작성"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "클립보드"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "클립보드가 비어 있습니다"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "거래 기록 검색"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "이메일로 보내기"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "출처"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "보내기"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "클립보드 붙여넣기"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "주소 붙여넣기"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "지갑 간 전송"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "QR 코드 스캔"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "비트코인 속성 전송!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "비트코인 속성 전송!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "자주 사용하는 주소를 저장하고 한 번의 탭으로 저장된 주소에 비트코인 전송"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "첫 번째 연락처 추가"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "비트코인 지갑이 비어 있습니다"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "시작하려면 비트코인 캐시(BCH) 또는 비트코인 코어(BTC)를 구매하거나 주소를 공유합니다."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "지갑 또는 서비스에서 비트코인을 받을 수 있습니다."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "시작하시기 위해선 비트코인 지갑을 생성하시거나 비트코인을 구매하세요."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "지금 비트코인 구매"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "내 주소 보기"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "최대 수량 보내기"
@ -3030,7 +3104,7 @@ msgstr "시작하시려면 비트코인을 구매하시거나 주소를 등록
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "시작하시기 위해선 비트코인 지갑을 생성하시거나 비트코인을 구매하세요."
msgstr "시작하려면 비트코인 지갑을 만들고 비트코인을 구매하십시오."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} 거래 내역 다운로드 완료"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.n}}의 {{wallet.m}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "커뮤니티"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "BCH Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com 트위터"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Bitcoin.com 탐색"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "BCH 게임"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "소식"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "채굴 풀"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "도구"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "비트코인 가격 차트"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "무료 BCH"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "비트코인 지갑이 완료되었습니다!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Dutch\n"
"Language: nl\n"
"PO-Revision-Date: 2018-07-04 09:26\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Koop &amp; Verkoop Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Bitcoin kopen"
@ -619,10 +620,14 @@ msgstr "Verbinding maken met Glidera..."
msgid "Connection reset by peer"
msgstr "Verbinding is gereset door peer"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contactpersonen"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Opgeslagen veelgebruikte adressen"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Ga verder"
@ -823,7 +828,7 @@ msgstr "Gedeelde Portemonnee Aanmaken"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Bitcoin portemonnee aanmaken"
@ -2533,6 +2538,14 @@ msgstr "Doorzoek Transacties"
msgid "Search or enter bitcoin address"
msgstr "Zoeken of bitcoin adres invullen"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Klembord"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Uw klembord is leeg"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Doorzoek transacties"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Verstuur via email"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Verzenden vanuit"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Verzenden naar"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Klembord plakken"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Adres plakken"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Portemonnee overdracht"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Scan QR-code"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Stuur Bitcoin sneller!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Stuur Bitcoin sneller!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Sla veelgebruikte adressen op en verstuur ze Bitcoin met een druk op de knop"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Uw eerste contact toevoegen"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Uw Bitcoin portemonnee is leeg"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Om aan de slag te gaan, koop Bitcoin Cash (BCH) of Bitcoin Core (BTC), of deel uw adres."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "U kunt Bitcoin ontvangen van elke portemonnee of dienst."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Om aan de slag te gaan zult u een bitcoin portemonnee moeten aanmaken en wat bitcoin moeten verkrijgen."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Bitcoin kopen"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Toon mijn adres"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Verzend maximale hoeveelheid"
@ -3030,7 +3104,7 @@ msgstr "Om aan de slag te gaan, koop bitcoin of deel uw adres. U kunt bitcoin on
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Om aan de slag te gaan zult u een bitcoin portemonnee moeten aanmaken en wat bitcoin moeten verkrijgen."
msgstr "Om aan de slag te gaan, zult u een Bitcoin-portemonnee aan moeten maken en wat Bitcoin moeten verkrijgen."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transacties gedownload"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-van-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Community"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Bitcoin.com verkennen"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash spellen"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Nieuws"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Mining Pool"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Hulpmiddelen"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Bitcoin prijs grafieken"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Gratis Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Uw bitcoin portemonnee is gereed!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Polish\n"
"Language: pl\n"
"PO-Revision-Date: 2018-07-04 03:58\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,7 @@ msgstr "Numer konta"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr ""
msgstr "Natychmiastowe transakcje z niskimi prowizjami"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -363,12 +363,12 @@ msgstr "Adres bitcoin"
#: www/views/cashScan.html:4
msgid "Bitcoin Cash (BCH) Balances"
msgstr ""
msgstr "Salda Bitcoin Cash (BCH)"
#: www/views/preferencesCash.html:3
#: www/views/tab-settings.html:47
msgid "Bitcoin Cash Support"
msgstr ""
msgstr "Wsparcie Bitcoin Cash"
#: www/views/tab-home.html:98
#: www/views/tab-settings.html:115
@ -384,7 +384,7 @@ msgstr "Polityka prowizji sieci bitcoin"
#: www/views/tab-home.html:83
#: www/views/tab-settings.html:107
msgid "Bitcoin Core Wallets"
msgstr ""
msgstr "Portfele Bitcoin Core"
#: src/js/services/incomingData.js:151
msgid "Bitcoin cash Payment"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Kup &amp; sprzedaj bitcoiny"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Kup bitcoiny"
@ -619,10 +620,14 @@ msgstr "Łączenie z Gildera..."
msgid "Connection reset by peer"
msgstr "Połączenie zostało zresetowane"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Kontakty"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Zapisane często używane adresy"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Dalej"
@ -823,7 +828,7 @@ msgstr "Utwórz współdzielony portfel"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Utwórz portfel bitcoin"
@ -977,7 +982,7 @@ msgstr "Puste adresy osiągnęły limit. Nowe adresy nie mogą być generowane."
#: www/views/preferencesCash.html:17
msgid "Enable Bitcoin Cash wallet creation and operation within the App."
msgstr ""
msgstr "Włącz tworzenie i obsługę portfela Bitcoin Cash w aplikacji."
#: www/views/tab-scan.html:19
msgid "Enable camera access in your device settings to get started."
@ -993,7 +998,7 @@ msgstr "Włącz powiadomienia"
#: www/views/preferencesNotifications.html:33
msgid "Enable sound"
msgstr ""
msgstr "Włącz dźwięk"
#: www/views/tab-scan.html:18
msgid "Enable the camera to get started."
@ -1001,7 +1006,7 @@ msgstr "Włącz kamerę aby rozpocząć."
#: www/views/tab-settings.html:49
msgid "Enabled"
msgstr ""
msgstr "Włączono"
#: src/js/services/walletService.js:1047
#: src/js/services/walletService.js:1062
@ -1586,7 +1591,7 @@ msgstr "Nieprawidłowy adres"
#: src/js/controllers/confirm.js:306
#: src/js/services/bwcError.js:44
msgid "Insufficient confirmed funds"
msgstr ""
msgstr "Niewystarczające potwierdzone środki"
#: src/js/controllers/topup.js:165
#: src/js/controllers/topup.js:177
@ -1931,7 +1936,7 @@ msgstr "Nie BIP44 portfel"
#: www/views/cashScan.html:46
msgid "Non eligible BTC wallets"
msgstr ""
msgstr "Niewspierane portfele BTC"
#: src/js/services/feeService.js:12
msgid "Normal"
@ -2004,7 +2009,7 @@ msgstr "Nadszedł czas, aby sprawdzić swoje otoczenie. Czy jesteś w pobliżu o
#: src/js/services/popupService.js:72
#: www/views/modals/chooseFeeLevel.html:6
msgid "OK"
msgstr ""
msgstr "OK"
#: www/views/modals/tx-status.html:12
#: www/views/modals/tx-status.html:24
@ -2023,7 +2028,7 @@ msgstr "O nie!"
#: src/js/controllers/buyMercadoLibre.js:306
msgid "Ok"
msgstr ""
msgstr "Ok"
#: www/views/tab-home.html:39
msgid "On this screen you can see all your wallets, accounts, and assets."
@ -2053,7 +2058,7 @@ msgstr "Otwórz projekt GitHub"
#: src/js/controllers/bitpayCard.js:123
#: src/js/controllers/tx-details.js:192
msgid "Open Explorer"
msgstr ""
msgstr "Otwórz Explorer"
#: www/views/tab-scan.html:22
msgid "Open Settings"
@ -2069,7 +2074,7 @@ msgstr "Otwórz stronę internetową"
#: src/js/controllers/preferencesCash.js:32
msgid "Open bitcoincash.org?"
msgstr ""
msgstr "Otworzyć bitcoincash.org?"
#: src/js/controllers/cashScan.js:18
msgid "Open the recovery tool."
@ -2240,7 +2245,7 @@ msgstr "Proszę wybrać plik kopii zapasowej"
#: www/views/bitpayCard.html:81
msgid "Pre-Auth Holds"
msgstr ""
msgstr "Wstrzymanie przedautoryzacyjne"
#: www/views/tab-settings.html:40
msgid "Preferences"
@ -2353,7 +2358,7 @@ msgstr "Otrzymaj"
#: www/views/customAmount.html:44
msgid "Receive in"
msgstr ""
msgstr "Otrzymaj w"
#: www/views/includes/walletHistory.html:24
#: www/views/tx-details.html:18
@ -2511,7 +2516,7 @@ msgstr "Proszę zeskanować linie papilarne"
#: www/views/preferencesCash.html:23
msgid "Scan your wallets for Bitcoin Cash"
msgstr ""
msgstr "Skanuj portfele w poszukiwaniu Bitcoin Cash"
#: src/js/services/onGoingProcess.js:30
msgid "Scanning Wallet funds..."
@ -2533,6 +2538,14 @@ msgstr "Szukaj transakcji"
msgid "Search or enter bitcoin address"
msgstr "Wyszukaj lub wpisz adres bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Schowek"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Schowek jest pusty"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Szukaj transakcji"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Wyślij przez e-mail"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Wyślij z"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Wyślij do"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Wklej ze schowka"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Wklej adres"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transfer z portfela do portfela"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Zeskanuj kod QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Przesyłaj Bitcoiny szybciej!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Przesyłaj Bitcoiny szybciej!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Zapisz często używane adresy i wyślij im Bitcoin za pomocą jednego dotknięcia"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Dodaj swój pierwszy kontakt"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Twój portfel jest pusty"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Aby zacząć, kup Bitcoin Cash (BCH) lub Bitcoin Core (BTC), albo udostępnij swój adres."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Bitcoiny można odbierać z dowolnego portfela lub usługi."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Aby rozpocząć należy utworzyć portfel i dostać trochę bitcoinów."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Kup Bitcoin teraz"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Pokaż mój adres"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Wyślij całą kwotę"
@ -2764,7 +2838,7 @@ msgstr "Przesuń, aby wysłać"
#: www/views/cashScan.html:56
msgid "Some of your wallets are not eligible for Bitcoin Cash support. You can try to access BCH funds from these wallets using the"
msgstr ""
msgstr "Niektóre z twoich portfeli nie kwalifikują się do wsparcia Bitcoin Cash. Dostęp do środków BCH z tych portfeli można spróbować uzyskać, korzystając z"
#: src/js/controllers/create.js:88
#: src/js/controllers/join.js:71
@ -2785,7 +2859,7 @@ msgstr "Wymagane hasło wypłat"
#: www/views/walletDetails.html:173
msgid "Spending this balance will need significant Bitcoin network fees"
msgstr ""
msgstr "Wydanie tego salda będzie wymagało znacznych opłat sieciowych Bitcoin"
#: www/views/tab-send.html:28
msgid "Start sending bitcoin"
@ -2810,7 +2884,7 @@ msgstr "Super Ekonomiczna"
#: www/views/preferencesCash.html:11
msgid "Support Bitcoin Cash"
msgstr ""
msgstr "Wsparcie Bitcoin Cash"
#: www/views/paperWallet.html:7
msgid "Sweep"
@ -2860,7 +2934,7 @@ msgstr "Warunki użytkowania"
#: www/views/tab-create-personal.html:118
#: www/views/tab-import-phrase.html:68
msgid "Testnet"
msgstr ""
msgstr "Testnet"
#: www/views/includes/incomingDataMenu.html:61
msgid "Text"
@ -2999,7 +3073,7 @@ msgstr "Ta kluczowa fraza został utworzona przy użyciu hasła. Aby odzyskać p
#: www/views/tx-details.html:91
msgid "This transaction amount is too small compared to current Bitcoin network fees. Spending these funds will need a Bitcoin network fee cost comparable to the funds itself."
msgstr ""
msgstr "Ta kwota transakcji jest zbyt mała w porównaniu z obecnymi opłatami sieci Bitcoin. Wydanie tych środków będzie wymagało opłaty sieciowej Bitcoin, która jest porównywalna do kosztów samych funduszy."
#: www/views/tx-details.html:87
msgid "This transaction could take a long time to confirm or could be dropped due to the low fees set by the sender"
@ -3034,15 +3108,15 @@ msgstr "Aby rozpocząć należy utworzyć portfel i dostać trochę bitcoinów."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr ""
msgstr "Aby móc wykonać czynność {{reason}}, musisz przedtem dodać swoje konto BitPay {{email}}"
#: src/js/services/onGoingProcess.js:48
msgid "Top up in progress..."
msgstr ""
msgstr "Doładowanie w trakcie..."
#: src/js/controllers/topup.js:206
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr ""
msgstr "Doładuj o {{amountStr}} kartę debetową ({{cardLastNumber}})"
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
@ -3061,7 +3135,7 @@ msgstr "Liczba współwłaścicieli portfela"
#: www/views/addresses.html:81
msgid "Total wallet inputs"
msgstr ""
msgstr "Dane wejściowe portfela łącznie"
#: src/js/services/fingerprintService.js:63
#: src/js/services/fingerprintService.js:68
@ -3200,7 +3274,7 @@ msgstr "Zobacz zasady użytkowania"
#: src/js/controllers/bitpayCard.js:122
#: src/js/controllers/tx-details.js:191
msgid "View Transaction on Explorer.Bitcoin.com"
msgstr ""
msgstr "Zobacz transakcję na Explorer.Bitcoin.com"
#: src/js/controllers/tab-home.js:148
msgid "View Update"
@ -3212,7 +3286,7 @@ msgstr "Zobacz na blockchainie"
#: www/views/mercadoLibre.html:26
msgid "Visit mercadolivre.com.br &rarr;"
msgstr ""
msgstr "Odwiedź mercadolivre.com.br &rarr;"
#: www/views/walletDetails.html:182
msgid "WARNING: Key derivation is not working on this device/wallet. Actions cannot be performed on this wallet."
@ -3274,7 +3348,7 @@ msgstr "Informacje o portfelu"
#: www/views/addresses.html:76
msgid "Wallet Inputs"
msgstr ""
msgstr "Dane wejściowe portfela"
#: www/views/join.html:26
msgid "Wallet Invitation"
@ -3328,7 +3402,7 @@ msgstr "Portfel już istnieje"
#: src/js/services/profileService.js:516
msgid "Wallet already in {{appName}}"
msgstr ""
msgstr "Portfel już w aplikacji {{appName}}"
#: www/views/includes/walletActivity.html:6
msgid "Wallet created"
@ -3508,7 +3582,7 @@ msgstr "Nie należy ustawiać opłatę wyższą niż {{maxFeeRecommended}} satos
#: www/views/modals/bitpay-card-confirmation.html:5
msgid "You will need to log back for fill in your BitPay Card."
msgstr ""
msgstr "Musisz zalogować się ponownie, aby wypełnić swoją kartę BitPay."
#: www/views/preferencesNotifications.html:34
msgid "You'll receive email notifications about payments sent and received from your wallets."
@ -3580,7 +3654,7 @@ msgstr "[Balans ukryty]"
#: www/views/walletDetails.html:141
#: www/views/walletDetails.html:61
msgid "[Scanning Funds]"
msgstr ""
msgstr "[Skanowanie środków]"
#: src/js/controllers/bitpayCardIntro.js:11
msgid "add your BitPay Visa card(s)"
@ -3612,7 +3686,7 @@ msgstr "{{amountStr}} dla karty upominkowej Amazon.com"
#: src/js/controllers/buyMercadoLibre.js:237
msgid "{{amountStr}} for Mercado Livre Brazil Gift Card"
msgstr ""
msgstr "{{amountStr}} na karcie podarunkowej Mercado Livre Brazil"
#: www/views/preferencesBwsUrl.html:21
msgid "{{appName}} depends on Bitcore Wallet Service (BWS) for blockchain information, networking and Copayer synchronization. The default configuration points to https://bws.bitpay.com (BitPay's public BWS instance)."
@ -3624,7 +3698,7 @@ msgstr "{{fee}} zostanie potrącone jako prowizja sieci bitcoin."
#: www/views/confirm.html:85
msgid "{{tx.txp[wallet.id].feeRatePerStr}} of the sending amount"
msgstr ""
msgstr "{{tx.txp[wallet.id].feeRatePerStr}} wysyłanej kwoty"
#: www/views/walletDetails.html:218
msgid "{{updatingTxHistoryProgress}} transactions downloaded"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} transakcje pobrane"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-z-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Społeczność"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Reddit Bitcoin Cash"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Twitter Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Poznaj Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Gry Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Aktualności"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Pula kopalni"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Narzędzia"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Wykresy kursu Bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Darmowa Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Twoje portfele Bitcoin są gotowe!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Portuguese, Brazilian\n"
"Language: pt\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Comprar &amp; Vender Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Comprar Bitcoin"
@ -619,10 +620,14 @@ msgstr "A conectar ao Glidera..."
msgid "Connection reset by peer"
msgstr "Ligação redefinida pelo mesmo nível"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Contactos"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Salvou os endereços usados com frequência"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Continuar"
@ -823,7 +828,7 @@ msgstr "Criar carteira partilhada"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Criar carteira bitcoin"
@ -2533,6 +2538,14 @@ msgstr "Procurar transações"
msgid "Search or enter bitcoin address"
msgstr "Procure ou digite o endereço bitcoin"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Área de transferência"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "A sua área de transferência está vazia"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Procurar transações"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Enviar por E-mail"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Enviar De"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Enviar para"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Colar na área de trabalho"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Colar endereço"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transferência de carteira para carteira"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Digitalizar o código QR"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envie Bitcoin mais rápido!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envie Bitcoin mais rápido!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Salvar endereços usados com frequência e enviar Bitcoin com apenas um toque"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Adicionar o seu primeiro contato"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Sua carteira de Bitcoin está vazia"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Para começar, compre Bitcoin Cash (BCH) ou Bitcoin Core (BTC) ou compartilhe o seu endereço."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Você pode receber bitcoin de qualquer carteira ou serviço."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para começar, você precisa criar uma carteira de bitcoins e obter alguns bitcoins."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Compre Bitcoin agora"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Mostrar meu endereço"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Quantidade Máxima de envio"
@ -3030,7 +3104,7 @@ msgstr "Para começar, compre bitcoins ou compartilhe seu endereço. Você pode
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para começar, você precisa criar uma carteira de bitcoins e obter alguns bitcoins."
msgstr "Para começar, você precisará criar uma carteira e obter algum bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3636,3 +3710,51 @@ msgstr "Transações de {{updatingTxHistoryProgress}} transferidas"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-de-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Comunidade"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Twitter Bitcoin.com"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Explore Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Jogos Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Notícias"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Pool de mineração"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Ferramentas"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Gráficos de preço do Bitcoin"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash grátis"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "As suas carteiras de Bitcoin estão prontas!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Russian\n"
"Language: ru\n"
"PO-Revision-Date: 2018-07-04 09:27\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,7 @@ msgstr "Номер учётной записи"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr "Мгновенные транзакции с низкой оплатой"
msgstr "Мгновенные транзакции с низкой комиссией"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "Купить &amp; продать биткойн"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "Купить биткойн"
@ -619,10 +620,14 @@ msgstr "Подключение к Glidera..."
msgid "Connection reset by peer"
msgstr "Соединение сброшено другой стороной"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "Контакты"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Сохраненные часто используемые адреса"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "Продолжить"
@ -823,7 +828,7 @@ msgstr "Создать общий кошелёк"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "Создать биткойн-кошелёк"
@ -2533,6 +2538,14 @@ msgstr "Поиск транзакций"
msgid "Search or enter bitcoin address"
msgstr "Найти или ввести биткойн-адрес"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "Буфер обмена"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Буфер обмена пуст"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "Поиск транзакций"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "Отправить на email"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "Отправить от"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "Получатель"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "Вставить из буфера обмена"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "Вставить адрес"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Перевод с кошелька на кошелек"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "Сканировать QR код"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Отправляйте биткойны еще быстрее!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Отправляйте биткойны еще быстрее!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Сохраняйте часто используемые адреса кошельков и отправляйте на них биткойны одним нажатием"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Добавить первый контакт"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Ваш кошелёк пуст"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "Чтобы начать работу, купите Bitcoin Cash (BCH) или Bitcoin Core (BTC), или поделитесь вашим адресом."
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "Вы можете получать биткойны с любого кошелька или сервиса."
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Чтобы начать работу, вам нужно создать кошелёк и получить биткойн."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Купить биткойны сейчас"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "Показать мой адрес"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "Отправить макс. сумму"
@ -3636,3 +3710,51 @@ msgstr "{{updatingTxHistoryProgress}} транзакций загружено"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}-из-{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Сообщество"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "Обзор Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Игры Bitcoin Cash"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Новости"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "Пул для майнинга"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "Инструменты"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "Динамика курса биткойна"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "Bitcoin Cash бесплатно"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Ваши кошельки готовы!"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Swedish\n"
"Language: sv\n"
"PO-Revision-Date: 2018-07-04 03:58\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr ""
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
@ -619,10 +620,14 @@ msgstr ""
msgid "Connection reset by peer"
msgstr ""
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr ""
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr ""
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr ""
@ -823,7 +828,7 @@ msgstr ""
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr ""
@ -2533,6 +2538,14 @@ msgstr ""
msgid "Search or enter bitcoin address"
msgstr ""
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr ""
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr ""
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr ""
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr ""
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr ""
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr ""
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr ""
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr ""
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr ""
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr ""
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr ""
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr ""
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr ""
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr ""
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr ""
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr ""
@ -3636,3 +3710,51 @@ msgstr ""
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr ""
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr ""
#: www/views/includes/community.html:3
msgid "Community"
msgstr ""
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr ""
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr ""
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr ""
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr ""
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr ""
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr ""
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr ""
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr ""

View file

@ -72,6 +72,26 @@ msgstr ""
msgid "Instant transactions with low fees"
msgstr ""
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr ""
#: www/views/amount.html:42
msgid "Change Currency"
msgstr ""
#: www/views/amount.html:49
msgid "Available Funds"
msgstr ""
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr ""
#: www/views/amount.html:99
msgid "Next"
msgstr ""
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr ""
@ -197,6 +217,20 @@ msgstr ""
msgid "Alternative Currency"
msgstr ""
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr ""
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr ""
@ -428,6 +462,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr ""
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
@ -652,6 +687,7 @@ msgstr ""
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr ""
@ -1271,6 +1307,7 @@ msgstr ""
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr ""
@ -1331,10 +1368,6 @@ msgid "Get news and updates from BitPay"
msgstr ""
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr ""
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr ""
@ -2158,6 +2191,10 @@ msgstr ""
msgid "Payment Sent"
msgstr ""
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr ""
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr ""
@ -2175,7 +2212,7 @@ msgid "Payment details"
msgstr ""
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr ""
#: www/views/mercadoLibreCards.html:22
@ -2611,7 +2648,7 @@ msgid "Paste Address"
msgstr ""
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgid "Transfer between wallets"
msgstr ""
#: www/views/tab-send.html:35
@ -2622,10 +2659,6 @@ msgstr ""
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr ""
@ -2647,6 +2680,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
@ -3051,6 +3086,14 @@ msgstr ""
msgid "This bitcoin payment request has expired."
msgstr ""
#: www/views/review.html:55
msgid "Payment expires:"
msgstr ""
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr ""
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3092,10 +3135,6 @@ msgstr ""
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr ""
@ -3108,6 +3147,26 @@ msgstr ""
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr ""
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr ""
#: www/views/shapeshift.html:30
msgid "he process is fast and you will receive the exchanged amount in your wallet."
msgstr ""
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr ""
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3700,16 +3759,68 @@ msgstr ""
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr ""
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr ""
#: www/views/includes/community.html:3
msgid "Community"
msgstr ""
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr ""
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr ""
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr ""
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr ""
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr ""
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr ""
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr ""
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr ""
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr ""
#: www/views/review.html:4
msgid "Review Transaction"
msgstr ""
#: www/views/review.html:14
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr ""
#: www/views/review.html:22
msgid "From:"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr ""
#: www/views/review.html:36
@ -3720,6 +3831,13 @@ msgstr ""
msgid "Add personal note"
msgstr ""
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr ""
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr ""
#: www/views/review.html:57
msgid "Personal note:"
@ -3727,4 +3845,8 @@ msgstr ""
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr ""
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr ""

View file

@ -11,11 +11,11 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Vietnamese\n"
"Language: vi\n"
"PO-Revision-Date: 2018-07-04 03:58\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
msgstr "(Đáng tin cậy)"
msgstr "(Tin cậy)"
#: www/views/includes/txp.html:23
#: www/views/includes/walletHistory.html:64
@ -28,7 +28,7 @@ msgstr "* A payment proposal can be deleted if 1) you are the creator, and no ot
#: www/views/tx-details.html:82
msgid "- {{btx.feeRateStr}} of the transaction"
msgstr "{{btx.feeRateStr}} của giao dịch"
msgstr "- {{btx.feeRateStr}} of the transaction"
#: www/views/modals/txp-details.html:102
msgid "- {{tx.feeRateStr}} of the transaction"
@ -41,7 +41,9 @@ msgstr "Xếp hạng 5 sao giúp chúng tôi để {{appName}} đến tay nhiề
#: www/views/mercadoLibre.html:18
#: www/views/mercadoLibre.html:40
msgid "<b>Only</b> redeemable on Mercado Livre (Brazil)"
msgstr "<b>Only</b> redeemable on Mercado Livre (Brazil)"
msgstr "<b>Only</b> redeemable on \n"
"Mercado Livre (Brazil) #\n\n"
"2"
#: src/js/controllers/feedback/send.js:27
#: www/views/feedback/complete.html:21
@ -54,7 +56,8 @@ msgstr "A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size all
#: src/js/controllers/confirm.js:395
msgid "A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided."
msgstr "A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided."
msgstr "Tổng cộng {{amountBelowFeeStr}} đã bị loại trừ. Số tiền này đến từ UTXOs nhỏ hơn chi phí mạng cung cấp.#\n"
"1"
#: src/js/controllers/preferencesAbout.js:6
#: www/views/tab-settings.html:156
@ -79,7 +82,7 @@ msgstr "Account Number"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr ""
msgstr "2"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -124,338 +127,339 @@ msgstr "Add account"
#: www/views/tab-create-personal.html:62
#: www/views/tab-create-shared.html:91
msgid "Add an optional password to secure the recovery phrase"
msgstr ""
msgstr "Add a password option to allow a secure cluster"
#: www/views/includes/incomingDataMenu.html:41
msgid "Add as a contact"
msgstr ""
msgstr "Thêm như một liên hệ"
#: src/js/controllers/confirm.js:424
msgid "Add description"
msgstr ""
msgstr "Thêm mô tả"
#: www/views/topup.html:6
msgid "Add funds"
msgstr ""
msgstr "Nạp tiền"
#: src/js/services/bitpayAccountService.js:78
msgid "Add this BitPay account ({{email}})?"
msgstr ""
msgstr "Thêm BitPay ({{email}}) tài khoản này?"
#: www/views/add.html:3
msgid "Add wallet"
msgstr ""
msgstr "Thêm ví"
#: www/views/addressbook.view.html:26
#: www/views/customAmount.html:28
#: www/views/modals/paypro.html:24
msgid "Address"
msgstr ""
msgstr "Địa chỉ"
#: www/views/addressbook.html:6
#: www/views/tab-settings.html:13
msgid "Address Book"
msgstr ""
msgstr "Sổ địa chỉ"
#: www/views/preferencesInformation.html:41
msgid "Address Type"
msgstr ""
msgstr "Loại địa chỉ"
#: www/views/addresses.html:64
msgid "Addresses With Balance"
msgstr ""
msgstr "Địa chỉ với số dư"
#: www/views/tab-settings.html:149
msgid "Advanced"
msgstr ""
msgstr "Nâng cao"
#: www/views/advancedSettings.html:3
msgid "Advanced Settings"
msgstr ""
msgstr "Cài đặt nâng cao"
#: www/views/bitpayCard.html:62
msgid "All"
msgstr ""
msgstr "Tất cả"
#: www/views/allAddresses.html:3
msgid "All Addresses"
msgstr ""
msgstr "Tất cả địa chỉ"
#: www/views/modals/wallet-balance.html:18
msgid "All of your bitcoin wallet balance may not be available for immediate spending."
msgstr ""
msgstr "Tất cả số dư ví bitcoin của bạn có thể không có sẵn cho chi tiêu ngay lập tức."
#: www/views/tab-receive.html:25
msgid "All signing devices must be added to this multisig wallet before bitcoin addresses can be created."
msgstr ""
msgstr "All contract device will be added to this multisig before the bitcoin address has been created."
#: www/views/tab-scan.html:21
msgid "Allow Camera Access"
msgstr ""
msgstr "Allow camera access"
#: www/views/onboarding/notifications.html:7
msgid "Allow notifications"
msgstr ""
msgstr "Allow notification"
#: www/views/onboarding/disclaimer.html:14
msgid "Almost done! Let's review."
msgstr ""
msgstr "Most as completed! We see review."
#: www/views/preferencesAltCurrency.html:4
#: www/views/tab-settings.html:79
msgid "Alternative Currency"
msgstr ""
msgstr "Money Currency instead"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr ""
msgstr "Amazon.com is not available at this time. Please try again again."
#: www/views/amount.html:44
#: www/views/customAmount.html:34
#: www/views/includes/output.html:7
msgid "Amount"
msgstr ""
msgstr "Quantity"
#: src/js/services/bwcError.js:110
msgid "Amount below minimum allowed"
msgstr ""
msgstr "Maximum amount of the minimum amount"
#: src/js/controllers/confirm.js:216
msgid "Amount too big"
msgstr ""
msgstr "Amount too large"
#: www/views/includes/walletHistory.html:31
msgid "Amount too low to spend"
msgstr ""
msgstr "Amount too low for standard"
#: src/js/controllers/tab-home.js:147
msgid "An update to this app is available. For your security, please update to the latest version."
msgstr ""
msgstr "Hotel have a Update for this application. To preserve your password, please please update the latest version."
#: www/views/backupWarning.html:14
msgid "Anyone with your backup phrase can access or spend your bitcoin."
msgstr ""
msgstr "Każdy, kto ma Twoją kluczową là một trong những điều tuyệt vời nhất."
#: www/views/addresses.html:94
msgid "Approximate Bitcoin network fee to transfer wallet's balance (with normal priority)"
msgstr ""
msgstr "La taxa approssimativa della rete Bitcoin cho mỗi lần gửi tiền theo yêu cầu của bạn"
#: www/views/backupWarning.html:10
msgid "Are you being watched?"
msgstr ""
msgstr "Chúng tôi vigilen?"
#: src/js/controllers/preferencesExternal.js:15
msgid "Are you being watched? Anyone with your recovery phrase can access or spend your bitcoin."
msgstr ""
msgstr "You are tracking? Bất cứ ai có thể phục hồi từ bạn, bạn có thể truy cập hoặc bitcoin chi tiêu của bạn."
#: src/js/controllers/copayers.js:56
msgid "Are you sure you want to cancel and delete this wallet?"
msgstr ""
msgstr "Are you sure you want to cancel and remove this video?"
#: src/js/controllers/addressbookView.js:37
msgid "Are you sure you want to delete this contact?"
msgstr ""
msgstr "Bạn có chắc chắn muốn xóa địa chỉ liên hệ này không?"
#: src/js/controllers/preferencesDelete.js:25
msgid "Are you sure you want to delete this wallet?"
msgstr ""
msgstr "Are you sure you want to delete this wallet?"
#: src/js/controllers/modals/txpDetails.js:154
msgid "Are you sure you want to reject this transaction?"
msgstr ""
msgstr "Are you sure you want to reject this transaction?"
#: src/js/controllers/modals/txpDetails.js:171
msgid "Are you sure you want to remove this transaction?"
msgstr ""
msgstr "Are you sure you want to remove this transaction?"
#: src/js/controllers/onboarding/backupRequest.js:23
msgid "Are you sure you want to skip it?"
msgstr ""
msgstr "Are you sure you want to skip it?"
#: www/views/modals/bitpay-card-confirmation.html:4
msgid "Are you sure you would like to log out of your BitPay Card account?"
msgstr ""
msgstr "Bạn có chắc chắn muốn đăng xuất khỏi tài khoản Thẻ BitPay của mình không?"
#: src/js/controllers/preferencesBitpayCard.js:7
#: src/js/controllers/preferencesBitpayServices.js:20
msgid "Are you sure you would like to remove your BitPay Card ({{lastFourDigits}}) from this device?"
msgstr ""
msgstr "Are you sure you would like to remove your BitPay Card ({{lastFourDigits}}) from this device?"
#: www/views/includes/walletInfo.html:10
msgid "Auditable"
msgstr ""
msgstr "Auditable"
#: www/views/modals/wallet-balance.html:42
msgid "Available"
msgstr ""
msgstr "Available"
#: www/views/includes/available-balance.html:3
msgid "Available Balance"
msgstr ""
msgstr "Available Balance"
#: www/views/modals/chooseFeeLevel.html:24
#: www/views/preferencesFee.html:15
msgid "Average confirmation time"
msgstr ""
msgstr "Average confirmation time"
#: www/views/join.html:143
#: www/views/tab-create-personal.html:113
#: www/views/tab-create-shared.html:142
#: www/views/tab-import-phrase.html:51
msgid "BIP32 path for address derivation"
msgstr ""
msgstr "Đường dẫn BIP32 cho dẫn xuất địa chỉ"
#: www/views/cashScan.html:25
msgid "BTC wallets"
msgstr ""
msgstr "Ví BTC"
#: www/views/preferences.html:34
msgid "Backup"
msgstr ""
msgstr "Backup"
#: www/views/includes/backupNeededPopup.html:7
msgid "Backup Needed"
msgstr ""
msgstr "Backup Needed"
#: src/js/controllers/lockSetup.js:87
msgid "Backup all livenet wallets before using this function"
msgstr ""
msgstr "Backup all livenet wallets before using this function"
#: src/js/controllers/cashScan.js:64
#: www/views/includes/walletListSettings.html:12
#: www/views/preferences.html:36
msgid "Backup needed"
msgstr ""
msgstr "Cần sao lưu"
#: www/views/includes/backupNeededPopup.html:9
msgid "Backup now"
msgstr ""
msgstr "Sao lưu ngay"
#: www/views/onboarding/backupRequest.html:11
#: www/views/tab-export-file.html:89
msgid "Backup wallet"
msgstr ""
msgstr "Backup wallet"
#: src/js/controllers/lockSetup.js:84
msgid "Backup your wallet before using this function"
msgstr ""
msgstr "Backup your wallet before using this function"
#: src/js/services/profileService.js:446
msgid "Bad wallet invitation"
msgstr ""
msgstr "Bad wallet invitation"
#: www/views/preferencesInformation.html:102
msgid "Balance By Address"
msgstr ""
msgstr "Balance By Address"
#: www/views/includes/confirmBackupPopup.html:7
msgid "Be sure to store your recovery phrase in a secure place. If this app is deleted, your money cannot be recovered without it."
msgstr ""
msgstr "Hãy chắc chắn lưu trữ cụm từ khôi phục của bạn ở một nơi an toàn. Nếu ứng dụng này bị xóa, tiền của bạn không thể được phục hồi mà không có nó."
#: www/views/preferencesBitpayServices.html:9
msgid "BitPay Visa&reg; Cards"
msgstr ""
msgstr "BitPay Visa & reg; thẻ"
#: www/views/addressbook.add.html:38
#: www/views/includes/incomingDataMenu.html:29
msgid "Bitcoin Address"
msgstr ""
msgstr "Bitcoin Address"
#: www/views/cashScan.html:4
msgid "Bitcoin Cash (BCH) Balances"
msgstr ""
msgstr "Bitcoin Cash (BCH) Balances"
#: www/views/preferencesCash.html:3
#: www/views/tab-settings.html:47
msgid "Bitcoin Cash Support"
msgstr ""
msgstr "Bitcoin Cash Support"
#: www/views/tab-home.html:98
#: www/views/tab-settings.html:115
msgid "Bitcoin Cash Wallets"
msgstr ""
msgstr "Bitcoin Cash Wallets"
#: www/views/modals/chooseFeeLevel.html:4
#: www/views/preferencesFee.html:4
#: www/views/tab-settings.html:90
msgid "Bitcoin Network Fee Policy"
msgstr ""
msgstr "Bitcoin Network Fee Policy"
#: www/views/tab-home.html:83
#: www/views/tab-settings.html:107
msgid "Bitcoin Core Wallets"
msgstr ""
msgstr "Bitcoin Core Wallets"
#: src/js/services/incomingData.js:151
msgid "Bitcoin cash Payment"
msgstr ""
msgstr "Bitcoin cash Payment"
#: www/views/onboarding/tour.html:31
msgid "Bitcoin is a currency."
msgstr ""
msgstr "Bitcoin is a currency."
#: www/views/onboarding/disclaimer.html:15
msgid "Bitcoin is different &ndash; it cannot be safely held with a bank or web service."
msgstr ""
msgstr "&ndash;."
#: www/views/onboarding/tour.html:18
msgid "Bitcoin is secure,<br>digital money."
msgstr ""
msgstr "Bitcoin là an toàn, <br> tiền kỹ thuật số."
#: www/views/preferencesFee.html:11
msgid "Bitcoin transactions include a fee collected by miners on the network."
msgstr ""
msgstr "Bitcoin transactions include a fee collected by miners on the network."
#: www/views/buyAmazon.html:108
msgid "Bought {{amountUnitStr}}"
msgstr ""
msgstr "Bought {{amountUnitStr}}"
#: www/views/modals/txp-details.html:36
msgid "Broadcast Payment"
msgstr ""
msgstr "Broadcast Payment"
#: src/js/controllers/modals/txpDetails.js:64
#: src/js/controllers/tx-details.js:81
msgid "Broadcasted"
msgstr ""
msgstr "Broadcasted"
#: src/js/services/onGoingProcess.js:11
msgid "Broadcasting transaction"
msgstr ""
msgstr "Broadcasting transaction"
#: www/views/unsupported.html:6
msgid "Browser unsupported"
msgstr ""
msgstr "Browser unsupported"
#: www/views/buyAmazon.html:5
#: www/views/buyMercadoLibre.html:6
msgid "Buy"
msgstr ""
msgstr "Buy"
#: www/views/includes/buyAndSellCard.html:3
msgid "Buy &amp; Sell Bitcoin"
msgstr ""
msgstr "Buy &amp; Sell Bitcoin"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
msgstr "Buy Bitcoin"
#: www/views/mercadoLibre.html:22
#: www/views/mercadoLibre.html:50
msgid "Buy a Gift Card"
msgstr ""
msgstr "Buy a Gift Card"
#: src/js/controllers/buyAmazon.js:334
msgid "Buy from"
msgstr ""
msgstr "Buy from"
#: src/js/services/onGoingProcess.js:40
msgid "Buying Bitcoin..."
msgstr ""
msgstr "Mua Bitcoin..."
#: src/js/services/onGoingProcess.js:12
msgid "Calculating fee"
msgstr ""
msgstr "Phí tính toán"
#: src/js/controllers/buyAmazon.js:313
#: src/js/controllers/buyMercadoLibre.js:307
@ -474,65 +478,65 @@ msgstr ""
#: www/views/modals/bitpay-card-confirmation.html:8
#: www/views/modals/confirmation.html:13
msgid "Cancel"
msgstr ""
msgstr "Hủy bỏ"
#: www/views/copayers.html:36
msgid "Cancel invitation"
msgstr ""
msgstr "Hủy lời mời"
#: src/js/controllers/onboarding/tour.js:52
msgid "Cannot Create Wallet"
msgstr ""
msgstr "Không thể tạo Wallet"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr ""
msgstr "Cannot join the same wallet more that once"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
msgstr ""
msgstr "Cards"
#: www/views/modals/paypro.html:30
msgid "Certified by"
msgstr ""
msgstr "Certified by"
#: www/views/preferencesExternal.html:19
msgid "Check installation and retry."
msgstr ""
msgstr "Check installation and retry."
#: www/views/tab-import-file.html:4
msgid "Choose a backup file from your computer"
msgstr ""
msgstr "Chọn tệp sao lưu từ máy tính của bạn"
#: www/views/modals/wallets.html:9
msgid "Choose your destination wallet"
msgstr ""
msgstr "Choose your destination wallet"
#: www/views/modals/wallets.html:10
msgid "Choose your source wallet"
msgstr ""
msgstr "Chọn ví nguồn của bạn"
#: www/views/backup.html:61
msgid "Clear"
msgstr ""
msgstr "Clear"
#: www/views/preferencesHistory.html:24
msgid "Clear cache"
msgstr ""
msgstr "Clear cache"
#: src/js/controllers/confirm.js:373
#: src/js/controllers/modals/txpDetails.js:49
msgid "Click to accept"
msgstr ""
msgstr "Click to accept"
#: src/js/controllers/confirm.js:367
msgid "Click to pay"
msgstr ""
msgstr "Click to pay"
#: src/js/controllers/confirm.js:379
#: src/js/controllers/modals/txpDetails.js:42
msgid "Click to send"
msgstr ""
msgstr "Click to send"
#: www/views/customAmount.html:4
#: www/views/modals/mercadolibre-card-details.html:3
@ -542,28 +546,28 @@ msgstr ""
#: www/views/modals/wallet-balance.html:3
#: www/views/modals/wallets.html:5
msgid "Close"
msgstr ""
msgstr "Close"
#: www/views/includes/cash.html:2
#: www/views/preferencesInformation.html:17
msgid "Coin"
msgstr ""
msgstr "Coin"
#: www/views/preferences.html:22
msgid "Color"
msgstr ""
msgstr "Màu"
#: www/views/preferencesAbout.html:21
msgid "Commit hash"
msgstr ""
msgstr "Commit hash"
#: www/views/preferences.html:49
msgid "Complete the backup process to use this option"
msgstr ""
msgstr "Complete the backup process to use this option"
#: www/views/bitpayCard.html:93
msgid "Completed"
msgstr ""
msgstr "Completed"
#: src/js/controllers/buyAmazon.js:311
#: src/js/controllers/buyMercadoLibre.js:305
@ -575,95 +579,99 @@ msgstr ""
#: www/views/confirm.html:4
#: www/views/onboarding/collectEmail.html:32
msgid "Confirm"
msgstr ""
msgstr "Confirm"
#: www/views/modals/terms.html:26
#: www/views/onboarding/disclaimer.html:44
msgid "Confirm &amp; Finish"
msgstr ""
msgstr "Confirm &amp; Finish"
#: www/views/buyAmazon.html:90
msgid "Confirm purchase"
msgstr ""
msgstr "Confirm purchase"
#: www/views/modals/pin.html:10
msgid "Confirm your PIN"
msgstr ""
msgstr "Confirm your PIN"
#: src/js/services/walletService.js:1033
msgid "Confirm your new spending password"
msgstr ""
msgstr "Confirm your new spending password"
#: www/views/tx-details.html:98
msgid "Confirmations"
msgstr ""
msgstr "Confirmations"
#: www/views/bitpayCard.html:68
#: www/views/modals/wallet-balance.html:61
msgid "Confirming"
msgstr ""
msgstr "Xác nhận"
#: www/views/bitpayCardIntro.html:37
msgid "Connect my BitPay Card"
msgstr ""
msgstr "Kết nối thẻ BitPay của tôi"
#: src/js/services/onGoingProcess.js:13
msgid "Connecting to Coinbase..."
msgstr ""
msgstr "Connecting to Coinbase..."
#: src/js/services/onGoingProcess.js:14
msgid "Connecting to Glidera..."
msgstr ""
msgstr "Đang kết nối với Glidera ..."
#: src/js/services/bwcError.js:53
msgid "Connection reset by peer"
msgstr ""
msgstr "Đặt lại kết nối theo ngang hàng"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr ""
msgstr "Contacts"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Save the regular usage"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr ""
msgstr "Continue"
#: www/views/preferencesLanguage.html:26
msgid "Contribute Translations"
msgstr ""
msgstr "Contribute Translations"
#: src/js/controllers/confirm.js:130
msgid "Copay only supports Bitcoin Cash using new version numbers addresses"
msgstr ""
msgstr "Copay chỉ hỗ trợ Bitcoin Cash bằng cách sử dụng số phiên bản mới"
#: src/js/services/bwcError.js:62
msgid "Copayer already in this wallet"
msgstr ""
msgstr "Copayer already in this wallet"
#: src/js/services/bwcError.js:77
msgid "Copayer already voted on this spend proposal"
msgstr ""
msgstr "Coper is this option"
#: src/js/services/bwcError.js:107
msgid "Copayer data mismatch"
msgstr ""
msgstr "Dữ liệu Copayer không khớp"
#: www/views/includes/walletActivity.html:2
msgid "Copayer joined"
msgstr ""
msgstr "Copayer joined"
#: www/views/preferencesInformation.html:94
msgid "Copayer {{$index}}"
msgstr ""
msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr ""
msgstr "Sao chép vào clipboard"
#: www/views/tab-export-file.html:94
msgid "Copy this text as it is to a safe place (notepad or email)"
msgstr ""
msgstr "Copy this text as it is to a safe place (notepad or email)"
#: www/views/includes/incomingDataMenu.html:51
#: www/views/includes/incomingDataMenu.html:70
@ -671,35 +679,35 @@ msgstr ""
#: www/views/includes/logOptions.html:9
#: www/views/tab-export-file.html:78
msgid "Copy to clipboard"
msgstr ""
msgstr "Sao chép vào clipboard"
#: src/js/controllers/buyMercadoLibre.js:102
msgid "Could not access Gift Card Service"
msgstr ""
msgstr "Could not access Gift Card Service"
#: www/views/tab-import-phrase.html:2
msgid "Could not access the wallet at the server. Please check:"
msgstr ""
msgstr "Could not access the wallet at the server. Please check:"
#: src/js/controllers/buyAmazon.js:102
msgid "Could not access to Amazon.com"
msgstr ""
msgstr "Could not access to Amazon.com"
#: src/js/services/profileService.js:511
msgid "Could not access wallet"
msgstr ""
msgstr "Could not access wallet"
#: src/js/controllers/confirm.js:210
msgid "Could not add message to imported wallet without shared encrypting key"
msgstr ""
msgstr "Could not add message to imported wallet without shared encrypting key"
#: src/js/controllers/modals/txpDetails.js:199
msgid "Could not broadcast payment"
msgstr ""
msgstr "Could not broadcast payment"
#: src/js/services/bwcError.js:41
msgid "Could not build transaction"
msgstr ""
msgstr "Cannot build transaction"
#: src/js/services/walletService.js:854
msgid "Could not create address"
@ -823,7 +831,7 @@ msgstr ""
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr ""
@ -916,7 +924,7 @@ msgstr ""
#: www/views/modals/mercadolibre-card-details.html:6
#: www/views/topup.html:45
msgid "Details"
msgstr ""
msgstr "Chi tiết"
#: src/js/controllers/lockSetup.js:9
#: src/js/controllers/tab-settings.js:65
@ -2533,6 +2541,14 @@ msgstr ""
msgid "Search or enter bitcoin address"
msgstr ""
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr ""
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr ""
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr ""
@ -2591,9 +2607,70 @@ msgid "Send by email"
msgstr ""
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr ""
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr ""
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr ""
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr ""
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr ""
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr ""
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr ""
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr ""
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr ""
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr ""
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr ""
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr ""
@ -3636,3 +3713,51 @@ msgstr ""
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr ""
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr ""
#: www/views/includes/community.html:3
msgid "Community"
msgstr ""
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr ""
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr ""
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr ""
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr ""
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr ""
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr ""
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr ""
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr ""

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Chinese Simplified\n"
"Language: zh\n"
"PO-Revision-Date: 2018-07-04 03:57\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,7 @@ msgstr "帐号"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr ""
msgstr "以较低费用进行即时交易"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -363,12 +363,12 @@ msgstr "比特币地址"
#: www/views/cashScan.html:4
msgid "Bitcoin Cash (BCH) Balances"
msgstr ""
msgstr "Bitcoin Cash (BCH) 余额"
#: www/views/preferencesCash.html:3
#: www/views/tab-settings.html:47
msgid "Bitcoin Cash Support"
msgstr ""
msgstr "Bitcoin Cash 支持"
#: www/views/tab-home.html:98
#: www/views/tab-settings.html:115
@ -384,7 +384,7 @@ msgstr "比特币网络手续费策略"
#: www/views/tab-home.html:83
#: www/views/tab-settings.html:107
msgid "Bitcoin Core Wallets"
msgstr ""
msgstr "Bitcoin Core 钱包"
#: src/js/services/incomingData.js:151
msgid "Bitcoin cash Payment"
@ -437,6 +437,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "购买或出售比特币"
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr "购买比特币"
@ -619,10 +620,14 @@ msgstr "正在连接 Glidera..."
msgid "Connection reset by peer"
msgstr "连接被对方重置"
#: www/views/tab-send.html:45
#: www/views/tab-send.html:85
msgid "Contacts"
msgstr "联系人"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "保存的常用地址"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
msgstr "继续"
@ -653,7 +658,7 @@ msgstr "Copayer 加入"
#: www/views/preferencesInformation.html:94
msgid "Copayer {{$index}}"
msgstr ""
msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
@ -823,7 +828,7 @@ msgstr "创建自己的免费钱包"
#: www/views/onboarding/tour.html:51
#: www/views/tab-home.html:75
#: www/views/tab-send.html:36
#: www/views/tab-send.html:75
msgid "Create bitcoin wallet"
msgstr "创建比特币的钱包"
@ -977,7 +982,7 @@ msgstr "已达到空地址限制。无法生成新的地址。"
#: www/views/preferencesCash.html:17
msgid "Enable Bitcoin Cash wallet creation and operation within the App."
msgstr ""
msgstr "在应用内启用 Bitcoin Cash 创建和操作。"
#: www/views/tab-scan.html:19
msgid "Enable camera access in your device settings to get started."
@ -993,7 +998,7 @@ msgstr "启用推式通知"
#: www/views/preferencesNotifications.html:33
msgid "Enable sound"
msgstr ""
msgstr "启用声音"
#: www/views/tab-scan.html:18
msgid "Enable the camera to get started."
@ -1001,7 +1006,7 @@ msgstr "使该摄像机开始。"
#: www/views/tab-settings.html:49
msgid "Enabled"
msgstr ""
msgstr "已启用"
#: src/js/services/walletService.js:1047
#: src/js/services/walletService.js:1062
@ -1586,7 +1591,7 @@ msgstr "网络地址不正确"
#: src/js/controllers/confirm.js:306
#: src/js/services/bwcError.js:44
msgid "Insufficient confirmed funds"
msgstr ""
msgstr "确认的资金不足"
#: src/js/controllers/topup.js:165
#: src/js/controllers/topup.js:177
@ -2011,7 +2016,7 @@ msgstr "好的"
#: www/views/modals/tx-status.html:36
#: www/views/modals/tx-status.html:46
msgid "OKAY"
msgstr ""
msgstr "确定"
#: www/views/modals/terms.html:15
msgid "Official English Disclaimer"
@ -2053,7 +2058,7 @@ msgstr "打开 GitHub 项目"
#: src/js/controllers/bitpayCard.js:123
#: src/js/controllers/tx-details.js:192
msgid "Open Explorer"
msgstr ""
msgstr "打开浏览器"
#: www/views/tab-scan.html:22
msgid "Open Settings"
@ -2069,7 +2074,7 @@ msgstr "打开网站"
#: src/js/controllers/preferencesCash.js:32
msgid "Open bitcoincash.org?"
msgstr ""
msgstr "打开 bitcoincash.org"
#: src/js/controllers/cashScan.js:18
msgid "Open the recovery tool."
@ -2511,7 +2516,7 @@ msgstr "请扫描你的指纹"
#: www/views/preferencesCash.html:23
msgid "Scan your wallets for Bitcoin Cash"
msgstr ""
msgstr "扫描您的 Bitcoin Cash 钱包"
#: src/js/services/onGoingProcess.js:30
msgid "Scanning Wallet funds..."
@ -2533,6 +2538,14 @@ msgstr "搜索交易"
msgid "Search or enter bitcoin address"
msgstr "搜索或输入比特币地址"
#: src/js/controllers/tab-send.js:28
msgid "Clipboard"
msgstr "剪贴板"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "您的剪贴板为空"
#: www/views/modals/search.html:16
msgid "Search transactions"
msgstr "搜索交易"
@ -2591,9 +2604,70 @@ msgid "Send by email"
msgstr "通过电邮发送"
#: src/js/controllers/confirm.js:177
#: src/js/controllers/tab-send.js:94
msgid "Send from"
msgstr "从发送"
#: src/js/controllers/tab-send.js:77
msgid "Send to"
msgstr "发送到"
#: www/views/tab-send.html:20
msgid "Paste Clipboard"
msgstr "粘贴剪贴板"
#: www/views/tab-send.html:21
msgid "Paste Address"
msgstr "粘贴地址"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "钱包转账"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
msgstr "扫描二维码"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "更快地发送比特币!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "更快地发送比特币!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "保存常用地址,只需点击一下即可将比特币发送到这些地址"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "添加您的第一个联系人"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "您的比特币钱包为空"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
msgstr "首先,购买 Bitcoin Cash (BCH) 或 Bitcoin Core (BTC),或者共享您的地址。"
#: www/views/tab-send.html:70
msgid "You can receive bitcoin from any wallet or service."
msgstr "您可以从任何钱包或服务接收比特币。"
#: www/views/tab-send.html:72
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "若要开始,您将需要创建一个比特币的钱包,并获得一些比特币。"
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "立即购买比特币"
#: www/views/tab-send.html:76
msgid "Show my address"
msgstr "显示我的地址"
#: www/views/includes/itemSelector.html:8
msgid "Send max amount"
msgstr "发送最大数量"
@ -2810,7 +2884,7 @@ msgstr "超级经济"
#: www/views/preferencesCash.html:11
msgid "Support Bitcoin Cash"
msgstr ""
msgstr "支持 Bitcoin Cash"
#: www/views/paperWallet.html:7
msgid "Sweep"
@ -2860,7 +2934,7 @@ msgstr "使用条款"
#: www/views/tab-create-personal.html:118
#: www/views/tab-import-phrase.html:68
msgid "Testnet"
msgstr ""
msgstr "测试网"
#: www/views/includes/incomingDataMenu.html:61
msgid "Text"
@ -3030,7 +3104,7 @@ msgstr "若要开始,请买比特币或共享您的地址。你可以从任何
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "若要开始,您将需要创建一个比特币的钱包,并获得一些比特币。"
msgstr "首先,您需要创建一个比特币钱包,并获得一些比特币。"
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
@ -3200,7 +3274,7 @@ msgstr "查看服务条款"
#: src/js/controllers/bitpayCard.js:122
#: src/js/controllers/tx-details.js:191
msgid "View Transaction on Explorer.Bitcoin.com"
msgstr ""
msgstr "在 Explorer.Bitcoin.com 上查看交易"
#: src/js/controllers/tab-home.js:148
msgid "View Update"
@ -3596,7 +3670,7 @@ msgstr "我"
#: www/views/addressbook.add.html:32
msgid "name@example.com"
msgstr ""
msgstr "name@example.com"
#: www/views/preferencesHistory.html:15
msgid "preparing..."
@ -3636,3 +3710,51 @@ msgstr "下载的 {{updatingTxHistoryProgress}} 交易"
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "{{wallet.m}}{{wallet.n}}"
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "社区"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr "Bitcoin Cash Reddit"
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr "Bitcoin.com Twitter"
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr "探索 Bitcoin.com"
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash 游戏"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "新闻"
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr "矿池"
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr "工具"
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr "比特币价格图表"
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr "免费的 Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "您的比特币钱包已就绪!"

View file

@ -21,6 +21,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
$timeout(function() {
var form = addressbookForm;
if (data && form) {
if (data.result) {
data = data.result;
}
data = data.replace(/^bitcoin(cash)?:/, '');
form.address.$setViewValue(data);
form.address.$isValid = true;
@ -36,9 +39,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
addressbook.address = translated.legacy;
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("contact_created", [{
"coin": $scope.addressbookEntry.coin

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, sendFlowService, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
var config = configService.getSync();
var defaults = configService.getDefaults();
@ -22,6 +22,7 @@ angular.module('copayApp.controllers').controller('addressbookViewController', f
$scope.sendTo = function() {
$ionicHistory.removeBackView();
sendFlowService.clear();
$state.go('tabs.send');
$timeout(function() {
var to = '';
@ -31,12 +32,16 @@ angular.module('copayApp.controllers').controller('addressbookViewController', f
} else {
to = $scope.addressbookEntry.address;
}
$state.transitionTo('tabs.send.amount', {
var stateParams = {
toAddress: to,
toName: $scope.addressbookEntry.name,
toEmail: $scope.addressbookEntry.email,
coin: $scope.addressbookEntry.coin
});
};
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 100);
};

View file

@ -1,68 +1,167 @@
'use strict';
angular.module('copayApp.controllers').controller('amountController', function($scope, $filter, $timeout, $ionicModal, $ionicScrollDelegate, $ionicHistory, storageService, walletService, gettextCatalog, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, txFormatService, ongoingProcess, popupService, bwcError, payproService, profileService, bitcore, amazonService, nodeWebkitService) {
angular.module('copayApp.controllers').controller('amountController', amountController);
function amountController(configService, $filter, gettextCatalog, $ionicHistory, $ionicModal, $ionicScrollDelegate, lodash, $log, nodeWebkitService, rateService, $scope, $state, $timeout, sendFlowService, shapeshiftService, txFormatService, platformInfo, profileService, walletService, $window) {
var vm = this;
vm.allowSend = false;
vm.altCurrencyList = [];
vm.alternativeAmount = '';
vm.alternativeUnit = '';
vm.amount = '0';
vm.availableFunds = '';
// Use insufficient for logic, as when the amount is invalid, funds being
// either sufficent or insufficient doesn't make sense.
vm.fundsAreInsufficient = false;
vm.globalResult = '';
vm.isRequestingSpecificAmount = false;
vm.listComplete = false;
vm.lastUsedPopularList = [];
vm.maxAmount = 0;
vm.minAmount = 0;
vm.thirdParty = false;
vm.unit = '';
vm.changeUnit = changeUnit;
vm.close = close;
vm.findCurrency = findCurrency;
vm.finish = finish;
vm.goBack = goBack;
vm.loadMore = loadMore;
vm.next = next;
vm.openPopup = openPopup;
vm.pushDigit = pushDigit;
vm.removeDigit = removeDigit;
vm.save = save;
vm.sendMax = sendMax;
vm.errorMessage = '';
$scope.$on('$ionicView.beforeEnter', onBeforeEnter);
$scope.$on('$ionicView.leave', onLeave);
var _id;
var unitToSatoshi;
var satToUnit;
var unitDecimals;
var satToBtc;
var SMALL_FONT_SIZE_LIMIT = 10;
var LENGTH_EXPRESSION_LIMIT = 19;
var LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT = 8;
var LENGTH_AFTER_COMMA_EXPRESSION_LIMIT = 8;
var isNW = platformInfo.isNW;
var unitIndex = 0;
var altCurrencyModal = null;
var altUnitIndex = 0;
var availableFundsInCrypto = '';
var availableFundsInFiat = '';
var availableSatoshis = null;
var availableUnits = [];
var fiatCode;
var isNW = platformInfo.isNW;
var isAndroid = platformInfo.isAndroid;
var isIos = platformInfo.isIOS;
var lastUsedAltCurrencyList = [];
var passthroughParams = {};
var satToUnit;
var unitDecimals;
var unitIndex = 0;
var unitToSatoshi;
var useSendMax = false;
var fixedUnit;
$scope.amountModel = { amount: 0 };
$scope.isChromeApp = platformInfo.isChromeApp;
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIos = platformInfo.isIOS;
$scope.$on('$ionicView.leave', function() {
function onLeave() {
angular.element($window).off('keydown');
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
}
function onBeforeEnter(event, data) {
if (data.direction == "back") {
sendFlowService.popState();
}
console.log('amount onBeforeEnter after back sendflow ', sendFlowService.state);
initCurrencies();
if (data.stateParams.shapeshiftOrderId && data.stateParams.shapeshiftOrderId.length > 0) {
$scope.minShapeshiftAmount = parseFloat(data.stateParams.minShapeshiftAmount);
$scope.maxShapeshiftAmount = parseFloat(data.stateParams.maxShapeshiftAmount);
$scope.shapeshiftOrderId = data.stateParams.shapeshiftOrderId;
}
passthroughParams = sendFlowService.getStateClone();
// To get the wallet from with the new flow
$scope.fromWalletId = data.stateParams.fromWalletId;
vm.fromWalletId = passthroughParams.fromWalletId;
vm.toWalletId = passthroughParams.toWalletId;
vm.minAmount = parseFloat(passthroughParams.minAmount);
vm.maxAmount = parseFloat(passthroughParams.maxAmount);
if (data.stateParams.noPrefix) {
$scope.showWarningMessage = data.stateParams.noPrefix != 0;
if ($scope.showWarningMessage) {
var message = 'Address doesn\'t contain currency information, please make sure you are sending the correct currency.';
popupService.showAlert('', message, function() {}, 'Ok');
if (passthroughParams.thirdParty) {
vm.thirdParty = passthroughParams.thirdParty; // Parse stringified JSON-object
if (vm.thirdParty) {
if (vm.thirdParty.id === 'shapeshift') {
if (!vm.thirdParty.data) {
vm.thirdParty.data = {};
}
vm.thirdParty.data['fromWalletId'] = vm.fromWalletId;
vm.fromWallet = profileService.getWallet(vm.fromWalletId);
vm.toWallet = profileService.getWallet(vm.toWalletId);
shapeshiftService.getMarketData(vm.fromWallet.coin, vm.toWallet.coin, function(data) {
vm.thirdParty.data['minAmount'] = vm.minAmount = parseFloat(data.minimum);
vm.thirdParty.data['maxAmount'] = vm.maxAmount = parseFloat(data.maxLimit);
});
}
}
}
vm.isRequestingSpecificAmount = !passthroughParams.fromWalletId;
var config = configService.getSync().wallet.settings;
setAvailableUnits();
updateUnitUI();
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
if (!isAndroid && !isIos) {
var disableKeys = angular.element($window).on('keydown', function(e) {
if (!e.key) return;
if (e.which === 8) { // you can add others here inside brackets.
if (!altCurrencyModal) {
e.preventDefault();
vm.removeDigit();
}
}
if (e.key.match(reNr)) {
vm.pushDigit(e.key);
} else if (e.key.match(reOp)) {
pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey) processClipboard();
} else if (e.keyCode === 13) vm.finish();
$timeout(function() {
$scope.$apply();
});
});
}
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
unitDecimals = config.unitDecimals;
resetAmount();
processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
function setAvailableUnits() {
var defaults = configService.getDefaults();
var configCache = configService.getSync();
availableUnits = [];
var hasBCHWallets = profileService.getWallets({
coin: 'bch'
}).length;
var coinFromWallet = '';
if (passthroughParams.fromWalletId) {
var fromWallet = profileService.getWallet(passthroughParams.fromWalletId);
coinFromWallet = fromWallet.coin;
} else {
var toWallet = profileService.getWallet(passthroughParams.toWalletId);
coinFromWallet = toWallet.coin;
}
if (hasBCHWallets) {
if (coinFromWallet === 'bch') {
availableUnits.push({
name: 'Bitcoin Cash',
id: 'bch',
@ -70,11 +169,7 @@ angular.module('copayApp.controllers').controller('amountController', function($
});
};
var hasBTCWallets = profileService.getWallets({
coin: 'btc'
}).length;
if (hasBTCWallets) {
if (coinFromWallet === 'btc') {
availableUnits.push({
name: 'Bitcoin',
id: 'btc',
@ -84,31 +179,11 @@ angular.module('copayApp.controllers').controller('amountController', function($
unitIndex = 0;
if (data.stateParams.coin) {
var coins = data.stateParams.coin.split(',');
var newAvailableUnits = [];
lodash.each(coins, function(c) {
var coin = lodash.find(availableUnits, {
id: c
});
if (!coin) {
$log.warn('Could not find desired coin:' + data.stateParams.coin)
} else {
newAvailableUnits.push(coin);
}
});
if (newAvailableUnits.length > 0) {
availableUnits = newAvailableUnits;
}
}
// currency have preference
var fiatName;
if (data.stateParams.currency) {
fiatCode = data.stateParams.currency;
if (passthroughParams.currency) {
fiatCode = passthroughParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
@ -125,142 +200,53 @@ angular.module('copayApp.controllers').controller('amountController', function($
isFiat: true,
});
if (data.stateParams.fixedUnit) {
fixedUnit = true;
}
unitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
altUnitIndex = 0;
};
// Go to...
_id = data.stateParams.id; // Optional (BitPay Card ID or Wallet ID)
$scope.nextStep = data.stateParams.nextStep;
setAvailableUnits();
updateUnitUI();
$scope.hasMaxAmount = true;
if ($ionicHistory.backView().stateName == 'tabs.receive') {
$scope.hasMaxAmount = false;
}
$scope.showMenu = $ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send' || $ionicHistory.backView().stateName == 'tabs.bitpayCard');
$scope.recipientType = data.stateParams.recipientType || null;
$scope.toAddress = data.stateParams.toAddress;
$scope.displayAddress = data.stateParams.displayAddress;
$scope.toName = data.stateParams.toName;
$scope.toEmail = data.stateParams.toEmail;
$scope.toColor = data.stateParams.toColor;
if (!$scope.nextStep && !data.stateParams.toAddress) {
$log.error('Bad params at amount')
throw ('bad params');
}
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
if (!$scope.isAndroid && !$scope.isIos) {
var disableKeys = angular.element($window).on('keydown', function(e) {
if (!e.key) return;
if (e.which === 8) { // you can add others here inside brackets.
if (!$scope.altCurrencyModal) {
e.preventDefault();
$scope.removeDigit();
}
}
if (e.key.match(reNr)) {
$scope.pushDigit(e.key);
} else if (e.key.match(reOp)) {
$scope.pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey) processClipboard();
} else if (e.keyCode === 13) $scope.finish();
$timeout(function() {
$scope.$apply();
});
});
}
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isCordova = platformInfo.isCordova;
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
satToBtc = 1 / 100000000;
unitDecimals = config.unitDecimals;
$scope.resetAmount();
// in SAT ALWAYS
if ($stateParams.toAmount) {
$scope.amountModel.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals);
}
$scope.processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
});
$scope.goBack = function() {
if ($scope.shapeshiftOrderId) {
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.shapeshift');
});
});
} else {
$ionicHistory.goBack();
if (passthroughParams.fromWalletId) {
var fromWallet = profileService.getWallet(passthroughParams.fromWalletId);
updateAvailableFundsFromWallet(fromWallet);
}
}
}
function goBack() {
$ionicHistory.goBack();
}
function paste(value) {
$scope.amountModel.amount = value;
$scope.processAmount();
vm.amount = value;
processAmount();
$timeout(function() {
$scope.$apply();
});
};
}
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
};
}
$scope.sendMax = function() {
$scope.useSendMax = true;
$scope.finish();
};
$scope.toggleAlternative = function() {
if ($scope.amountModel.amount && isExpression($scope.amountModel.amount)) {
var amount = evaluate(format($scope.amountModel.amount));
$scope.globalResult = '= ' + processResult(amount);
}
};
function sendMax() {
useSendMax = true;
finish();
}
function updateUnitUI() {
$scope.unit = availableUnits[unitIndex].shortName;
$scope.alternativeUnit = availableUnits[altUnitIndex].shortName;
vm.unit = availableUnits[unitIndex].shortName;
vm.alternativeUnit = availableUnits[altUnitIndex].shortName;
$scope.processAmount();
$log.debug('Update unit coin @amount unit:' + $scope.unit + " alternativeUnit:" + $scope.alternativeUnit);
};
processAmount();
$log.debug('Update unit coin @amount unit:' + vm.unit + " alternativeUnit:" + vm.alternativeUnit);
}
$scope.changeUnit = function() {
function changeUnit() {
$scope.amountModel.amount = '0';
if (fixedUnit) return;
vm.amount = '0';
if (!(availableUnits[unitIndex].isFiat && availableUnits.length > 2 && altUnitIndex == 0)) {
unitIndex++;
@ -275,153 +261,166 @@ angular.module('copayApp.controllers').controller('amountController', function($
});
}
updateAvailableFundsStringIfNeeded();
updateUnitUI();
};
}
$scope.changeAlternativeUnit = function() {
// Do nothing is fiat is not main unit
if (!availableUnits[unitIndex].isFiat) return;
var nextCoin = lodash.findIndex(availableUnits, function(x) {
if (x.isFiat) return false;
if (x.id == availableUnits[altUnitIndex].id) return false;
return true;
});
if (nextCoin >= 0) {
altUnitIndex = nextCoin;
updateUnitUI();
}
};
function checkFontSize() {
if ($scope.amountModel.amount && $scope.amountModel.amount.length >= SMALL_FONT_SIZE_LIMIT) $scope.smallFont = true;
else $scope.smallFont = false;
};
$scope.pushDigit = function(digit) {
if ($scope.amountModel.amount && digit != '.') {
var amountSplitByComma = $scope.amountModel.amount.split('.');
function pushDigit(digit) {
if (vm.amount && digit != '.') {
var amountSplitByComma = vm.amount.split('.');
if (amountSplitByComma.length > 1 && amountSplitByComma[1].length >= LENGTH_AFTER_COMMA_EXPRESSION_LIMIT) return;
if (amountSplitByComma.length == 1 && amountSplitByComma[0].length >= LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT) return;
}
if ($scope.amountModel.amount && $scope.amountModel.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if ($scope.amountModel.amount.indexOf('.') > -1 && digit == '.') return;
if ($scope.amountModel.amount == '0' && digit == '0') return;
if (availableUnits[unitIndex].isFiat && $scope.amountModel.amount.indexOf('.') > -1 && $scope.amountModel.amount[$scope.amountModel.amount.indexOf('.') + 2]) return;
if (vm.amount && vm.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if (vm.amount.indexOf('.') > -1 && digit == '.') return;
if (vm.amount == '0' && digit == '0') return;
if (availableUnits[unitIndex].isFiat && vm.amount.indexOf('.') > -1 && vm.amount[vm.amount.indexOf('.') + 2]) return;
if ($scope.amountModel.amount == '0' && digit != '.') {
$scope.amountModel.amount = '';
if (vm.amount == '0' && digit != '.') {
vm.amount = '';
}
if ($scope.amountModel.amount == '' && digit == '.') {
$scope.amountModel.amount = '0';
if (vm.amount == '' && digit == '.') {
vm.amount = '0';
}
$scope.amountModel.amount = ($scope.amountModel.amount + digit).replace('..', '.');
checkFontSize();
$scope.processAmount();
};
vm.amount = (vm.amount + digit).replace('..', '.');
processAmount();
}
$scope.pushOperator = function(operator) {
if (!$scope.amountModel.amount || $scope.amountModel.amount.length == 0) return;
$scope.amountModel.amount = _pushOperator($scope.amountModel.amount);
function pushOperator(operator) {
if (!vm.amount || vm.amount.length == 0) return;
vm.amount = pushOperator(vm.amount);
function _pushOperator(val) {
function pushOperator(val) {
if (!isOperator(lodash.last(val))) {
return val + operator;
} else {
return val.slice(0, -1) + operator;
}
};
};
}
}
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
};
}
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
};
}
$scope.removeDigit = function() {
$scope.amountModel.amount = ($scope.amountModel.amount).toString().slice(0, -1);
$scope.processAmount();
checkFontSize();
};
function removeDigit() {
vm.amount = (vm.amount).toString().slice(0, -1);
processAmount();
}
$scope.resetAmount = function() {
$scope.amountModel.amount = $scope.alternativeAmount = $scope.globalResult = '';
$scope.allowSend = false;
checkFontSize();
};
function resetAmount() {
vm.amount = vm.alternativeAmount = vm.globalResult = '0';
vm.allowSend = false;
}
$scope.openPopup = function() {
function openPopup() {
$ionicModal.fromTemplateUrl('views/modals/altCurrency.html', {
scope: $scope
}).then(function(modal) {
$scope.altCurrencyModal = modal;
$scope.altCurrencyModal.show();
altCurrencyModal = modal;
altCurrencyModal.show();
});
};
}
$scope.close = function() {
$scope.altCurrencyModal.remove();
$scope.altCurrencyModal = false;
};
function close() {
altCurrencyModal.remove();
altCurrencyModal = null;
}
$scope.processAmount = function() {
var formatedValue = format($scope.amountModel.amount);
function processAmount() {
var formatedValue = format(vm.amount);
var result = evaluate(formatedValue);
var amountInCrypto = 0;
if (lodash.isNumber(result)) {
$scope.globalResult = isExpression($scope.amountModel.amount) ? '= ' + processResult(result) : '';
vm.globalResult = isExpression(vm.amount) ? '= ' + processResult(result) : '';
if (availableUnits[unitIndex].isFiat) {
var a = fromFiat(result);
if (a) {
$scope.alternativeAmount = txFormatService.formatAmount(a * unitToSatoshi, true);
$scope.allowSend = lodash.isNumber(a) && a > 0
&& (!$scope.shapeshiftOrderId
|| (a >= $scope.minShapeshiftAmount && a <= $scope.maxShapeshiftAmount));
amountInCrypto = a;
var amountInSatoshis = a * unitToSatoshi;
vm.fundsAreInsufficient = !!passthroughParams.fromWalletId
&& availableSatoshis !== null
&& availableSatoshis < amountInSatoshis;
vm.alternativeAmount = txFormatService.formatAmount(amountInSatoshis, true);
vm.allowSend = lodash.isNumber(a)
&& a > 0
&& (!vm.minAmount || a >= vm.minAmount)
&& (!vm.maxAmount || a <= vm.maxAmount)
&& !vm.fundsAreInsufficient;
} else {
if (result) {
$scope.alternativeAmount = 'N/A';
vm.alternativeAmount = 'N/A';
} else {
$scope.alternativeAmount = null;
vm.alternativeAmount = null;
}
$scope.allowSend = false;
vm.fundsAreInsufficient = false;
vm.allowSend = false;
}
} else {
$scope.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
$scope.allowSend = lodash.isNumber(result) && result > 0
&& (!$scope.shapeshiftOrderId
|| (result >= $scope.minShapeshiftAmount && result <= $scope.maxShapeshiftAmount));
amountInCrypto = result;
vm.fundsAreInsufficient = passthroughParams.fromWalletId
&& availableSatoshis !== null
&& availableSatoshis < result * unitToSatoshi;
vm.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
vm.allowSend = lodash.isNumber(result)
&& result > 0
&& (!vm.minAmount || result >= vm.minAmount)
&& (!vm.maxAmount || result <= vm.maxAmount)
&& !vm.fundsAreInsufficient;
}
} else {
vm.fundsAreInsufficient = false;
}
};
if (vm.fundsAreInsufficient) {
vm.errorMessage = gettextCatalog.getString('Not enough available funds');
} else if (amountInCrypto && vm.thirdParty && vm.thirdParty.id === 'shapeshift') {
if (amountInCrypto < vm.minAmount) {
vm.errorMessage = gettextCatalog.getString('Amount is below minimum');
} else if (amountInCrypto > vm.maxAmount) {
vm.errorMessage = gettextCatalog.getString('Amount is above maximum');
} else {
vm.errorMessage = '';
}
} else {
vm.errorMessage = '';
}
}
function processResult(val) {
if (availableUnits[unitIndex].isFiat) return $filter('formatFiatAmount')(val);
else return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
};
}
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
};
}
function toFiat(val) {
if (!rateService.getRate(fiatCode)) return;
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
};
}
function evaluate(val) {
var result;
@ -432,7 +431,7 @@ angular.module('copayApp.controllers').controller('amountController', function($
}
if (!lodash.isFinite(result)) return 0;
return result;
};
}
function format(val) {
if (!val) return;
@ -442,97 +441,44 @@ angular.module('copayApp.controllers').controller('amountController', function($
if (isOperator(lodash.last(val))) result = result.slice(0, -1);
return result.replace('x', '*');
};
}
$scope.finish = function() {
function finish() {
var unit = availableUnits[unitIndex];
var uiAmount = evaluate(format(vm.amount));
function finish() {
var unit = availableUnits[unitIndex];
var _amount = evaluate(format($scope.amountModel.amount));
var coin = unit.id;
if (unit.isFiat) {
coin = availableUnits[altUnitIndex].id;
}
var satoshis = 0;
if (unit.isFiat) {
satoshis = (fromFiat(uiAmount) * unitToSatoshi).toFixed(0);
} else {
satoshis = (uiAmount * unitToSatoshi).toFixed(0);
}
if ($scope.nextStep) {
$state.transitionTo($scope.nextStep, {
id: _id,
amount: $scope.useSendMax ? null : _amount,
currency: unit.id.toUpperCase(),
coin: coin,
useSendMax: $scope.useSendMax,
fromWalletId: $scope.fromWalletId
});
} else {
var amount = _amount;
var confirmData = {
amount: useSendMax ? undefined : satoshis,
fromWalletId: passthroughParams.fromWalletId,
sendMax: useSendMax,
toAddress: passthroughParams.toAddress,
toWalletId: passthroughParams.toWalletId
};
if (unit.isFiat) {
amount = (fromFiat(amount) * unitToSatoshi).toFixed(0);
} else {
amount = (amount * unitToSatoshi).toFixed(0);
}
if (vm.thirdParty) {
confirmData.thirdParty = vm.thirdParty;
}
var confirmData = {
recipientType: $scope.recipientType,
toAmount: amount,
toAddress: $scope.toAddress,
displayAddress: $scope.displayAddress || $scope.toAddress,
toName: $scope.toName,
toEmail: $scope.toEmail,
toColor: $scope.toColor,
coin: coin,
useSendMax: $scope.useSendMax,
fromWalletId: $scope.fromWalletId
};
if ($scope.shapeshiftOrderId) {
var shapeshiftOrderUrl = 'https://www.shapeshift.io/#/status/';
shapeshiftOrderUrl += $scope.shapeshiftOrderId;
confirmData.description = shapeshiftOrderUrl;
confirmData.fromWalletId = $scope.fromWalletId;
if (confirmData.useSendMax) {
var wallet = lodash.find(profileService.getWallets({ coin: coin }),
function(w) {
return w.id == $scope.fromWalletId;
});
var balance = parseFloat(wallet.cachedBalance.substring(0, wallet.cachedBalance.length-4));
if (balance < $scope.minShapeshiftAmount * 1.04) {
confirmData.useSendMax = false;
confirmData.toAmount = $scope.minShapeshiftAmount * unitToSatoshi;
} else if (balance > $scope.maxShapeshiftAmount) {
confirmData.useSendMax = false;
confirmData.toAmount = $scope.maxShapeshiftAmount * unitToSatoshi * 0.99;
}
}
}
$state.transitionTo('tabs.send.review', confirmData);
}
sendFlowService.pushState(confirmData);
if (!confirmData.fromWalletId) {
$state.transitionTo('tabs.paymentRequest.confirm', confirmData);
} else {
$state.transitionTo('tabs.send.review', confirmData);
$scope.useSendMax = null;
}
if ($scope.showWarningMessage) {
var u = $scope.unit == 'BCH' || $scope.unit == 'BTC' ? $scope.unit : $scope.alternativeUnit;
var message = 'Are you sure you want to send ' + u.toUpperCase() + '?';
popupService.showConfirm(message, '', 'Yes', 'No', function(res) {
if (!res) {
$scope.useSendMax = null;
return;
};
finish();
});
} else {
finish();
}
};
}
// Currency
var next = 10;
var nextCurrencies = 10;
var completeAlternativeList = [];
var popularCurrencyList = [
@ -546,7 +492,7 @@ angular.module('copayApp.controllers').controller('amountController', function($
{isoCode: 'CNY', order: 7},
{isoCode: 'KRW', order: 8},
{isoCode: 'HKD', order: 9},
]
];
function initCurrencies() {
var unusedCurrencyList = [{
@ -562,10 +508,10 @@ angular.module('copayApp.controllers').controller('amountController', function($
}];
rateService.whenAvailable(function() {
$scope.listComplete = false;
vm.listComplete = false;
var idx = lodash.indexBy(unusedCurrencyList, 'isoCode');
var idx2 = lodash.indexBy($scope.lastUsedAltCurrencyList, 'isoCode');
var idx2 = lodash.indexBy(lastUsedAltCurrencyList, 'isoCode');
var idx3 = lodash.indexBy(popularCurrencyList, 'isoCode');
var alternatives = rateService.listAlternatives(true);
@ -578,8 +524,10 @@ angular.module('copayApp.controllers').controller('amountController', function($
}
});
$scope.altCurrencyList = completeAlternativeList.slice(0, 10);
$scope.lastUsedPopularList = lodash.unique(lodash.union($scope.lastUsedAltCurrencyList, popularCurrencyList), 'isoCode');
vm.altCurrencyList = completeAlternativeList.slice(0, 10);
vm.lastUsedPopularList = lodash.unique(lodash.union(lastUsedAltCurrencyList, popularCurrencyList), 'isoCode');
rateService.updateRates();
$timeout(function() {
$scope.$apply();
@ -587,19 +535,24 @@ angular.module('copayApp.controllers').controller('amountController', function($
});
}
$scope.loadMore = function() {
function loadMore() {
$timeout(function() {
$scope.altCurrencyList = completeAlternativeList.slice(0, next);
next += 10;
$scope.listComplete = $scope.altCurrencyList.length >= completeAlternativeList.length;
vm.altCurrencyList = completeAlternativeList.slice(0, nextCurrencies);
nextCurrencies += 10;
vm.listComplete = vm.altCurrencyList.length >= completeAlternativeList.length;
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 100);
};
}
$scope.findCurrency = function(search) {
function next() {
useSendMax = false;
vm.finish();
}
function findCurrency(search) {
if (!search) initCurrencies();
var list = lodash.unique(lodash.union(completeAlternativeList, lodash.union($scope.lastUsedAltCurrencyList, popularCurrencyList)), 'isoCode');
$scope.altCurrencyList = lodash.filter(list, function(item) {
var list = lodash.unique(lodash.union(completeAlternativeList, lodash.union(lastUsedAltCurrencyList, popularCurrencyList)), 'isoCode');
vm.altCurrencyList = lodash.filter(list, function(item) {
var val = item.name
var val2 = item.isoCode;
return lodash.includes(val.toLowerCase(), search.toLowerCase()) || lodash.includes(val2.toLowerCase(), search.toLowerCase());
@ -607,9 +560,9 @@ angular.module('copayApp.controllers').controller('amountController', function($
$timeout(function() {
$scope.$apply();
});
};
}
$scope.save = function(newAltCurrency) {
function save(newAltCurrency) {
var opts = {
wallet: {
settings: {
@ -629,8 +582,63 @@ angular.module('copayApp.controllers').controller('amountController', function($
availableUnits[altUnitIndex].name = newAltCurrency.isoCode;
availableUnits[altUnitIndex].shortName = newAltCurrency.isoCode;
fiatCode = newAltCurrency.isoCode;
updateAvailableFundsStringIfNeeded();
updateUnitUI();
$scope.close();
close();
});
};
});
}
function updateAvailableFundsStringIfNeeded() {
if (passthroughParams.fromWalletId && availableSatoshis !== null) {
availableFundsInFiat = '';
vm.availableFunds = availableFundsInCrypto;
if (availableUnits[unitIndex].isFiat) {
var coin = availableUnits[altUnitIndex].id;
txFormatService.formatAlternativeStr(coin, availableSatoshis, function formatCallback(formatted){
if (formatted) {
availableFundsInFiat = formatted;
$scope.$apply(function() {
vm.availableFunds = availableFundsInFiat;
});
}
});
}
}
}
function updateAvailableFundsFromWallet(wallet) {
if (wallet.status && wallet.status.isValid) {
availableFundsInCrypto = wallet.status.spendableBalanceStr;
availableSatoshis = wallet.status.spendableAmount;
if (wallet.status.alternativeBalanceAvailable) {
availableFundsInFiat = wallet.status.spendableBalanceAlternative + ' ' + wallet.status.alternativeIsoCode;
} else {
availableFundsInFiat = '';
}
} else if (wallet.cachedStatus && wallet.status.isValid) {
if (wallet.cachedStatus.alternativeBalanceAvailable) {
availableFundsInFiat = wallet.cachedStatus.spendableBalanceAlternative + ' ' + wallet.cachedStatus.alternativeIsoCode;
} else {
availableFundsInFiat = '';
}
availableFundsInCrypto = wallet.cachedStatus.spendableBalanceStr;
availableSatoshis = wallet.cachedStatus.spendableAmount;
} else {
availableFundsInFiat = '';
availableFundsInCrypto = '';
availableSatoshis = null;
}
if (availableUnits[unitIndex].isFiat) {
vm.availableFunds = availableFundsInFiat || availableFundsInCrypto;
} else {
vm.availableFunds = availableFundsInCrypto;
}
}
}

View file

@ -0,0 +1,101 @@
describe('amountController', function(){
var configCache,
configService,
$controller,
$ionicHistory,
$rootScope,
platformInfo,
profileService,
rateService,
$stateParams;
beforeEach(function(){
module('ngLodash');
module('copayApp.controllers');
configCache = {
wallet: {
settings: {
}
}
};
configService = jasmine.createSpyObj(['getDefaults','getSync']);
configService.getDefaults.and.returnValue({
bitcoinCashAlias: 'bch',
bitcoinAlias: 'btc'
});
configService.getSync.and.returnValue(configCache);
$ionicHistory = jasmine.createSpyObj(['backView']);
platformInfo = {
isChromeApp: false,
isAndroid: false,
isIos: true
};
profileService = jasmine.createSpyObj(['getWallets']);
rateService = jasmine.createSpyObj(['fromFiat', 'whenAvailable']);
$stateParams = {};
inject(function(_$controller_, _$rootScope_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$controller = _$controller_;
$rootScope = _$rootScope_;
});
});
it('receives fromWalletId and toAddress.', function() {
var backView = {
stateName: 'ignoreme'
};
$ionicHistory.backView.and.returnValue(backView);
profileService.getWallets.and.returnValue([{}]);
rateService.fromFiat.and.returnValue(12); // satoshis or coins?
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: {},
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: {},
platformInfo: platformInfo,
profileService: profileService,
popupService: {},
rateService: rateService,
$scope: $scope,
$state: {},
$stateParams: $stateParams,
txFormatService: {},
walletService: {}
});
var data = {
stateParams: {
fromWalletId: 'fd56c1e7-e3ac-4fd9-8afc-27b9c1b3718b',
toAddress: 'qrup46avn8t466xxwlzs4qelht7cnwvesv2e29wf7s'
}
};
$scope.$emit('$ionicView.beforeEnter', data);
expect($scope.fromWalletId).toBe('fd56c1e7-e3ac-4fd9-8afc-27b9c1b3718b');
expect($scope.toAddress).toBe('qrup46avn8t466xxwlzs4qelht7cnwvesv2e29wf7s');
});
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('backupController',
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal, firebaseEventsService) {
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal) {
if ($state.current.name == 'onboarding.backup') {
$scope.onboarding = true;
@ -89,7 +89,8 @@ angular.module('copayApp.controllers').controller('backupController',
$scope.setFlow(2);
})
} else {
firebaseEventsService.logEvent('backed_up_wallet');
//firebaseEventsService.logEvent('backed_up_wallet');
openConfirmBackupModal();
}
};

View file

@ -1,25 +1,20 @@
'use strict';
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, $stateParams, $window, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bwcError, txConfirmNotification, externalLinkService, firebaseEventsService, soundService) {
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $timeout, $ionicScrollDelegate, $ionicLoading, ionicToast, addressbookService, gettextCatalog, walletService, platformInfo, lodash, configService, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, feeService, bitcoinCashJsService, bwcError, txConfirmNotification, soundService, clipboardService) {
var countDown = null;
var FEE_TOO_HIGH_LIMIT_PER = 15;
var tx = {};
var lastTxId = "";
// Config Related values
var config = configService.getSync();
var walletConfig = config.wallet;
var unitToSatoshi = walletConfig.settings.unitToSatoshi;
var unitDecimals = walletConfig.settings.unitDecimals;
var satToUnit = 1 / unitToSatoshi;
var configFeeLevel = walletConfig.settings.feeLevel ? walletConfig.settings.feeLevel : 'normal';
// Platform info
var isChromeApp = platformInfo.isChromeApp;
var isCordova = platformInfo.isCordova;
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
//custom fee flag
var usingCustomFee = false;
@ -31,6 +26,16 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}, 10);
}
$scope.shareTransaction = function() {
var explorerTxUrl = 'https://explorer.bitcoin.com/'+tx.coin+'/tx/'+lastTxId;
if (platformInfo.isCordova) {
var text = 'Take a look at this Bitcoin transaction here: '+explorerTxUrl;
window.plugins.socialsharing.share(text, null, null, null);
} else {
ionicToast.show(gettextCatalog.getString('Copied to clipboard'), 'bottom', false, 3000);
clipboardService.copyToClipboard(explorerTxUrl);
}
};
$scope.showWalletSelector = function() {
$scope.walletSelector = true;
@ -45,7 +50,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$ionicConfig.views.swipeBackEnabled(false);
});
function exitWithError(err) {
$log.info('Error setting wallet selector:' + err);
popupService.showAlert(gettextCatalog.getString(), bwcError.msg(err), function() {
@ -68,112 +72,108 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
var setWalletSelector = function(coin, network, minAmount, cb) {
function setWalletSelector(coin, network, minAmount, cb) {
// no min amount? (sendMax) => look for no empty wallets
minAmount = minAmount || 1;
// no min amount? (sendMax) => look for no empty wallets
minAmount = minAmount || 1;
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: network,
coin: coin
});
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: network,
coin: coin
if (tx.fromWalletId) {
$scope.wallets = lodash.filter($scope.wallets, function (w) {
return w.id == tx.fromWalletId;
});
if (tx.fromWalletId) {
$scope.wallets = lodash.filter($scope.wallets, function(w) {
return w.id == tx.fromWalletId;
});
}
if (!$scope.wallets || !$scope.wallets.length) {
setNoWallet(gettextCatalog.getString('No wallets available'), true);
return cb();
}
var filteredWallets = [];
var index = 0;
var walletsUpdated = 0;
lodash.each($scope.wallets, function(w) {
walletService.getStatus(w, {}, function(err, status) {
if (err || !status) {
$log.error(err);
} else {
walletsUpdated++;
w.status = status;
if (!status.availableBalanceSat)
$log.debug('No balance available in: ' + w.name);
if (status.availableBalanceSat > minAmount) {
filteredWallets.push(w);
}
}
if (++index == $scope.wallets.length) {
if (!walletsUpdated)
return cb('Could not update any wallet');
if (lodash.isEmpty(filteredWallets)) {
setNoWallet(gettextCatalog.getString('Insufficient confirmed funds'), true);
}
$scope.wallets = lodash.clone(filteredWallets);
return cb();
}
});
});
};
// Setup $scope
var B = data.stateParams.coin == 'bch' ? bitcoreCash : bitcore;
var networkName;
try {
networkName = (new B.Address(data.stateParams.toAddress)).network.name;
} catch(e) {
var message = gettextCatalog.getString('Invalid address');
var backText = gettextCatalog.getString('Go back');
var learnText = gettextCatalog.getString('Learn more');
popupService.showConfirm(null, message, backText, learnText, function(back) {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
if (!back) {
var url = 'https://support.bitpay.com/hc/en-us/articles/115004671663';
externalLinkService.open(url);
}
});
});
return;
}
if (!$scope.wallets || !$scope.wallets.length) {
setNoWallet(gettextCatalog.getString('No wallets available'), true);
return cb();
}
var filteredWallets = [];
var index = 0;
var walletsUpdated = 0;
lodash.each($scope.wallets, function (w) {
walletService.getStatus(w, {}, function (err, status) {
if (err || !status) {
$log.error(err);
} else {
walletsUpdated++;
w.status = status;
if (!status.availableBalanceSat)
$log.debug('No balance available in: ' + w.name);
if (status.availableBalanceSat > minAmount) {
filteredWallets.push(w);
}
}
if (++index == $scope.wallets.length) {
if (!walletsUpdated)
return cb('Could not update any wallet');
if (lodash.isEmpty(filteredWallets)) {
setNoWallet(gettextCatalog.getString('Insufficient confirmed funds'), true);
}
$scope.wallets = lodash.clone(filteredWallets);
return cb();
}
});
});
};
$scope.getContacts = function(addr) {
addressbookService.list(function(err, ab) {
if (err) $log.error(err);
$scope.hasContacts = lodash.isEmpty(ab) ? false : true;
if (!$scope.hasContacts) return cb();
var completeContacts = [];
lodash.each(ab, function(v, k) {
completeContacts.push({
name: lodash.isObject(v) ? v.name : v,
address: k,
email: lodash.isObject(v) ? v.email : null,
recipientType: 'contact',
coin: v.coin,
displayCoin: (v.coin == 'bch'
? (config.bitcoinCashAlias || defaults.bitcoinCashAlias)
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase()
});
});
return cb();
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.fromWallet = profileService.getWallet(data.stateParams.fromWalletId); // Wallet to send from
// Grab stateParams
tx = {
toAmount: parseInt(data.stateParams.toAmount),
amount: parseInt(data.stateParams.amount),
sendMax: data.stateParams.useSendMax == 'true' ? true : false,
fromWalletId: data.stateParams.fromWalletId,
toAddress: data.stateParams.toAddress,
displayAddress: data.stateParams.displayAddress,
description: data.stateParams.description,
paypro: data.stateParams.paypro,
feeLevel: configFeeLevel,
spendUnconfirmed: walletConfig.spendUnconfirmed,
// Vanity tx info (not in the real tx)
recipientType: data.stateParams.recipientType || null,
toName: data.stateParams.toName,
toEmail: data.stateParams.toEmail,
toColor: data.stateParams.toColor,
network: networkName,
coin: data.stateParams.coin,
recipientType: $scope.recipientType || null,
toName: null,
toEmail: null,
toColor: null,
network: false,
coin: $scope.fromWallet.coin,
txp: {},
};
@ -182,18 +182,71 @@ angular.module('copayApp.controllers').controller('confirmController', function(
tx.feeRate = parseInt(data.stateParams.requiredFeeRate);
}
if (tx.coin && tx.coin == 'bch') {
if (tx.coin && tx.coin === 'bch') {
tx.feeLevel = 'normal';
}
var B = data.stateParams.coin === 'bch' ? bitcoreCash : bitcore;
var networkName;
$scope.recipientType = null;
try {
if (data.stateParams.toWalletId) { // There is a toWalletId, so we presume this is a wallet-to-wallet transfer
$scope.recipientType = 'wallet'; // set transaction type to wallet-to-wallet
$ionicLoading.show();
var toWallet = profileService.getWallet(data.stateParams.toWalletId);
tx.toColor = toWallet.color;
tx.toName = toWallet.name;
// We need an address to send to, so we ask the walletService to create a new address for the toWallet.
walletService.getAddress(toWallet, true, function (err, addr) {
$ionicLoading.hide();
tx.toAddress = addr;
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
setupTx(tx);
});
} else { // This is a Wallet-to-address transfer
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
setupTx(tx);
}
} catch (e) {
var message = gettextCatalog.getString('Invalid address');
popupService.showAlert(null, message, function () {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function () {
$ionicHistory.clearHistory();
});
});
return;
}
});
var setupTx = function(tx) {
if (tx.coin === 'bch') {
tx.displayAddress = bitcoinCashJsService.readAddress(tx.toAddress).cashaddr;
} else {
tx.displayAddress = entry.address;
}
addressbookService.get(tx.coin+tx.toAddress, function(err, addr) { // Check if the recipient is a contact
if (!err && addr) {
tx.toName = addr.name;
tx.toEmail = addr.email;
tx.recipientType = 'contact';
}
});
// Other Scope vars
$scope.isCordova = isCordova;
$scope.isWindowsPhoneApp = isWindowsPhoneApp;
$scope.showAddress = false;
$scope.walletSelectorTitle = gettextCatalog.getString('Send from');
setWalletSelector(tx.coin, tx.network, tx.toAmount, function(err) {
setWalletSelector(tx.coin, tx.network, tx.amount, function(err) {
if (err) {
return exitWithError('Could not update wallets');
}
@ -207,7 +260,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.displayBalanceAsFiat = walletConfig.settings.priceDisplay === 'fiat';
});
};
function getSendMaxInfo(tx, wallet, cb) {
@ -231,7 +284,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
return setSendError(msg);
}
if (tx.toAmount > Number.MAX_SAFE_INTEGER) {
if (tx.amount > Number.MAX_SAFE_INTEGER) {
var msg = gettextCatalog.getString('Amount too big');
$log.warn(msg);
return setSendError(msg);
@ -241,7 +294,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txp.outputs = [{
'toAddress': tx.toAddress,
'amount': tx.toAmount,
'amount': tx.amount,
'message': tx.description
}];
@ -280,13 +333,13 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.tx = tx;
function updateAmount() {
if (!tx.toAmount) return;
if (!tx.amount) return;
// Amount
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.toAmount);
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.amount);
tx.amountValueStr = tx.amountStr.split(' ')[0];
tx.amountUnitStr = tx.amountStr.split(' ')[1];
txFormatService.formatAlternativeStr(wallet.coin, tx.toAmount, function(v) {
txFormatService.formatAlternativeStr(wallet.coin, tx.amount, function(v) {
var parts = v.split(' ');
tx.alternativeAmountStr = v;
tx.alternativeAmountValueStr = parts[0];
@ -342,7 +395,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}
tx.sendMaxInfo = sendMaxInfo;
tx.toAmount = tx.sendMaxInfo.amount;
tx.amount = tx.sendMaxInfo.amount;
updateAmount();
ongoingProcess.set('calculatingFee', false);
$timeout(function() {
@ -393,7 +446,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
function useSelectedWallet() {
if (!$scope.useSendMax) {
showAmount(tx.toAmount);
showAmount(tx.amount);
}
$scope.onWalletSelect($scope.wallet);
@ -402,19 +455,19 @@ angular.module('copayApp.controllers').controller('confirmController', function(
function setButtonText(isMultisig, isPayPro) {
if (isPayPro) {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to pay');
} else {
$scope.buttonText = gettextCatalog.getString('Click to pay');
}
} else if (isMultisig) {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to accept');
} else {
$scope.buttonText = gettextCatalog.getString('Click to accept');
}
} else {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to send');
} else {
$scope.buttonText = gettextCatalog.getString('Click to send');
@ -422,7 +475,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}
};
$scope.toggleAddress = function() {
$scope.showAddress = !$scope.showAddress;
};
@ -612,6 +664,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txConfirmNotification.subscribe(wallet, {
txid: txp.txid
});
lastTxId = txp.txid;
}
}, onSendStatusChange);
};
@ -643,9 +696,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
soundService.play('misc/payment_sent.mp3');
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -655,8 +708,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
// Should be removed
firebaseEventsService.logEvent('sent_bitcoin', { coin: $scope.wallet.coin });
$timeout(function() {
$scope.$digest();
}, 100);

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('createController',
function($scope, $rootScope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, storageService, popupService, appConfigService, pushNotificationsService, firebaseEventsService, $ionicNavBarDelegate) {
function($scope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, popupService, appConfigService, pushNotificationsService, $ionicNavBarDelegate) {
/* For compressed keys, m*73 + n*34 <= 496 */
var COPAYER_PAIR_LIMITS = {
@ -268,7 +268,7 @@ angular.module('copayApp.controllers').controller('createController',
}, 100);
}
else {
firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
//firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
$state.go('tabs.home');
}
}

View file

@ -17,7 +17,7 @@ angular.module('copayApp.controllers').controller('customAmountController', func
}
$scope.$on("$ionicView.beforeEnter", function(event, data) {
var walletId = data.stateParams.id;
var walletId = data.stateParams.toWalletId;
if (!walletId) {
showErrorAndBack('Error', 'No wallet selected');
@ -53,17 +53,26 @@ angular.module('copayApp.controllers').controller('customAmountController', func
$scope.address = bchAddresses[$scope.bchAddressType];
}
$scope.coin = data.stateParams.coin;
$scope.coin = $scope.wallet.coin;
var satoshis = parseInt(data.stateParams.amount, 10);
var parsedAmount = txFormatService.parseAmount(
$scope.wallet.coin,
data.stateParams.amount,
data.stateParams.currency);
satoshis,
'sat');
// Amount in USD or BTC
var amount = parsedAmount.amount;
var currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$timeout(function () {
$scope.$apply();
});
});
if (currency != 'BTC' && currency != 'BCH') {
// Convert to BTC or BCH
var config = configService.getSync().wallet.settings;

View file

@ -76,9 +76,9 @@ angular.module('copayApp.controllers').controller('preferencesNotificationsContr
emailService.updateEmail(opts);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("settings_email_notification_toggle", [{
"toggle": $scope.emailNotifications.value

View file

@ -4,9 +4,10 @@ angular
.module('copayApp.controllers')
.controller('reviewController', reviewController);
function reviewController(addressbookService, configService, $ionicConfig, $log, profileService, $scope, txFormatService) {
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, sendFlowService, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
var vm = this;
vm.buttonText = '';
vm.destination = {
address: '',
balanceAmount: '',
@ -18,68 +19,80 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
kind: '', // 'address', 'contact', 'wallet'
name: ''
};
vm.fee = {
cryptoAmount: '',
cryptoCurrencyCode: '',
description: '',
fiatAmount: '',
fiatCurrency: '',
high: false
};
vm.fee
vm.feeCrypto = '';
vm.feeFiat = '';
vm.fiatCurrency = '';
vm.feeIsHigh = false;
vm.feeLessThanACent = false;
vm.isCordova = platformInfo.isCordova;
vm.notReadyMessage = '';
vm.origin = {
balanceAmount: '',
balanceCurrency: '',
color: '',
currency: '',
currencyColor: '',
name: '',
};
vm.originWallet = null;
vm.paymentExpired = false;
vm.personalNotePlaceholder = gettextCatalog.getString('Enter text here');
vm.primaryAmount = '';
vm.primaryCurrency = '';
vm.usingMerchantFee = false;
vm.readyToSend = false;
vm.remainingTimeStr = '';
vm.secondaryAmount = '';
vm.secondaryCurrency = '';
vm.sendingTitle = gettextCatalog.getString('You are sending');
vm.sendStatus = '';
vm.showAddress = true;
vm.thirdParty = false;
vm.wallet = null;
vm.memoExpanded = false;
// Functions
vm.goBack = goBack;
vm.onSuccessConfirm = onSuccessConfirm;
var sendFlowData;
var config = null;
var configFeeLevel = '';
var countDown = null;
var defaults = {};
var coin = '';
var countDown = null;
var usingCustomFee = false;
var usingMerchantFee = false;
var destinationWalletId = '';
var originWalletId = '';
var priceDisplayIsFiat = true;
var satoshis = null;
var toAddress = '';
var destinationWalletId = '';
var tx = {};
var txPayproData = null;
var unitFromSat = 0;
var FEE_TOO_HIGH_LIMIT_PERCENTAGE = 15;
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.beforeLeave", onBeforeLeave);
$scope.$on("$ionicView.enter", onEnter);
function onBeforeEnter(event, data) {
// Dummy values for testing
vm.fee = {
cryptoAmount: '0.00195823',
cryptoCurrencyCode: 'BCH',
description: 'Less than 1 cent',
fiatAmount: '',
fiatCurrency: '',
high: false
};
originWalletId = data.stateParams.fromWalletId;
// For testing only
//originWalletId = data.stateParams.fromWalletId || 'bf00af8f-0788-4b57-b30a-0390747407e9';
satoshis = parseInt(data.stateParams.amount, 10);
toAddress = data.stateParams.toAddr;
console.log('walletSelector onBeforeEnter sendflow ', sendFlowService.state);
defaults = configService.getDefaults();
sendFlowData = sendFlowService.getStateClone();
originWalletId = sendFlowData.fromWalletId;
satoshis = parseInt(sendFlowData.amount, 10);
toAddress = sendFlowData.toAddress;
destinationWalletId = sendFlowData.toWalletId;
var originWallet = profileService.getWallet(originWalletId);
vm.origin.currency = originWallet.coin.toUpperCase();
vm.origin.color = originWallet.color;
vm.origin.name = originWallet.name;
coin = originWallet.coin;
vm.originWallet = profileService.getWallet(originWalletId);
vm.origin.currency = vm.originWallet.coin.toUpperCase();
coin = vm.originWallet.coin;
if (sendFlowData.thirdParty) {
vm.thirdParty = sendFlowData.thirdParty;
handleThirdPartyInitIfBip70();
handleThirdPartyInitIfShapeshift();
}
configService.get(function onConfig(err, configCache) {
if (err) {
@ -87,32 +100,264 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
} else {
config = configCache;
priceDisplayIsFiat = config.wallet.settings.priceDisplay === 'fiat';
vm.origin.currencyColor = originWallet.coin === 'btc' ? config.bitcoinWalletColor : config.bitcoinCashWalletColor;
vm.origin.currencyColor = (vm.originWallet.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor);
console.log("coin", vm.originWallet.coin, vm.origin.currencyColor, config.bitcoinWalletColor, vm.originWallet.coin === 'btc');
unitFromSat = 1 / config.wallet.settings.unitToSatoshi;
}
configFeeLevel = config.wallet.settings.feeLevel ? config.wallet.settings.feeLevel : 'normal';
updateSendAmounts();
getOriginWalletBalance(originWallet);
getOriginWalletBalance(vm.originWallet);
handleDestinationAsAddress(toAddress, coin);
handleDestinationAsWallet(data.stateParams.toWalletId);
handleDestinationAsWallet(sendFlowData.toWalletId);
createVanityTransaction(data);
});
}
function onBeforeLeave(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
}
function onEnter(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
vm.approve = function() {
if (!tx || !vm.originWallet) return;
if (vm.paymentExpired) {
popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.', function () {
$ionicHistory.goBack();
}));
vm.sendStatus = '';
$timeout(function() {
$scope.$apply();
});
return;
}
ongoingProcess.set('creatingTx', true, statusChangeHandler);
getTxp(lodash.clone(tx), vm.originWallet, false, function(err, txp) {
ongoingProcess.set('creatingTx', false, statusChangeHandler);
if (err) return;
// confirm txs for more that 20usd, if not spending/touchid is enabled
function confirmTx(cb) {
if (walletService.isEncrypted(vm.originWallet))
return cb();
var amountUsd = parseFloat(txFormatService.formatToUSD(vm.originWallet.coin, txp.amount));
return cb();
};
function publishAndSign() {
if (!vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal()) {
$log.info('No signing proposal: No private key');
return walletService.onlyPublish(vm.originWallet, txp, function(err) {
if (err) setSendError(err);
}, statusChangeHandler);
}
walletService.publishAndSign(vm.originWallet, txp, function(err, txp) {
if (err) return setSendError(err);
if (config.confirmedTxsNotifications && config.confirmedTxsNotifications.enabled) {
txConfirmNotification.subscribe(vm.originWallet, {
txid: txp.txid
});
}
}, statusChangeHandler);
};
confirmTx(function(nok) {
if (nok) {
vm.sendStatus = '';
$timeout(function() {
$scope.$apply();
});
return;
}
publishAndSign();
});
});
};
vm.chooseFeeLevel = function(tx, wallet) {
if (wallet.coin == 'bch') return;
if (usingMerchantFee) return;
var scope = $rootScope.$new(true);
scope.network = tx.network;
scope.feeLevel = tx.feeLevel;
scope.noSave = true;
scope.coin = vm.originWallet.coin;
if (usingCustomFee) {
scope.customFeePerKB = tx.feeRate;
scope.feePerSatByte = tx.feeRate / 1000;
}
$ionicModal.fromTemplateUrl('views/modals/chooseFeeLevel.html', {
scope: scope,
backdropClickToClose: false,
hardwareBackButtonClose: false
}).then(function(modal) {
scope.chooseFeeLevelModal = modal;
scope.openModal();
});
scope.openModal = function() {
scope.chooseFeeLevelModal.show();
};
scope.hideModal = function(newFeeLevel, customFeePerKB) {
scope.chooseFeeLevelModal.hide();
$log.debug('New fee level choosen:' + newFeeLevel + ' was:' + tx.feeLevel);
usingCustomFee = newFeeLevel == 'custom' ? true : false;
if (tx.feeLevel == newFeeLevel && !usingCustomFee) return;
tx.feeLevel = newFeeLevel;
if (usingCustomFee) tx.feeRate = parseInt(customFeePerKB);
updateTx(tx, vm.originWallet, {
clearCache: true,
dryRun: true
}, function() {});
};
};
function createVanityTransaction(data) {
console.log('createVanityTransaction()');
var configFeeLevel = config.wallet.settings.feeLevel ? config.wallet.settings.feeLevel : 'normal';
// Grab stateParams
tx = {
amount: parseInt(sendFlowData.amount),
sendMax: sendFlowData.sendMax,
fromWalletId: sendFlowData.fromWalletId,
toAddress: sendFlowData.toAddress,
paypro: txPayproData,
feeLevel: configFeeLevel,
spendUnconfirmed: config.wallet.spendUnconfirmed,
// Vanity tx info (not in the real tx)
recipientType: vm.destination.kind || null,
toName: vm.destination.name || null,
toEmail: vm.destination.email || null,
toColor: vm.destination.color || null,
network: false,
coin: vm.originWallet.coin,
txp: {},
};
if (data.stateParams.requiredFeeRate) {
vm.usingMerchantFee = true;
tx.feeRate = parseInt(data.stateParams.requiredFeeRate);
}
if (tx.coin && tx.coin === 'bch') {
tx.feeLevel = 'normal';
}
var B = tx.coin === 'bch' ? bitcoreCash : bitcore;
var networkName;
try {
if (vm.destination.kind === 'wallet') { // This is a wallet-to-wallet transfer
ongoingProcess.set('generatingNewAddress', true);
var toWallet = profileService.getWallet(destinationWalletId);
// We need an address to send to, so we ask the walletService to create a new address for the toWallet.
console.log('Getting address for wallet...');
walletService.getAddress(toWallet, true, function onWalletAddress(err, addr) {
console.log('getAddress cb called', err);
ongoingProcess.set('generatingNewAddress', false);
tx.toAddress = addr;
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
console.log('calling setupTx() for wallet.');
setupTx(tx);
});
} else { // This is a Wallet-to-address transfer
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
console.log('calling setupTx() for address.');
setupTx(tx);
}
} catch (e) {
console.error('Error setting up tx', e);
var message = gettextCatalog.getString('Invalid address');
popupService.showAlert(null, message, function () {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function () {
$ionicHistory.clearHistory();
});
});
return;
}
}
function getOriginWalletBalance(originWallet) {
var balanceText = getWalletBalanceDisplayText(originWallet);
var balanceText = getWalletBalanceDisplayText(vm.originWallet);
vm.origin.balanceAmount = balanceText.amount;
vm.origin.balanceCurrency = balanceText.currency;
}
function getSendMaxInfo(tx, wallet, cb) {
if (!tx.sendMax) return cb();
//ongoingProcess.set('retrievingInputs', true);
walletService.getSendMaxInfo(wallet, {
feePerKb: tx.feeRate,
excludeUnconfirmedUtxos: !tx.spendUnconfirmed,
returnInputs: true,
}, cb);
};
function getTxp(tx, wallet, dryRun, cb) {
// ToDo: use a credential's (or fc's) function for this
if (tx.description && !wallet.credentials.sharedEncryptingKey) {
var msg = gettextCatalog.getString('Could not add message to imported wallet without shared encrypting key');
$log.warn(msg);
return setSendError(msg);
}
if (tx.amount > Number.MAX_SAFE_INTEGER) {
var msg = gettextCatalog.getString('Amount too big');
$log.warn(msg);
return setSendError(msg);
}
var txp = {};
txp.outputs = [{
'toAddress': tx.toAddress,
'amount': tx.amount,
'message': vm.memo
}];
if (tx.sendMaxInfo) {
txp.inputs = tx.sendMaxInfo.inputs;
txp.fee = tx.sendMaxInfo.fee;
} else {
if (usingCustomFee || usingMerchantFee) {
txp.feePerKb = tx.feeRate;
} else txp.feeLevel = tx.feeLevel;
}
txp.message = vm.memo;
if (tx.paypro) {
txp.payProUrl = tx.paypro.url;
}
txp.excludeUnconfirmedUtxos = !tx.spendUnconfirmed;
txp.dryRun = dryRun;
walletService.createTx(wallet, txp, function(err, ctxp) {
if (err) {
setSendError(err);
return cb(err);
}
return cb(null, ctxp);
});
};
function getWalletBalanceDisplayText(wallet) {
var balanceCryptoAmount = '';
var balanceCryptoCurrencyCode = '';
@ -153,6 +398,10 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
};
}
function goBack() {
$ionicHistory.goBack();
}
function handleDestinationAsAddress(address, originCoin) {
if (!address) {
return;
@ -161,21 +410,24 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
// Check if the recipient is a contact
addressbookService.get(originCoin + address, function(err, contact) {
if (!err && contact) {
console.log('destination is contact');
handleDestinationAsContact(contact);
handleDestinationAsAddressOfContact(contact);
} else {
console.log('destination is address');
vm.destination.address = address;
if (originCoin === 'bch') {
vm.destination.address = bitcoinCashJsService.readAddress(address).cashaddr;
} else {
vm.destination.address = address;
}
vm.destination.kind = 'address';
}
});
}
function handleDestinationAsContact(contact) {
function handleDestinationAsAddressOfContact(contact) {
vm.destination.kind = 'contact';
vm.destination.name = contact.name;
vm.destination.color = contact.coin === 'btc' ? config.bitcoinWalletColor : config.bitcoinCashWalletColor;
vm.destination.email = contact.email;
vm.destination.color = contact.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor;
vm.destination.currency = contact.coin.toUpperCase();
vm.destination.currencyColor = vm.destination.color;
}
@ -186,7 +438,6 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
return;
}
console.log('destination is wallet');
var destinationWallet = profileService.getWallet(destinationWalletId);
vm.destination.coin = destinationWallet.coin;
vm.destination.color = destinationWallet.color;
@ -194,8 +445,8 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
vm.destination.kind = 'wallet';
vm.destination.name = destinationWallet.name;
if (config) {
vm.destination.currencyColor = vm.destination.coin === 'btc' ? config.bitcoinWalletColor : config.bitcoinCashWalletColor;
if (defaults) {
vm.destination.currencyColor = vm.destination.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor;
}
var balanceText = getWalletBalanceDisplayText(destinationWallet);
@ -203,6 +454,108 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
vm.destination.balanceCurrency = balanceText.currency;
}
function handleThirdPartyInitIfBip70() {
if (vm.thirdParty.id === 'bip70') {
vm.sendingTitle = gettextCatalog.getString('You are paying');
vm.memo = vm.thirdParty.memo;
vm.memoExpanded = !!vm.memo;
vm.destination.name = vm.thirdParty.name;
txPayproData = {
caTrusted: vm.thirdParty.caTrusted,
domain: vm.thirdParty.domain,
expires: vm.thirdParty.expires,
toAddress: toAddress,
url: vm.thirdParty.url,
verified: vm.thirdParty.verified,
};
}
}
function handleThirdPartyInitIfShapeshift() {
if (vm.thirdParty.id === 'shapeshift') {
vm.sendingTitle = gettextCatalog.getString('You are shifting');
if (!vm.thirdParty.data) {
vm.thirdParty.data = {};
}
var toWallet = profileService.getWallet(destinationWalletId);
vm.destination.name = toWallet.name;
vm.destination.color = toWallet.color;
vm.destination.currency = toWallet.coin.toUpperCase();
ongoingProcess.set('connectingShapeshift', true);
walletService.getAddress(vm.originWallet, false, function onReturnWalletAddress(err, returnAddr) {
if (err) {
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
return;
}
walletService.getAddress(toWallet, false, function onWithdrawalWalletAddress(err, withdrawalAddr) {
if (err) {
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
return;
}
shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function onShiftIt(err, shapeshiftData) {
if (err && err != null) {
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
} else {
vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId;
vm.memoExpanded = !!vm.memo;
tx.toAddress = shapeshiftData.toAddress;
vm.destination.address = toAddress;
vm.destination.kind = 'shapeshift';
}
});
});
});
}
}
function startExpirationTimer(expirationTime) {
vm.paymentExpired = false;
setExpirationTime();
countDown = $interval(function() {
setExpirationTime();
}, 1000);
function setExpirationTime() {
console.log('setExpirationTime()');
var now = Math.floor(Date.now() / 1000);
if (now > expirationTime) {
setExpiredValues();
return;
}
var totalSecs = expirationTime - now;
var m = Math.floor(totalSecs / 60);
var s = totalSecs % 60;
vm.remainingTimeStr = m + ":" + ('0' + s).slice(-2);
};
function setExpiredValues() {
vm.paymentExpired = true;
vm.remainingTimeStr = gettextCatalog.getString('Expired');
vm.readyToSend = false;
if (countDown) $interval.cancel(countDown);
$timeout(function() {
$scope.$apply();
});
};
};
function updateSendAmounts() {
if (typeof satoshis !== 'number') {
return;
@ -246,4 +599,315 @@ function reviewController(addressbookService, configService, $ionicConfig, $log,
});
}
function onSuccessConfirm() {
vm.sendStatus = '';
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
$state.transitionTo('tabs.home');
});
};
function setButtonText(isMultisig, isPayPro) {
if (isPayPro) {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to pay');
} else {
vm.buttonText = gettextCatalog.getString('Click to pay');
}
} else if (isMultisig) {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to accept');
} else {
vm.buttonText = gettextCatalog.getString('Click to accept');
}
} else {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to send');
} else {
vm.buttonText = gettextCatalog.getString('Click to send');
}
}
}
function setNotReady(msg, criticalError) {
vn.readyToSend = false;
vm.notReadyMessage = msg;
$scope.criticalError = criticalError;
$log.warn('Not ready to make the payment:' + msg);
$timeout(function() {
$scope.$apply();
});
};
function setSendError(msg) {
$scope.sendStatus = '';
vm.readyToSend = false;
$timeout(function() {
$scope.$apply();
});
popupService.showAlert(gettextCatalog.getString('Error at confirm'), bwcError.msg(msg), function () {
$ionicHistory.goBack();
});
};
function setupTx(tx) {
if (tx.coin === 'bch') {
tx.displayAddress = bitcoinCashJsService.readAddress(tx.toAddress).cashaddr;
} else {
tx.displayAddress = tx.toAddress;
}
addressbookService.get(tx.coin+tx.toAddress, function(err, addr) { // Check if the recipient is a contact
if (!err && addr) {
tx.toName = addr.name;
tx.toEmail = addr.email;
tx.recipientType = 'contact';
}
});
vm.showAddress = false;
setButtonText(vm.originWallet.credentials.m > 1, !!tx.paypro);
if (tx.paypro)
startExpirationTimer(tx.paypro.expires);
updateTx(tx, vm.originWallet, {
dryRun: true
}, function(err) {
$timeout(function() {
$scope.$apply();
}, 10);
});
// setWalletSelector(tx.coin, tx.network, tx.amount, function(err) {
// if (err) {
// return exitWithError('Could not update wallets');
// }
//
// if (vm.wallets.length > 1) {
// vm.showWalletSelector();
// } else if (vm.wallets.length) {
// setWallet(vm.wallets[0], tx);
// }
// });
}
function showSendMaxWarning(wallet, sendMaxInfo) {
var feeAlternative = '',
msg = '';
function verifyExcludedUtxos() {
var warningMsg = [];
if (sendMaxInfo.utxosBelowFee > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
amountBelowFeeStr: txFormatService.formatAmountStr(wallet.coin, sendMaxInfo.amountBelowFee)
}));
}
if (sendMaxInfo.utxosAboveMaxSize > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded.", {
amountAboveMaxSizeStr: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.amountAboveMaxSize)
}));
}
return warningMsg.join('\n');
};
feeAlternative = txFormatService.formatAlternativeStr(vm.originWallet.coin, sendMaxInfo.fee);
if (feeAlternative) {
msg = gettextCatalog.getString("{{feeAlternative}} will be deducted for bitcoin networking fees ({{fee}}).", {
fee: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.fee),
feeAlternative: feeAlternative
});
} else {
msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees).", {
fee: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.fee)
});
}
var warningMsg = verifyExcludedUtxos();
if (!lodash.isEmpty(warningMsg))
msg += '\n' + warningMsg;
popupService.showAlert(null, msg, function() {});
};
function statusChangeHandler(processName, showName, isOn) {
$log.debug('statusChangeHandler: ', processName, showName, isOn);
if (
(
processName === 'broadcastingTx' ||
((processName === 'signingTx') && vm.originWallet.m > 1) ||
(processName == 'sendingTx' && !vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal())
) && !isOn) {
vm.sendStatus = 'success';
if ($state.current.name === "tabs.send.review") { // XX SP: Otherwise all open wallets on other devices play this sound if you have been in a send flow before on that device.
soundService.play('misc/payment_sent.mp3');
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
}
// When displaying Fiat, if the formatting fails, the crypto will be the primary amount.
var amount = unitFromSat * satoshis;
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": vm.originWallet.coin,
"type": "outgoing",
"amount": amount,
"fees": vm.feeCrypto
}], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
$timeout(function() {
$scope.$digest();
}, 100);
} else if (showName) {
vm.sendStatus = showName;
}
};
function updateTx(tx, wallet, opts, cb) {
ongoingProcess.set('calculatingFee', true);
if (opts.clearCache) {
tx.txp = {};
}
// $scope.tx = tx;
// function updateAmount() {
// if (!tx.amount) return;
//
// // Amount
// tx.amountStr = txFormatService.formatAmountStr(originWallet.coin, tx.amount);
// tx.amountValueStr = tx.amountStr.split(' ')[0];
// tx.amountUnitStr = tx.amountStr.split(' ')[1];
// txFormatService.formatAlternativeStr(wallet.coin, tx.amount, function(v) {
// var parts = v.split(' ');
// tx.alternativeAmountStr = v;
// tx.alternativeAmountValueStr = parts[0];
// tx.alternativeAmountUnitStr = (parts.length > 0) ? parts[1] : '';
// });
// }
//
// updateAmount();
// refresh();
var feeServiceLevel = usingMerchantFee && vm.originWallet.coin == 'btc' ? 'urgent' : tx.feeLevel;
feeService.getFeeRate(vm.originWallet.coin, tx.network, feeServiceLevel, function(err, feeRate) {
if (err) {
ongoingProcess.set('calculatingFee', false);
return cb(err);
}
var msg;
if (usingCustomFee) {
msg = gettextCatalog.getString('Custom');
tx.feeLevelName = msg;
} else if (usingMerchantFee) {
$log.info('Using Merchant Fee:' + tx.feeRate + ' vs. Urgent level:' + feeRate);
msg = gettextCatalog.getString('Suggested by Merchant');
tx.feeLevelName = msg;
} else {
tx.feeLevelName = feeService.feeOpts[tx.feeLevel];
tx.feeRate = feeRate;
}
getSendMaxInfo(lodash.clone(tx), wallet, function(err, sendMaxInfo) {
if (err) {
ongoingProcess.set('calculatingFee', false);
var msg = gettextCatalog.getString('Error getting SendMax information');
return setSendError(msg);
}
if (sendMaxInfo) {
$log.debug('Send max info', sendMaxInfo);
if (tx.sendMax && sendMaxInfo.amount == 0) {
ongoingProcess.set('calculatingFee', false);
setNotReady(gettextCatalog.getString('Insufficient confirmed funds'));
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'), function () {
$ionicHistory.goBack();
});
return cb('no_funds');
}
tx.sendMaxInfo = sendMaxInfo;
tx.amount = tx.sendMaxInfo.amount;
satoshis = tx.amount;
updateSendAmounts();
ongoingProcess.set('calculatingFee', false);
$timeout(function() {
showSendMaxWarning(wallet, sendMaxInfo);
}, 200);
}
// txp already generated for this wallet?
if (tx.txp[wallet.id]) {
ongoingProcess.set('calculatingFee', false);
vm.readyToSend = true;
updateSendAmounts();
$scope.$apply();
return cb();
}
console.log('calling getTxp() from getSendMaxInfo cb.');
getTxp(lodash.clone(tx), wallet, opts.dryRun, function(err, txp) {
ongoingProcess.set('calculatingFee', false);
if (err) {
if (err.message == 'Insufficient funds') {
setNotReady(gettextCatalog.getString('Insufficient funds'));
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'));
return cb('no_funds');
} else
return cb(err);
}
txp.feeStr = txFormatService.formatAmountStr(wallet.coin, txp.fee);
txFormatService.formatAlternativeStr(wallet.coin, txp.fee, function(v) {
// txp.alternativeFeeStr = v;
// if (txp.alternativeFeeStr.substring(0, 4) == '0.00')
// txp.alternativeFeeStr = '< ' + txp.alternativeFeeStr;
vm.feeFiat = v;
vm.fiatCurrency = config.wallet.settings.alternativeIsoCode;
if (v.substring(0, 1) === "<") {
vm.feeLessThanACent = true;
}
console.log("fiat", vm.feeFiat);
});
var per = (txp.fee / (txp.amount + txp.fee) * 100);
var perString = per.toFixed(2);
txp.feeRatePerStr = (perString == '0.00' ? '< ' : '') + perString + '%';
txp.feeToHigh = per > FEE_TOO_HIGH_LIMIT_PERCENTAGE;
vm.feeCrypto = (unitFromSat * txp.fee).toFixed(8);
vm.feeIsHigh = txp.feeToHigh;
console.log("crypto", vm.feeCrypto);
tx.txp[wallet.id] = txp;
$log.debug('Confirm. TX Fully Updated for wallet:' + wallet.id, tx);
vm.readyToSend = true;
updateSendAmounts();
console.log('readyToSend:', vm.readyToSend);
$scope.$apply();
return cb();
});
});
});
}
}

View file

@ -1,7 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, $interval, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, sendFlowService, $state, $timeout, $ionicHistory, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
var walletsBtc = [];
var walletsBch = [];
@ -16,24 +15,9 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
}
function showToWallets() {
$scope.toWallets = $scope.fromWallet.coin == 'btc' ? walletsBch : walletsBtc;
$scope.toWallets = $scope.fromWallet.coin === 'btc' ? walletsBch : walletsBtc;
$scope.onToWalletSelect($scope.toWallets[0]);
$scope.singleToWallet = $scope.toWallets.length == 1;
}
$scope.onFromWalletSelect = function(wallet) {
$scope.fromWallet = wallet;
showToWallets();
generateAddress(wallet, function(addr) {
$scope.fromWalletAddress = addr;
});
};
$scope.onToWalletSelect = function(wallet) {
$scope.toWallet = wallet;
generateAddress(wallet, function(addr) {
$scope.toWalletAddress = addr;
});
$scope.singleToWallet = $scope.toWallets.length === 1;
}
$scope.$on("$ionicView.beforeEnter", function(event, data) {
@ -42,15 +26,15 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
$scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) {
return w.status.balance.availableAmount > 0;
});
if ($scope.fromWallets.length == 0) return;
$scope.onFromWalletSelect($scope.fromWallets[0]);
$scope.onToWalletSelect($scope.toWallets[0]);
$scope.singleFromWallet = $scope.fromWallets.length == 1;
$scope.singleToWallet = $scope.toWallets.length == 1;
$scope.singleFromWallet = $scope.fromWallets.length === 1;
$scope.fromWalletSelectorTitle = 'From';
$scope.toWalletSelectorTitle = 'To';
$scope.showFromWallets = false;
$scope.showToWallets = false;
$scope.walletsWithFunds = profileService.getWallets({onlyComplete: true, hasFunds: true});
$scope.wallets = profileService.getWallets({onlyComplete: true});
$scope.hasWallets = !lodash.isEmpty($scope.wallets);
});
$scope.$on("$ionicView.enter", function(event, data) {
@ -59,9 +43,42 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
$scope.showFromWalletSelector = function() {
$scope.showFromWallets = true;
}
};
$scope.showToWalletSelector = function() {
$scope.showToWallets = true;
};
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.add.create-personal');
});
};
$scope.buyBitcoin = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.buyandsell');
});
};
$scope.shapeshift = function() {
var stateParams = {
thirdParty: {
id: 'shapeshift'
}
};
// Starting new send flow, so ensure everything is reset
sendFlowService.clear();
$state.go('tabs.home').then(function() {
$ionicHistory.clearHistory();
$state.go('tabs.send').then(function() {
$timeout(function () {
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 60);
});
});
}
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('tabHomeController',
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, communityService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, sendFlowService, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
var wallet;
var listeners = [];
var notifications = [];
@ -20,7 +20,12 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = '';
$scope.$on("$ionicView.afterEnter", function() {
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
$scope.$on("$ionicView.afterEnter", onAfterEnter);
$scope.$on("$ionicView.leave", onLeave);
function onAfterEnter () {
startupService.ready();
bannerService.getBanner(function (banner) {
@ -28,9 +33,10 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = banner.url;
$scope.bannerIsLoading = false;
});
});
};
function onBeforeEnter (event, data) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
if (!$scope.homeTip) {
storageService.getHomeTipAccepted(function(error, value) {
$scope.homeTip = (value == 'accepted') ? false : true;
@ -51,9 +57,9 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
});
}
});
};
$scope.$on("$ionicView.enter", function(event, data) {
function onEnter(event, data) {
$ionicNavBarDelegate.showBar(true);
updateAllWallets();
@ -97,26 +103,29 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
$scope.showServices = true;
pushNotificationsService.init();
firebaseEventsService.init();
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 10);
});
});
};
$scope.$on("$ionicView.leave", function(event, data) {
function onLeave (event, data) {
lodash.each(listeners, function(x) {
x();
});
});
};
$scope.createdWithinPastDay = function(time) {
return timeService.withinPastDay(time);
};
$scope.startFreshSend = function() {
sendFlowService.clear();
$state.go('tabs.send');
}
$scope.openExternalLink = function() {
var url = 'https://github.com/Bitcoin-com/Wallet/releases/latest';
var optIn = true;
@ -205,6 +214,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
var j = 0;
lodash.each(wallets, function(wallet) {
walletService.invalidateCache(wallet); // Temporary solution, to have the good balance, when we ask to reload the wallets.
walletService.getStatus(wallet, {}, function(err, status) {
if (err) {
@ -224,6 +234,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
cb();
}
}
$scope.walletsWithFunds = profileService.getWallets({hasFunds: true});
});
});
};

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, txFormatService, soundService, clipboardService) {
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, sendFlowService, txFormatService, soundService, clipboardService) {
var listeners = [];
$scope.bchAddressType = { type: 'cashaddr' };
@ -18,10 +18,10 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.displayBalanceAsFiat = true;
$scope.requestSpecificAmount = function() {
$state.go('tabs.paymentRequest.amount', {
id: $scope.wallet.credentials.walletId,
coin: $scope.wallet.coin
sendFlowService.pushState({
toWalletId: $scope.wallet.credentials.walletId
});
$state.go('tabs.paymentRequest.amount');
};
$scope.setAddress = function(newAddr, copyAddress) {
@ -145,9 +145,9 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
}
$scope.paymentReceivedCoin = $scope.wallet.coin;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -159,6 +159,10 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
soundService.play('misc/payment_received.mp3');
}
// Notify new tx
$scope.$emit('bwsEvent', $scope.wallet.id);
$scope.$apply(function () {
$scope.showingPaymentReceived = true;
});
@ -233,10 +237,14 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
if (!$scope.wallets[0]) return;
// select first wallet if no wallet selected previously
var selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
var selectedWallet = null;
if (data.stateParams.walletId) { // from walletDetails
selectedWallet = checkSelectedWallet(profileService.getWallet(data.stateParams.walletId), $scope.wallets);
} else {
// select first wallet if no wallet selected previously
selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
}
$scope.onWalletSelect(selectedWallet);
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
listeners = [

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) {
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, sendFlowService, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) {
var clipboardHasAddress = false;
var clipboardHasContent = false;
var originalList;
@ -28,6 +28,10 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.$on("$ionicView.enter", function(event, data) {
var stateParams = sendFlowService.getStateClone();
$scope.fromWallet = profileService.getWallet(stateParams.fromWalletId);
clipboardService.readFromClipboard(function(text) {
if (text.length > 200) {
text = text.substring(0, 200);
@ -55,42 +59,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
});
});
var wallets;
var walletsBch;
var walletsBtc;
var walletToWalletFrom = false;
$scope.onWalletSelect = function(wallet) {
if (!$scope.walletToWalletFrom) {
$scope.walletToWalletFrom = wallet;
if (wallet.coin === 'bch') {
$scope.showWalletsBch = true;
} else if (wallet.coin === 'btc') {
$scope.showWalletsBtc = true;
}
$scope.walletSelectorTitleTo = gettextCatalog.getString('Send to');
} else {
$ionicLoading.show();
walletService.getAddress(wallet, true, function(err, addr) {
$ionicLoading.hide();
return $state.transitionTo('tabs.send.amount', {
displayAddress: $scope.walletToWalletFrom.coin === 'bch' ? bitcoinCashJsService.translateAddresses(addr).cashaddr : addr,
recipientType: 'wallet',
fromWalletId: $scope.walletToWalletFrom.id,
toAddress: addr,
coin: $scope.walletToWalletFrom.coin
});
});
}
};
$scope.showWalletSelector = function() {
$scope.walletToWalletFrom = false;
$scope.walletSelectorTitleFrom = gettextCatalog.getString('Send from');
$scope.showWallets = true;
};
$scope.findContact = function(search) {
if (incomingData.redir(search)) {
@ -133,7 +101,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
var updateHasFunds = function() {
$scope.hasFunds = false;
var index = 0;
lodash.each($scope.wallets, function(w) {
@ -179,10 +146,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
coin: v.coin,
displayCoin: (v.coin == 'bch'
? (config.bitcoinCashAlias || defaults.bitcoinCashAlias)
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase(),
getAddress: function(cb) {
return cb(null, k);
},
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase()
});
});
originalList = completeContacts;
@ -203,39 +167,46 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.searchBlurred = function() {
if ($scope.formData.search == null || $scope.formData.search.length == 0) {
if ($scope.formData.search == null || $scope.formData.search.length === 0) {
$scope.searchFocus = false;
}
};
$scope.goToAmount = function(item) {
$timeout(function() {
item.getAddress(function(err, addr) {
if (err || !addr) {
//Error is already formated
return popupService.showAlert(err);
}
$scope.sendToContact = function (item) {
$timeout(function () {
var toAddress = item.address;
if (item.recipientType && item.recipientType == 'contact') {
if (addr.indexOf('bch') == 0 || addr.indexOf('btc') == 0) {
addr = addr.substring(3);
}
if (item.recipientType && item.recipientType === 'contact') {
if (toAddress.indexOf('bch') === 0 || toAddress.indexOf('btc') === 0) {
toAddress = toAddress.substring(3);
}
}
$log.debug('Got toAddress:' + toAddress + ' | ' + item.name);
var stateParams = sendFlowService.getStateClone();
stateParams.toAddress = toAddress,
stateParams.coin = item.coin;
sendFlowService.pushState(stateParams);
if (!stateParams.fromWalletId) { // If we have no toAddress or fromWallet
$state.transitionTo('tabs.send.origin');
} else {
$state.transitionTo('tabs.send.amount');
}
$log.debug('Got toAddress:' + addr + ' | ' + item.name);
return $state.transitionTo('tabs.send.amount', {
recipientType: item.recipientType,
displayAddress: item.coin == 'bch' ? bitcoinCashJsService.translateAddresses(addr).cashaddr : addr,
toAddress: addr,
toName: item.name,
toEmail: item.email,
toColor: item.color,
coin: item.coin
});
});
});
};
$scope.startWalletToWalletTransfer = function() {
console.log('startWalletToWalletTransfer()');
var params = sendFlowService.getStateClone();
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.wallet-to-wallet', {
fromWalletId: sendFlowService.fromWalletId
});
}
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
@ -250,6 +221,8 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
console.log(data);
console.log('tab-send onBeforeEnter sendflow ', sendFlowService.state);
$scope.isIOS = platformInfo.isIOS && platformInfo.isCordova;
$scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false;
@ -264,5 +237,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
});
if (data.direction == "back") {
sendFlowService.clear();
}
});
});
});

View file

@ -16,7 +16,7 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
isoCode: config.wallet.settings.alternativeIsoCode
};
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay === 'crypto' ? gettextCatalog.getString('Cryptocurrency') : gettextCatalog.getString('Fiat');
// TODO move this to a generic service
bitpayAccountService.getAccounts(function(err, data) {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingData, lodash, popupService, gettextCatalog, scannerService) {
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingData, lodash, popupService, gettextCatalog, scannerService, sendFlowService) {
$scope.onScan = function(data) {
if (!incomingData.redir(data)) {
@ -15,6 +15,11 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
};
$scope.startFreshSend = function() {
sendFlowService.clear();
$state.go('tabs.send');
};
$scope.importInit = function() {
$scope.fromOnboarding = $stateParams.fromOnboarding;
$timeout(function() {
@ -23,7 +28,7 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
$scope.chooseScanner = function() {
sendFlowService.clear();
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
if (!isWindowsPhoneApp) {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService) {
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, sendFlowService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService) {
var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage = 0;
@ -12,9 +12,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIOS = platformInfo.isIOS;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
@ -304,9 +304,13 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
};
function refreshAmountSection(scrollPos) {
var AMOUNT_HEIGHT_BASE = 210;
$scope.showBalanceButton = false;
if ($scope.status) {
$scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount);
if ($scope.showBalanceButton) {
AMOUNT_HEIGHT_BASE = 270;
}
}
if (!$scope.amountIsCollapsible) {
var t = ($scope.showBalanceButton ? 15 : 45);
@ -315,16 +319,16 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}
scrollPos = scrollPos || 0;
var amountHeight = 210 - scrollPos;
var amountHeight = AMOUNT_HEIGHT_BASE - scrollPos;
if (amountHeight < 80) {
amountHeight = 80;
}
var contentMargin = amountHeight;
if (contentMargin > 210) {
contentMargin = 210;
if (contentMargin > AMOUNT_HEIGHT_BASE) {
contentMargin = AMOUNT_HEIGHT_BASE;
}
var amountScale = (amountHeight / 210);
var amountScale = (amountHeight / AMOUNT_HEIGHT_BASE);
if (amountScale < 0.5) {
amountScale = 0.5;
}
@ -342,9 +346,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
top = TOP_BALANCE_BUTTON;
}
var amountTop = ((amountScale - 0.7) / 0.7) * top;
if (amountTop < -10) {
amountTop = -10;
var amountTop = ((amountScale - 0.80) / 0.80) * top;
if (amountTop < -2) {
amountTop = -2;
}
if (amountTop > top) {
amountTop = top;
@ -353,6 +357,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var t = amountTop;
$scope.altAmountOpacity = (amountHeight - 100) / 80;
$scope.buttonsOpacity = (amountHeight - 140) / 70;
$window.requestAnimationFrame(function() {
$scope.amountHeight = amountHeight + 'px';
$scope.contentMargin = contentMargin + 'px';
@ -373,6 +378,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
sendFlowService.clear();
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
@ -469,4 +475,36 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
$scope.goToSend = function() {
sendFlowService.startSend({
fromWalletId: $scope.wallet.id
});
// Go home first so that the Home tab works properly
$state.go('tabs.home').then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.send');
});
};
$scope.goToReceive = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.receive', {
walletId: $scope.wallet.id
});
});
};
$scope.goToBuy = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.buyandsell');
});
};
});

View file

@ -0,0 +1,210 @@
'use strict';
angular.module('copayApp.controllers').controller('walletSelectorController', function($scope, $rootScope, $state, $log, $ionicHistory, sendFlowService, configService, gettextCatalog, profileService, txFormatService) {
var fromWalletId = '';
var priceDisplayAsFiat = false;
var unitDecimals = 0;
var unitsFromSatoshis = 0;
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
function onBeforeEnter(event, data) {
if (data.direction == "back") {
sendFlowService.popState();
}
console.log('walletSelector onBeforeEnter after back sendflow', sendFlowService.state);
$scope.params = sendFlowService.getStateClone();
var config = configService.getSync().wallet.settings;
priceDisplayAsFiat = config.priceDisplay === 'fiat';
unitDecimals = config.unitDecimals;
unitsFromSatoshis = 1 / config.unitToSatoshi;
switch($state.current.name) {
case 'tabs.send.wallet-to-wallet':
$scope.sendFlowTitle = gettextCatalog.getString('Transfer between wallets');
break;
case 'tabs.send.destination':
if ($scope.params.fromWalletId && !$scope.params.thirdParty) {
$scope.sendFlowTitle = gettextCatalog.getString('Transfer between wallets');
}
break;
default:
if (!$scope.params.thirdParty) {
$scope.sendFlowTitle = gettextCatalog.getString('Send');
}
// nop
}
$scope.coin = false; // Wallets to show (for destination screen or contacts)
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
fromWalletId = $scope.params['fromWalletId'];
if ($scope.type === 'destination' && $scope.params.toAddress) {
$state.transitionTo(getNextStep($scope.params));
}
if ($scope.params.coin) {
$scope.coin = $scope.params.coin; // Contacts have a coin embedded
}
if ($scope.params.amount) { // There is an amount, so presume that it is a payment request
$scope.sendFlowTitle = gettextCatalog.getString('Payment Request');
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isPaymentRequest = true;
}
if ($scope.params.thirdParty) {
$scope.thirdParty = $scope.params.thirdParty;
}
};
function onEnter (event, data) {
configService.whenAvailable(function(config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
});
if ($scope.thirdParty) {
// Third party services specific logic
handleThirdPartyIfShapeshift();
}
prepareWalletLists();
formatRequestedAmount();
};
function formatRequestedAmount() {
if ($scope.params.amount) {
var cryptoAmount = (unitsFromSatoshis * $scope.params.amount).toFixed(unitDecimals);
var cryptoCoin = $scope.coin.toUpperCase();
txFormatService.formatAlternativeStr($scope.coin, $scope.params.amount, function onFormatAlternativeStr(formatted){
if (formatted) {
var fiatParts = formatted.split(' ');
var fiatAmount = fiatParts[0];
var fiatCurrrency = fiatParts.length > 1 ? fiatParts[1] : '';
if (priceDisplayAsFiat) {
$scope.requestAmount = fiatAmount;
$scope.requestCurrency = fiatCurrrency;
$scope.requestAmountSecondary = cryptoAmount;
$scope.requestCurrencySecondary = cryptoCoin;
} else {
$scope.requestAmount = cryptoAmount;
$scope.requestCurrency = cryptoCoin;
$scope.requestAmountSecondary = fiatAmount;
$scope.requestCurrencySecondary = fiatCurrrency;
}
}
});
}
}
function getNextStep(params) {
if (!params.toWalletId && !params.toAddress) { // If we have no toAddress or fromWallet
return 'tabs.send.destination';
} else if (!params.amount) { // If we have no amount
return 'tabs.send.amount';
} else { // If we do have them
return 'tabs.send.review';
}
}
function handleThirdPartyIfShapeshift() {
console.log($scope.thirdParty, $scope.coin);
if ($scope.thirdParty.id === 'shapeshift' && $scope.type === 'destination') { // Shapeshift wants to know the
$scope.coin = profileService.getWallet(fromWalletId).coin;
if ($scope.coin === 'bch') {
$scope.coin = 'btc';
} else {
$scope.coin = 'bch';
}
}
}
function prepareWalletLists() {
var walletsAll = [];
var walletsSufficientFunds = [];
$scope.walletsInsufficientFunds = []; // For origin screen
if ($scope.type === 'origin') {
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from');
if ($scope.params.amount) {
walletsAll = profileService.getWallets({coin: $scope.coin});
walletsAll.forEach(function forWallet(wallet){
if (wallet.status.availableBalanceSat > $scope.params.amount) {
walletsSufficientFunds.push(wallet);
} else {
$scope.walletsInsufficientFunds.push(wallet);
}
});
if ($scope.coin === 'btc') {
$scope.walletsBtc = walletsSufficientFunds;
} else {
$scope.walletsBch = walletsSufficientFunds;
}
} else if ($scope.coin) {
walletsAll = profileService.getWallets({coin: $scope.coin});
walletsAll.forEach(function forWallet(wallet){
if (wallet.status.availableBalanceSat > 0) {
walletsSufficientFunds.push(wallet);
} else {
$scope.walletsInsufficientFunds.push(wallet);
}
});
if ($scope.coin === 'btc') {
$scope.walletsBtc = walletsSufficientFunds;
} else {
$scope.walletsBch = walletsSufficientFunds;
}
} else {
$scope.walletsBch = profileService.getWallets({coin: 'bch', hasFunds: true});
$scope.walletsBtc = profileService.getWallets({coin: 'btc', hasFunds: true});
$scope.walletsInsufficientFunds = profileService.getWallets({coin: $scope.coin, hasNoFunds: true});
}
} else if ($scope.type === 'destination') {
if (!$scope.coin) { // Allow for the coin to be set by a third party
$scope.fromWallet = profileService.getWallet(fromWalletId);
$scope.coin = $scope.fromWallet.coin; // Only show wallets with the select origin wallet coin
}
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send to');
if ($scope.coin === 'btc') { // if no specific coin is set or coin is set btc
$scope.walletsBtc = profileService.getWallets({coin: $scope.coin});
} else {
$scope.walletsBch = profileService.getWallets({coin: $scope.coin});
}
}
}
$scope.useWallet = function(wallet) {
var params = sendFlowService.getStateClone();
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
params.fromWalletId = wallet.id;
} else { // we're on the destination screen, set wallet to send to
params.toWalletId = wallet.id;
}
sendFlowService.pushState(params);
var nextStep = getNextStep(params);
console.log('walletSelector nextStep', nextStep);
$state.transitionTo(nextStep, $scope.params);
};
$scope.goBack = function() {
$ionicHistory.goBack();
}
});

View file

@ -1,92 +0,0 @@
'use strict';
/**
* @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false.
* @example fee = {
* value: 12.49382901,
* currency: 'BCH'
* }
* @example <amount value="fee.value" currency="fee.currency"></amount>
* @example <amount value="fee.value" currency="fee.currency" size-equal="true"></amount>
*/
angular.module('bitcoincom.directives')
.directive('amount', [
'$timeout',
function($timeout) {
return {
restrict: 'E',
scope: {
value: '=',
currency: '=',
sizeEqual: '='
},
templateUrl: 'views/includes/amount.html',
controller: ['$scope', function($scope) {
$scope.displaySizeEqual = typeof $scope.sizeEqual == 'undefined' ? false : true;
var decimalPlaces = {
'0': ['BIF', 'CLP', 'DJF', 'GNF', 'ILS', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'],
'3': ['BHD', 'IQD', 'JOD', 'KWD', 'OMR', 'TND'],
'8': ['BCH', 'BTC']
};
var numberWithCommas = function(x) {
return parseFloat(x).toLocaleString();
};
var buildAmount = function(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
var getDecimalPlaces = function(currency) {
if (decimalPlaces['0'].indexOf($scope.currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf($scope.currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf($scope.currency.toUpperCase()) > -1) return '8';
return '2';
};
var formatNumbers = function(currency, value) {
switch (getDecimalPlaces(currency)) {
case '0':
var valueFormatted = numberWithCommas(Math.round(parseFloat(value)));
buildAmount(valueFormatted, '', '');
break;
case '2':
var valueProcessing = parseFloat(parseFloat(value).toFixed(2));
var valueFormatted = numberWithCommas(valueProcessing);
buildAmount(valueFormatted, '', '');
break;
case '3':
var valueProcessing = parseFloat(parseFloat(value).toFixed(3));
var valueFormatted = numberWithCommas(valueProcessing);
buildAmount(valueFormatted, '', '');
break;
case '8':
var valueFormatted = parseFloat(value).toFixed(8);
if (parseFloat(value) == 0) {
buildAmount('0', '', '');
} else {
buildAmount(valueFormatted, '', '');
var start = numberWithCommas(valueFormatted.slice(0, -5));
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
}
}
formatNumbers($scope.currency, $scope.value);
$scope.$watchGroup(['currency', 'value'], function() {
formatNumbers($scope.currency, $scope.value);
});
}]
};
}
]);

View file

@ -0,0 +1,198 @@
'use strict';
(function(){
/**
* @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false.
* @example fee = {
* value: 12.49382901,
* currency: 'BCH'
* }
* @example <formatted-amount value="fee.value" currency="fee.currency"></formatted-amount>
* @example <formatted-amount value="fee.value" currency="fee.currency" size-equal="true"></formatted-amount>
*/
angular
.module('bitcoincom.directives')
.directive('formattedAmount', function() {
return {
restrict: 'E',
scope: {
value: '@',
currency: '@',
sizeEqual: '@'
},
templateUrl: 'views/includes/formatted-amount.html',
controller: formattedAmountController
}
});
function formattedAmountController($scope, uxLanguage) {
$scope.vm = {};
var vm = $scope.vm;
vm.currency = '';
vm.value = '';
$scope.canShow = false
$scope.displaySizeEqual = !!$scope.sizeEqual;
var decimalPlaces = {
'0': ['BIF', 'CLP', 'DJF', 'GNF', 'ILS', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'],
'3': ['BHD', 'IQD', 'JOD', 'KWD', 'OMR', 'TND'],
'8': ['BCH', 'BTC']
};
$scope.$watch('value', function onFormattedAmountWatch() {
formatNumbers();
});
function buildAmount(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
/**
* On Android 4.4, toLocaleString() only returns 3 fractional digits when 8 is specified.
*/
function ensureEnoughFractionDigits(localizedString, number, desiredFractionDigits) {
if (desiredFractionDigits === 0) {
// Assume it is OK
return localizedString;
}
var fractionalRe = /^-*(\d*\D)(\d+)$/;
var match = fractionalRe.exec(localizedString);
if (!match || match.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
var decimals = match[2];
var decimalCount = decimals.length;
if (decimalCount >= desiredFractionDigits) {
// Everything is OK.
return localizedString;
}
if (typeof number !== 'number') {
number = parseFloat(number);
}
var fixed = number.toFixed(desiredFractionDigits);
var fixedMatch = fractionalRe.exec(fixed);
if (!fixedMatch || fixedMatch.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
// Keeps locale decimal separator.
var enough = match[1] + fixedMatch[2];
return enough;
}
function formatNumbers() {
// Might get "< 0.01 USD" being passed in.
// During watch, may be changed from having a separate currency value,
// to both being in value. Don't want to use previous currency value.
// Try to extract currency from value..
if (!$scope.currency || $scope.currency.length === 0) {
var currencySplit = $scope.value.split(" ");
if (currencySplit.length >= 2) {
vm.currency = currencySplit[currencySplit.length - 1];
}
} else {
vm.currency = $scope.currency;
}
// Redo this when we have proper formatting for low fees
if ($scope.value.indexOf("<") === 0) {
buildAmount($scope.value, '', '');
vm.currency = '';
$scope.canShow = true;
return;
}
// Remove thousands separators for parseFloat()
$scope.value = $scope.value.replace(',', '');
var parsed = parseFloat($scope.value);
var valueFormatted = '';
var valueProcessing = '';
switch (getDecimalPlaces(vm.currency)) {
case '0':
if (isNaN(parsed)) {
buildAmount('-', '', '');
} else {
valueFormatted = localizeNumbers(Math.round(parsed), 0);
buildAmount(valueFormatted, '', '');
}
break;
case '3':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else {
valueProcessing = parsed.toFixed(3);
valueFormatted = localizeNumbers(valueProcessing, 3);
buildAmount(valueFormatted, '', '');
}
break;
case '8':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else if (parsed === 0) {
buildAmount('0', '', '');
} else {
valueFormatted = parsed.toFixed(8);
valueFormatted = localizeNumbers(valueFormatted, 8);
var start = valueFormatted.slice(0, -5);
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
default: // 2
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '--', '', '');
} else {
valueProcessing = parseFloat(parsed.toFixed(2));
valueFormatted = localizeNumbers(valueProcessing, 2);
buildAmount(valueFormatted, '', '');
}
break;
}
$scope.canShow = true;
};
function getDecimalPlaces(currency) {
if (decimalPlaces['0'].indexOf(currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf(currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf(currency.toUpperCase()) > -1) return '8';
return '2';
};
function getDecimalSeparator() {
var testNum = 1.5;
var testString = testNum.toLocaleString(uxLanguage.getCurrentLanguage());
// Some environments let you set decimal separators that are more than one character
var separator = /^1(.+)5$/.exec(testString)[1]
return separator;
};
function localizeNumbers(x, minimumFractionDigits) {
var parsed = parseFloat(x);
var opts = {
minimumFractionDigits: minimumFractionDigits,
useGrouping: true
};
var lang = uxLanguage.getCurrentLanguage();
var localized = parsed.toLocaleString(lang, opts);
var corrected = ensureEnoughFractionDigits(localized, x, minimumFractionDigits);
return corrected;
};
}
})();

View file

@ -111,7 +111,7 @@ angular.module('copayApp.directives').directive('shapeshiftCoinTrader', function
orderId: $scope.depositInfo.orderId
};
if (incomingData.redir(sendAddress, shapeshiftData)) {
if (incomingData.redir(sendAddress, 'shapeshift', shapeshiftData)) {
ongoingProcess.set('connectingShapeshift', false);
return;
}

View file

@ -9,12 +9,12 @@ angular.module('copayApp.directives')
scope: {
isShown: '=slideSuccessShow',
onConfirm: '&slideSuccessOnConfirm',
hideOnConfirm: '=slideSuccessHideOnConfirm'
hideOnConfirm: '=slideSuccessHideOnConfirm',
onShare: '=slideSuccessOnShare',
},
link: function(scope, element, attrs) {
scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
scope.isCordova = platformInfo.isCordova;
scope.hasShareFunction = typeof scope.onShare === 'function';
var elm = element[0];
elm.style.display = 'none';
scope.$watch('isShown', function() {
@ -32,6 +32,9 @@ angular.module('copayApp.directives')
elm.style.display = 'none';
}
};
scope.onShareButtonClick = function() {
scope.onShare();
}
}
};
});

View file

@ -0,0 +1,120 @@
'use strict';
(function(){
angular
.module('bitcoincom.directives')
.directive('walletBalance', function() {
return {
restrict: 'E',
scope: {
displayAsFiat: '@',
totalBalanceSat: '@',
// The Wallet object is sometimes not stringify()-able, so not interpolatable,
// so can't be passed to a directive.
walletStatus: '@',
walletCachedBalance: '@',
walletCachedBalanceUpdatedOn: '@',
walletCachedStatus: '@'
},
templateUrl: 'views/includes/wallet-balance.html',
controller: walletBalanceController
}
});
function walletBalanceController($log, $scope, txFormatService) {
var cryptoBalanceHasBeenDisplayed = false;
formatBalance();
$scope.$watchGroup(['displayAsFiat', 'totalBalanceSat'], function onWalletBalanceWatch() {
formatBalance();
});
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
console.log('displayCryptoBalance()');
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
setDisplay(walletStatus.totalBalanceStr, '');
cryptoBalanceHasBeenDisplayed = true;
return;
}
if (walletCachedBalance) {
setDisplay(walletCachedBalance, walletCachedBalanceUpdatedOn);
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.totalBalanceStr) {
setDisplay(walletCachedStatus.totalBalanceStr, '');
return;
}
setDisplay('', '');
}
function displayFiatBalance(walletStatus, walletCachedStatus) {
var displayAmount = '';
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.alternativeBalanceAvailable) {
displayAmount = walletCachedStatus.totalBalanceAlternative + ' ' + walletCachedStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
getFiatBalance(wallet);
}
function formatBalance() {
var displayAsFiat = $scope.displayAsFiat === 'true';
var walletStatusObj = null;
var walletCachedBalance = null;
var walletCachedBalanceUpdatedOn = null;
var walletCachedStatusObj = null;
try {
walletStatusObj = JSON.parse($scope.walletStatus);
} catch (e) {
$log.warn('Failed to parse walletStatus.', e);
}
try {
walletCachedStatusObj = JSON.parse($scope.walletCachedStatus);
} catch (e) {
$log.warn('Failed to parse walletCachedStatus.', e);
}
if (!displayAsFiat || displayAsFiat && !cryptoBalanceHasBeenDisplayed) {
displayCryptoBalance(walletStatusObj, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatusObj);
}
if (displayAsFiat) {
displayFiatBalance(walletStatusObj, walletCachedStatusObj);
}
}
function getFiatBalance(wallet) {
if (!(wallet.status && wallet.status.isValid)) {
$log.warn('Abandoning call to get fiat balance, because no valid wallet status.');
return;
}
txFormatService.formatAlternativeStr(wallet.coin, wallet.status.totalBalanceSat, function onFormatAlernativeStr(formatted) {
if (formatted) {
setDisplay(formatted, '');
}
});
}
function setDisplay(amount, cachedBalanceUpdatedOn) {
$scope.displayAmount = amount;
$scope.cachedBalanceUpdatedOn = cachedBalanceUpdatedOn;
}
}
})();

View file

@ -236,7 +236,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.receive', {
url: '/receive',
url: '/receive/:walletId',
views: {
'tab-receive': {
controller: 'tabReceiveController',
@ -287,16 +287,44 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*/
.state('tabs.send.amount', {
url: '/amount/:recipientType/:toAddress/:toName/:toEmail/:toColor/:coin/:fixedUnit/:fromWalletId/:minShapeshiftAmount/:maxShapeshiftAmount/:shapeshiftOrderId/:displayAddress/:noPrefix',
url: '/amount',
views: {
'tab-send@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
})
.state('tabs.send.wallet-to-wallet', {
url: '/wallet-to-wallet',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html'
}
}
})
.state('tabs.send.origin', {
url: '/origin',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html',
}
}
})
.state('tabs.send.destination', {
url: '/destination',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html',
}
}
})
.state('tabs.send.confirm', {
url: '/confirm/:recipientType/:toAddress/:toName/:toAmount/:toEmail/:toColor/:description/:coin/:useSendMax/:fromWalletId/:displayAddress/:requiredFeeRate',
url: '/confirm',
views: {
'tab-send@tabs': {
controller: 'confirmController',
@ -317,7 +345,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.review', {
url: '/review/:amount/:fromWalletId/:sendMax/:toAddr/:toWalletId',
url: '/review/:thirdParty/:amount/:fromWalletId/:sendMax/:toAddress/:toWalletId',
views: {
'tab-send@tabs': {
controller: 'reviewController',
@ -708,16 +736,17 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
})
.state('tabs.paymentRequest.amount', {
url: '/amount/:coin',
url: '/amount/:toWalletId',
views: {
'tab-receive@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
})
.state('tabs.paymentRequest.confirm', {
url: '/confirm/:amount/:currency/:coin',
url: '/confirm/:amount/:toWalletId',
views: {
'tab-receive@tabs': {
controller: 'customAmountController',
@ -858,6 +887,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -923,6 +953,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -981,7 +1012,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
/* Shapeshift */
.state('tabs.shapeshift', {
url: '/shapeshift',
url: '/shapeshift/:fromWalletId/:toWalletId',
views: {
'tab-home@tabs': {
controller: 'shapeshiftController',
@ -1042,6 +1073,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
},
@ -1094,6 +1126,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
},
@ -1150,6 +1183,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -1173,7 +1207,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
})
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, pushNotificationsService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
$ionicPlatform.ready(function() {
@ -1197,9 +1231,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
configService.whenAvailable(function(config) {
pushNotificationsService.init();
});
//firebaseEventsService.init();
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
// Send a log to test
@ -1238,6 +1277,13 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
});
window.BitAnalytics.ActionHandlers.trackAction(actionTabOpen);
var actionShapeShiftStart = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'shapeshift_start_click',
class: 'track_shapeshift_start_click',
channels: [channel]
});
window.BitAnalytics.ActionHandlers.trackAction(actionShapeShiftStart);
// Init language
uxLanguage.init(function (lang) {
@ -1277,7 +1323,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
if (screen.width < 768 && platformInfo.isCordova)
screen.lockOrientation('portrait');
if (ionic.Platform.isAndroid() && StatusBar) {
if (ionic.Platform.isAndroid() && platformInfo.isCordova && StatusBar) {
StatusBar.backgroundColorByHexString('#000000');
}

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('bitcoincomService', function(platformInfo, nextStepsService) {
angular.module('copayApp.services').factory('bitcoincomService', function(gettextCatalog, nextStepsService, platformInfo) {
var root = {};
var credentials = {};
@ -19,42 +19,42 @@ angular.module('copayApp.services').factory('bitcoincomService', function(platfo
var cashGamesItem = {
name: 'games',
title: 'Bitcoin Cash Games',
title: gettextCatalog.getString('Bitcoin Cash Games'),
icon: 'icon-games',
href: 'https://cashgames.bitcoin.com'
};
var newsItem = {
name: 'news',
title: 'News',
title: gettextCatalog.getString('News'),
icon: 'icon-news',
href: 'https://news.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=News'
};
var poolItem = {
name: 'pool',
title: 'Mining Pool',
title: gettextCatalog.getString('Mining Pool'),
icon: 'icon-mining',
href: 'https://pool.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Pool'
};
var toolsItem = {
name: 'tools',
title: 'Tools',
title: gettextCatalog.getString('Tools'),
icon: 'icon-tools',
href: 'https://tools.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Tools'
};
var priceChartItem = {
name: 'pricechart',
title: 'Bitcoin Price Charts',
title: gettextCatalog.getString('Bitcoin Price Charts'),
icon: 'icon-chart',
sref: 'tabs.pricechart',
};
var faucetItem = {
name: 'faucet',
title: 'Free Bitcoin Cash',
title: gettextCatalog.getString('Free Bitcoin Cash'),
icon: 'icon-faucet',
href: 'https://free.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Faucet'
};

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('buyAndSellService', function($log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
angular.module('copayApp.services').factory('buyAndSellService', function(gettextCatalog, $log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
var root = {};
var services = [];
var linkedServices = [];
@ -23,7 +23,7 @@ angular.module('copayApp.services').factory('buyAndSellService', function($log,
if (linkedServices.length == 0) {
servicesService.register({
title: 'Buy Bitcoin',
title: gettextCatalog.getString('Buy Bitcoin'),
name: 'buyandsell',
icon: 'icon-buy-bitcoin2',
sref: 'tabs.buyandsell',

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('clipboardService', function ($http, $log, platformInfo, nodeWebkitService, gettextCatalog, ionicToast, clipboard) {
angular.module('copayApp.services').factory('clipboardService', function ($http, $log, $timeout, platformInfo, nodeWebkitService, gettextCatalog, ionicToast, clipboard) {
var root = {};
root.copyToClipboard = function (data) {
@ -11,10 +11,15 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cordova.plugins.clipboard.copy(data);
} else if (platformInfo.isNW) {
nodeWebkitService.writeToClipboard(data);
} else if (navigator && navigator.clipboard) {
$log.debug("Use navigator clipboard.")
navigator.clipboard.writeText(data).catch(function onClipboardError(err) {
$log.debug("Clipboard writing is not supported in your browser..");
});
} else if (clipboard.supported) {
clipboard.copyText(data);
} else {
// No supported
// Not supported
return;
}
};
@ -26,7 +31,9 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cb(text);
})
} else if (platformInfo.isNW) {
cb(nodeWebkitService.readFromClipboard());
$timeout(function() {
cb(nodeWebkitService.readFromClipboard());
},0);
} else {
navigator.clipboard.readText()
.then(function (text) {

View file

@ -1,5 +1,5 @@
'use strict'
angular.module('copayApp.services').factory('communityService', function(configService, $log, lodash) {
angular.module('copayApp.services').factory('communityService', function(configService, gettextCatalog, $log, lodash) {
var root = {};
var services = [];
@ -37,14 +37,14 @@ angular.module('copayApp.services').factory('communityService', function(configS
var bchRedditItem = {
name: 'bchreddit',
title: 'Bitcoin Cash Reddit',
title: gettextCatalog.getString('Bitcoin Cash Reddit'),
icon: 'icon-reddit-white',
href: 'http://reddit.com/r/btc'
};
var bitcoincomTwitterItem = {
name: 'bitcoincomTwitter',
title: 'Bitcoin.com Twitter',
title: gettextCatalog.getString('Bitcoin.com Twitter'),
icon: 'icon-twitter-white',
href: 'https://twitter.com/BTCTN'
};

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, $state, $ionicHistory, sjcl, platformInfo, lodash, appConfigService, profileService, configService) {
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, platformInfo) {
var root = {};
var useEvents = platformInfo.isCordova && !platformInfo.isWP;

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {
angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, sendFlowService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {
var root = {};
@ -8,7 +8,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
$rootScope.$broadcast('incomingDataMenu.showMenu', data);
};
root.redir = function(data, shapeshiftData) {
root.redir = function(data, serviceId, serviceData) {
var originalAddress = null;
var noPrefixInAddress = 0;
@ -75,35 +75,41 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
return true;
}
function goSend(addr, amount, message, coin, shapeshiftData) {
function goSend(addr, amount, message, coin, serviceId, serviceData) {
$state.go('tabs.send', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.send' ? false : true
});
// Timeout is required to enable the "Back" button
$timeout(function() {
var params = sendFlowService.getStateClone();
if (amount) {
$state.transitionTo('tabs.send.confirm', {
toAmount: amount,
toAddress: addr,
displayAddress: originalAddress ? originalAddress : addr,
description: message,
coin: coin
});
params.amount = amount;
}
if (addr) {
params.toAddress = addr;
params.displayAddress = originalAddress ? originalAddress : addr;
}
if (coin) {
params.coin = coin;
}
if (noPrefixInAddress) {
params.noPrefixInAddress = noPrefixInAddress;
}
if (serviceId) {
params.thirdParty = [];
params.thirdParty.id = serviceId;
params.thirdParty.data = serviceData;
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.amount');
} else {
var params = {
toAddress: addr,
coin: coin,
displayAddress: originalAddress ? originalAddress : addr,
noPrefix: noPrefixInAddress
};
if (shapeshiftData) {
params['fromWalletId'] = shapeshiftData.fromWalletId;
params['minShapeshiftAmount'] = shapeshiftData.minAmount;
params['maxShapeshiftAmount'] = shapeshiftData.maxAmount;
params['shapeshiftOrderId'] = shapeshiftData.orderId;
}
$state.transitionTo('tabs.send.amount', params);
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.origin');
}
}, 100);
}
@ -112,15 +118,20 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
var coin = data.indexOf('bitcoincash') >= 0 ? 'bch' : 'btc';
data = decodeURIComponent(data.replace(/bitcoin(cash)?:\?r=/, ''));
if (coin == 'bch') {
payproService.getPayProDetailsViaHttp(data, function(err, details) {
payproService.getPayProDetailsViaHttp(data, function onGetPayProDetailsViaHttp(err, details) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err)
var message = err.toString();
if (typeof err.data === 'string') {
// i.e. 'This invoice is no longer accepting payments'
message = gettextCatalog.getString(err.data);
}
popupService.showAlert(gettextCatalog.getString('Error'), message)
} else {
handlePayPro(createBchPayProObject(details), coin);
handlePayPro(details, coin);
}
});
} else {
payproService.getPayProDetails(data, coin, function(err, details) {
payproService.getPayProDetails(data, coin, function onGetPayProDetails(err, details) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err);
} else {
@ -146,12 +157,12 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
if (parsed.r) {
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount) goSend(addr, amount, message, coin, shapeshiftData);
if (addr && amount) goSend(addr, amount, message, coin, serviceId, serviceData);
else popupService.showAlert(gettextCatalog.getString('Error'), err);
} else handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
goSend(addr, amount, message, coin, serviceId, serviceData);
}
return true;
// Cash URI
@ -169,14 +180,14 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount)
goSend(addr, amount, message, coin, shapeshiftData);
goSend(addr, amount, message, coin, serviceId, serviceData);
else
popupService.showAlert(gettextCatalog.getString('Error'), err);
}
handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
goSend(addr, amount, message, coin, serviceId, serviceData);
}
return true;
@ -212,14 +223,14 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount)
goSend(addr, amount, message, coin, shapeshiftData);
goSend(addr, amount, message, coin, serviceId, serviceData);
else
popupService.showAlert(gettextCatalog.getString('Error'), err);
}
handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
goSend(addr, amount, message, coin, serviceId, serviceData);
}
}
);
@ -377,55 +388,84 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
'notify': $state.current.name == 'tabs.send' ? false : true
});
$timeout(function() {
$state.transitionTo('tabs.send.amount', {
var stateParams = {
toAddress: toAddress,
coin: coin,
noPrefix: 1
});
};
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 100);
}
function createBchPayProObject(payProData) {
var displayAddr = payProData.outputs[0].address;
var toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy;
return {
amount: payProData.outputs[0].amount,
function handlePayPro(payProData, coin) {
console.log(payProData);
var toAddr = payProData.toAddress;
var amount = payProData.amount;
var paymentUrl = payProData.url;
var expires = payProData.expires;
var time = payProData.time;
if (coin === 'bch') {
var displayAddr = payProData.outputs[0].address;
toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy;
amount = payProData.outputs[0].amount;
paymentUrl = payProData.paymentUrl;
expires = Math.floor(new Date(expires).getTime() / 1000)
time = Math.ceil(new Date(time).getTime() / 1000)
}
var name = payProData.domain;
if (payProData.memo.indexOf('eGifter') > -1) {
name = 'eGifter'
} else if (paymentUrl.indexOf('https://bitpay.com') > -1) {
name = 'BitPay';
}
var thirdPartyData = {
id: 'bip70',
amount: amount,
caTrusted: true,
domain: 'bitpay.com',
expires: Math.floor(new Date(payProData.expires).getTime() / 1000),
name: name,
domain: payProData.domain,
expires: expires,
memo: payProData.memo,
network: 'livenet',
requiredFeeRate: payProData.requiredFeeRate,
selfSigned: 0,
time: Math.ceil(new Date(payProData.time).getTime() / 1000),
time: time,
displayAddress: displayAddr,
toAddress: toAddr,
url: payProData.paymentUrl,
url: paymentUrl,
verified: true
};
}
function handlePayPro(payProDetails, coin) {
var stateParams = {
toAmount: payProDetails.amount,
toAddress: payProDetails.toAddress,
description: payProDetails.memo,
paypro: payProDetails,
amount: thirdPartyData.amount,
toAddress: thirdPartyData.toAddress,
coin: coin,
thirdParty: thirdPartyData
};
// fee
if (payProDetails.requiredFeeRate) {
stateParams.requiredFeeRate = payProDetails.requiredFeeRate * 1024;
if (thirdPartyData.requiredFeeRate) {
stateParams.requiredFeeRate = thirdPartyData.requiredFeeRate * 1024;
}
// This does not make sense, thirdPartyData gets added by stateParams below
//sendFlowService.pushState(thirdPartyData);
scannerService.pausePreview();
$state.go('tabs.send', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.send' ? false : true
}).then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.confirm', stateParams);
sendFlowService.pushState(stateParams); // Need to do more here
$state.transitionTo('tabs.send.origin');
});
});
}

View file

@ -0,0 +1,78 @@
'use strict';
// For BIP70 Payment Protocol
angular
.module('copayApp.services')
.factory('payproService', payproService);
function payproService(gettextCatalog, $http, $log, ongoingProcess, platformInfo, profileService) {
var service = {
getPayProDetails: getPayProDetails,
getPayProDetailsViaHttp: getPayProDetailsViaHttp,
broadcastBchTx: broadcastBchTx
};
return service;
function getPayProDetails(uri, coin, cb, disableLoader) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true,
coin: coin
})[0];
if (!wallet) return cb();
if (platformInfo.isChromeApp) {
return cb(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
}
$log.debug('Fetch PayPro Request...', uri);
if (!disableLoader) ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
if (!disableLoader) ongoingProcess.set('fetchingPayPro', false);
if (err) return cb(gettextCatalog.getString('Could Not Fetch Payment: Check if it is still valid'));
else if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
return cb(gettextCatalog.getString('Payment Protocol Invalid'));
}
return cb(null, paypro);
});
}
function getPayProDetailsViaHttp(uri, cb) {
var config = {
headers: {'Accept': 'application/payment-request'}
};
$http.get(uri, config).then(function onGetPayProDetailsSuccess(response) {
return cb(null, response.data);
}, function onGetPayProDetailsError(error) {
return cb(error, null);
});
}
function broadcastBchTx(signedTxp, cb) {
var config = {
headers: {'Content-Type': 'application/payment'}
};
var data = {
currency: 'BCH',
transactions: [signedTxp.raw]
};
$http.post(signedTxp.payProUrl, data, config).then(function(response) {
signedTxp.response = response.data;
return cb(null, signedTxp);
}, function(error) {
return cb(error.data, null);
});
}
}

View file

@ -1,69 +0,0 @@
'use strict';
angular.module('copayApp.services').factory('payproService',
function(profileService, platformInfo, gettextCatalog, ongoingProcess, $log, $http) {
var ret = {};
ret.getPayProDetails = function(uri, coin, cb, disableLoader) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true,
coin: coin
})[0];
if (!wallet) return cb();
if (platformInfo.isChromeApp) {
return cb(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
}
$log.debug('Fetch PayPro Request...', uri);
if (!disableLoader) ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
if (!disableLoader) ongoingProcess.set('fetchingPayPro', false);
if (err) return cb(gettextCatalog.getString('Could Not Fetch Payment: Check if it is still valid'));
else if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
return cb(gettextCatalog.getString('Payment Protocol Invalid'));
}
return cb(null, paypro);
});
};
ret.getPayProDetailsViaHttp = function(uri, cb) {
var config = {
headers: {'Accept': 'application/payment-request'}
};
$http.get(uri, config).then(function(response) {
return cb(null, response.data);
}, function(error) {
return cb(error, null);
});
}
ret.broadcastBchTx = function(signedTxp, cb) {
var config = {
headers: {'Content-Type': 'application/payment'}
};
var data = {
currency: 'BCH',
transactions: [signedTxp.raw]
};
$http.post(signedTxp.payProUrl, data, config).then(function(response) {
signedTxp.response = response.data;
return cb(null, signedTxp);
}, function(error) {
return cb(error.data, null);
});
}
return ret;
});

View file

@ -427,9 +427,9 @@ angular.module('copayApp.services')
}, function(err, secret) {
if (err) return bwcError.cb(err, gettextCatalog.getString('Error creating wallet'), cb);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_created", [{
"coin": opts.coin
@ -847,6 +847,13 @@ angular.module('copayApp.services')
});
}
if (opts.hasNoFunds) {
ret = lodash.filter(ret, function(w) {
if (!w.status) return;
return (w.status.availableBalanceSat === 0);
});
}
if (opts.minAmount) {
ret = lodash.filter(ret, function(w) {
if (!w.status) return;

View file

@ -1,4 +1,4 @@
describe('secureStorageService in browser', function(){
xdescribe('secureStorageService in browser', function(){
var localStorage,
sss;
@ -100,7 +100,7 @@ describe('secureStorageService in browser', function(){
});
describe('secureStorageService on desktop', function(){
xdescribe('secureStorageService on desktop', function(){
var desktopSss,
sss;
@ -202,7 +202,7 @@ describe('secureStorageService on desktop', function(){
});
describe('secureStorageService on mobile', function(){
xdescribe('secureStorageService on mobile', function(){
var mobileSss,
sss;

View file

@ -0,0 +1,101 @@
'use strict';
(function(){
angular
.module('copayApp.services')
.factory('sendFlowService', sendFlowService);
function sendFlowService($log) {
var service = {
// A separate state variable so we can ensure it is cleared of everything,
// even other properties added that this service does not know about. (such as "coin")
state: {
amount: '',
fromWalletId: '',
sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: ''
},
previousStates: [],
// Functions
clear: clear,
getStateClone: getStateClone,
map: map,
popState: popState,
pushState: pushState,
startSend: startSend
};
return service;
function clear() {
console.log("sendFlow clear()");
clearCurrent();
service.previousStates = [];
}
function clearCurrent() {
console.log("sendFlow clearCurrent()");
service.state = {
amount: '',
fromWalletId: '',
sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: ''
}
}
/**
* Handy for debugging
*/
function getStateClone() {
var currentState = {};
Object.keys(service.state).forEach(function forCurrentParam(key) {
if (typeof service.state[key] !== 'function' && key !== 'previousStates') {
currentState[key] = service.state[key];
}
});
return currentState;
}
/**
* Clears all previous state
*/
function startSend(params) {
console.log('startSend()');
clear();
map(params);
}
function map(params) {
Object.keys(params).forEach(function forNewParam(key) {
service.state[key] = params[key];
});
};
function popState() {
console.log('sendFlow pop');
if (service.previousStates.length) {
var params = service.previousStates.pop();
clearCurrent();
map(params);
} else {
clear();
}
};
function pushState(params) {
console.log('sendFlow push');
var currentParams = getStateClone();
service.previousStates.push(currentParams);
clearCurrent();
map(params);
};
};
})();

View file

@ -1,7 +1,12 @@
'use strict'
angular.module('copayApp.services').factory('servicesService', function(configService, $log, lodash) {
var root = {};
var services = [];
var services = [{
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
}];
root.register = function(serviceInfo) {
$log.info('Adding Services entry:' + serviceInfo.name);

View file

@ -1,19 +1,141 @@
'use strict';
angular.module('copayApp.services').factory('shapeshiftService', function($http, $log, lodash, moment, storageService, configService, platformInfo, servicesService) {
angular.module('copayApp.services').factory('shapeshiftService', function ($http, $interval, $log, lodash, moment, ongoingProcess, shapeshiftApiService, storageService, configService, incomingData, platformInfo, servicesService) {
var root = {};
var credentials = {};
root.ShiftState = 'Shift';
root.coinIn = '';
root.coinOut = '';
root.withdrawalAddress = '';
root.returnAddress = '';
root.amount = '';
root.marketData = {};
var servicesItem = {
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
root.getMarketDataIn = function (coin) {
if (coin === root.coinOut) return root.getMarketData(root.coinOut, root.coinIn);
return root.getMarketData(coin, root.coinOut);
};
root.getMarketDataOut = function (coin) {
if (coin === root.coinIn) return root.getMarketData(root.coinOut, root.coinIn);
return root.getMarketData(root.coinIn, coin);
};
root.getMarketData = function (coinIn, coinOut, cb) {
root.coinIn = coinIn;
root.coinOut = coinOut;
if (root.coinIn === undefined || root.coinOut === undefined) return;
shapeshiftApiService
.marketInfo(root.coinIn, root.coinOut)
.then(function (marketData) {
root.marketData = marketData;
root.rateString = root.marketData.rate.toString() + ' ' + coinOut.toUpperCase() + '/' + coinIn.toUpperCase();
if (cb) {
cb(marketData);
}
});
};
var register = function() {
servicesService.register(servicesItem);
/*shapeshiftApiService.coins().then(function(coins){
root.coins = coins;
root.coinIn = coins['BTC'].symbol;
root.coinOut = coins['BCH'].symbol;
root.getMarketData(root.coinIn, root.coinOut);
});*/
root.coins = {
'BTC': {name: 'Bitcoin', symbol: 'BTC'},
'BCH': {name: 'Bitcoin Cash', symbol: 'BCH'}
};
function checkForError(data) {
if (data.err) return true;
return false;
}
root.shiftIt = function (coinIn, coinOut, withdrawalAddress, returnAddress, cb) {
ongoingProcess.set('connectingShapeshift', true);
root.withdrawalAddress = withdrawalAddress;
root.returnAddress = returnAddress;
root.coinIn = coinIn;
root.coinOut = coinOut;
shapeshiftApiService.ValidateAddress(withdrawalAddress, coinOut).then(function (valid) {
var tx = ShapeShift();
var coin;
console.log("Starting");
tx.then(function (txData) {
console.log("Got txData", txData);
if (txData['fixedTxData']) {
txData = txData.fixedTxData;
if (checkForError(txData)) return cb(txData.err);
//console.log(txData)
var coinPair = txData.pair.split('_');
txData.depositType = coinPair[0].toUpperCase();
txData.withdrawalType = coinPair[1].toUpperCase();
coin = root.coins[txData.depositType].name.toLowerCase();
txData.depositQR = coin + ":" + txData.deposit + "?amount=" + txData.depositAmount;
root.txFixedPending = true;
} else if (txData['normalTxData']) {
txData = txData.normalTxData;
if (checkForError(txData)) return cb(txData.err);
coin = root.coins[txData.depositType.toUpperCase()].name.toLowerCase();
txData.depositQR = coin + ":" + txData.deposit;
} else if (txData['cancelTxData']) {
txData = txData.cancelTxData;
if (checkForError(txData)) return cb(txData.err);
if (root.txFixedPending) {
root.txFixedPending = false;
}
root.ShiftState = 'Shift';
}
root.depositInfo = txData;
//console.log(root.marketData);
//console.log(root.depositInfo);
var sendAddress = txData.depositQR;
if (sendAddress && sendAddress.indexOf('bitcoin cash') >= 0)
sendAddress = sendAddress.replace('bitcoin cash', 'bitcoincash');
ongoingProcess.set('connectingShapeshift', false);
root.ShiftState = 'Cancel';
//root.GetStatus();
//root.txInterval=$interval(root.GetStatus, 8000);
var shapeshiftData = {
coinIn: coinIn,
coinOut: coinOut,
toWalletId: root.toWalletId,
minAmount: root.marketData.minimum,
maxAmount: root.marketData.maxLimit,
orderId: root.depositInfo.orderId,
toAddress: txData.deposit
};
//
// if (incomingData.redir(sendAddress, 'shapeshift', shapeshiftData)) {
ongoingProcess.set('connectingShapeshift', false);
// return;
// }
cb(null, shapeshiftData);
});
})
};
function ShapeShift() {
if (parseFloat(root.amount) > 0) return shapeshiftApiService.FixedAmountTx(root);
return shapeshiftApiService.NormalTx(root);
}
root.GetStatus = function () {
var address = root.depositInfo.deposit
shapeshiftApiService.GetStatusOfDepositToAddress(address).then(function (data) {
root.DepositStatus = data;
if (root.DepositStatus.status === 'complete') {
$interval.cancel(root.txInterval);
root.depositInfo = null;
root.ShiftState = 'Shift'
}
});
};
register();
return root;
});

View file

@ -414,7 +414,7 @@ xdescribe('storageService on desktop', function(){
});
describe('storageService on desktop using local storage', function(){
xdescribe('storageService on desktop using local storage', function(){
var appConfig,
localStorageServiceMock,
log,
@ -614,7 +614,7 @@ describe('storageService on desktop using local storage', function(){
});
describe('storageService on mobile', function(){
xdescribe('storageService on mobile', function(){
var appConfig,
expectedOldProfileSavedToSecure,
expectedOldProfileMergedWithSecure,

View file

@ -201,7 +201,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency
if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') {
if (currency && currency.toUpperCase() != 'BCH' && currency.toUpperCase() != 'BTC' && currency != 'sat') {
amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0);
} else if (currency == 'sat') {

View file

@ -343,21 +343,19 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (err) return cb(err);
if (!txsFromServer.length)
return cb();
return cb(null, []);
var res = lodash.takeWhile(txsFromServer, function(tx) {
return tx.txid != endingTxid;
});
return cb(null, res, res.length >= limit);
return cb(null, txsFromServer);
});
};
var removeAndMarkSoftConfirmedTx = function(txs) {
return lodash.filter(txs, function(tx) {
if (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT)
return tx;
tx.recent = true;
var isConfirm = (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT);
if (!isConfirm) {
tx.recent = true;
}
return isConfirm;
});
}
@ -437,12 +435,14 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null;
var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null;
$log.debug('Confirmed TXs. Got:' + confirmedTxs.length + '/' + txsFromLocal.length);
// First update
progressFn(txsFromLocal, 0);
wallet.completeHistory = txsFromLocal;
function getNewTxs(newTxs, skip, next) {
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res) {
if (err) {
$log.warn(bwcError.msg(err, 'Server Error')); //TODO
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
@ -454,7 +454,22 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
return next(err);
}
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res)));
// Check if new txs are founds, if yes, lets investigate in the 50 next
// To be sure we are not missing txs by sorting (maybe a new tx is after the "endingTxid"
var newDiscoveredTxs = res.filter(function (x) {
return confirmedTxs.filter(function (confX) {
return confX.txid == x.txid;
}).length == 0;
});
$log.debug('Discovering TXs. Got:' + newDiscoveredTxs.length);
var shouldContinue = newDiscoveredTxs.length > 0;
// If no new tx, no need to check
if (shouldContinue) {
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(newDiscoveredTxs)));
}
progressFn(newTxs.concat(txsFromLocal), newTxs.length);
@ -884,7 +899,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var createAddress = function(wallet, cb) {
$log.debug('Creating address for wallet:', wallet.id);
wallet.createAddress({}, function(err, addr) {
wallet.createAddress({}, function onWalletCreatedAddress(err, addr) {
if (err) {
var prefix = gettextCatalog.getString('Could not create address');
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
@ -902,6 +917,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (err) return cb(err);
return cb(null, addr[0].address);
});
return;
}
return bwcError.cb(err, prefix, cb);
}

View file

@ -55,6 +55,7 @@
.button {
border-radius: 6px;
&.button-full {
border-radius: 0;
display: block;
}
&-green {
@ -72,5 +73,17 @@
&.activated {
color: #FFF;
}
&-outline {
@include button-style(transparent, #FFFFFF, #FFFFFF, #FFFFFF, #FFFFFF);
@include button-outline(#FFFFFF);
background: none;
box-shadow: none;
}
}
&-grey-outline {
@include button-style(transparent, #727272, #FAFAFA, #727272, #727272);
@include button-outline(#727272);
background: none;
box-shadow: none;
}
}

View file

@ -1,4 +1,4 @@
.address {
.address-frame {
background-color: #F8F8F8;
border: 0.5px solid #EDEBEB;
border-radius: 3px;

View file

@ -4,8 +4,9 @@
@import "header";
@import "content-frame";
@import "address";
@import "address-frame";
@import "action-minor";
@import "expand-content";
@import "fee-summary";
@import "amount.scss";
@import "formatted-amount";
@import "wallet-balance";

View file

@ -1,7 +1,7 @@
.fee-summary {
position: relative;
display: flex;
justify-content: space-between;
flex-direction: column;
width: 100%;
padding: 5px 12px 15px;
box-sizing: border-box;
@ -17,17 +17,24 @@
background: linear-gradient(to bottom, rgba(242,242,242,0) 0%,rgba(242,242,242,1) 100%);
}
.fee-fiat {
&.positive {
color: #70955F;
.amount {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
.fee-fiat {
&.positive {
color: #70955F;
}
&.negative {
color: #C24633;
}
}
&.negative {
color: #C24633;
.fee-crypto {
color: #A7A7A7;
}
}
.fee-crypto {
color: #A7A7A7;
}
}

View file

@ -1,4 +1,6 @@
.amount {
.formatted-amount {
display: inline-block;
.start,
.middle,
.end,

View file

@ -1,6 +1,9 @@
.header {
padding: 29px 12px 61px;
background-color: #FAB915;
background-color: $v-bitcoin-orange;
&.btc {
background-color: $v-bitcoin-core;
}
color: #FFFFFF;
.title {

View file

@ -0,0 +1,3 @@
.wallet-balance-directive {
display: inline-block;
}

View file

@ -18,3 +18,53 @@
.absolute-center{
@include absolute-center();
}
.third-party-notice {
font-size: 12px;
margin: 0px 14px;
font-weight: 600;
color: #6F6F70;
@media (min-width: 768px) {
text-align: center;
}
}
@mixin empty-case() {
padding-top: 5vh;
text-align: center;
.item {
border-style: none;
}
& > .title {
font-size: 20px;
color: $v-dark-gray;
margin: 20px 10px;
}
& > .subtitle {
font-size: 1rem;
line-height: 1.5em;
font-weight: 300;
color: #6F6F70;
margin: 20px 1em 2.5em;
}
.big-icon-svg {
.bg.green {
padding: 0 10px;
box-shadow: none;
}
}
.buttons {
margin-top: 18px;
.button {
font-weight: bold;
font-size: 19px;
}
}
.button-first-contact img {
height: 19px;
width: 19px;
margin-right: 6px;
vertical-align: sub;
}
}

View file

@ -5,8 +5,8 @@ qrcode {
content: "";
background-size: 100% 100%;
display: block;
left: 88px;
margin-top: 88px;
left: calc(50% - 22px);
margin-top: calc(50% - 22px);
width: 44px;
height: 44px;
position:absolute;

View file

@ -233,6 +233,10 @@ input[type=number] {
font-size: 24px;
}
.size-25 {
font-size: 25px;
}
.size-28 {
font-size: 28px;
}
@ -464,3 +468,7 @@ input[type=file] {
.white-space-initial {
white-space: initial;
}
.height-spacer {
height: 15px;
}

View file

@ -8,7 +8,9 @@ $v-font-family-light: "Roboto-Light", sans-serif-
/* Colors */
$v-bitcoin-orange: #fab915 !default;
$v-bitcoin-core: #535353 !default;
$v-off-black: #262424;
$v-dark-gray: #445 !default;
$v-mid-gray: #667 !default;
$v-light-gray: #9b9bab !default;
@ -24,8 +26,11 @@ $v-text-accent-color: #647ce8 !default;
$v-success-color: #13e5b6 !default;
$v-warning-color: #ffa500 !default;
$v-warning-color-2: #b7664d;
$v-error-color: #ef473a !default;
$v-background-under-card: #f2f2f2;
$v-wallet-color-map: (
0: (color: #dd4b39, name: 'Cinnabar'),
1: (color: #f38f12, name: 'Carrot Orange'),
@ -77,6 +82,7 @@ $v-button-primary-active-bg: darken($v-accent-color, 10%
$v-button-primary-active-border: transparent !default;
$v-button-primary-clear-bg: none !default;
$v-button-primary-clear-color: $v-accent-color !default;
$v-button-primary-disabled-bg: $v-mid-gray;
$v-button-primary-outline-bg: transparent !default;
$v-button-primary-outline-border: $v-accent-color !default;
$v-button-primary-outline-color: $v-accent-color !default;

View file

@ -244,6 +244,21 @@
flex-direction: column;
justify-content: center;
.send-amount-header-footer {
flex: 1 1 auto;
min-height: 20px;
.warning {
font-weight: bold;
font-size: 12px;
padding: 0 6px 6px 6px;
text-align: center;
}
&__max {
float: right;
}
}
.send-amount-tool {
flex: 0 1 auto;
@ -260,6 +275,8 @@
}
.primary-amount {
color: #333;
font-weight: bold;
input, .unit, .primary-amount-display {
font-size: 1.8em;
@ -288,7 +305,8 @@
&.very-long {
input, .unit, .primary-amount-display {
font-size: 0.9em;
font-size: 1.2em; // OK for iPhone 5 / SE with BCH to 8dp
@media (min-width: 375px) {
font-size: 1.3em;
@ -329,16 +347,15 @@
line-height: 1em;
}
.unit {
font-weight: bold;
}
.primary-amount-display {
margin-right: 5px;
word-break: break-all;
}
}
.alternative-amount {
color: #6F6F70;
}
.switch-currencies {
position: absolute;
right: 0;
@ -351,26 +368,60 @@
}
}
}
}
}
.send-amount-actions {
margin-top: 15px;
display: flex;
align-items: center;
justify-content: center;
.send-amount-extras {
display: flex;
flex: 0 0 auto;
/* So that if only one item is present, it appears on the right. */
flex-direction: row-reverse;
font-size: 12px;
align-items: center;
justify-content: space-between;
margin: 0 14px;
.button {
flex: 1 1 auto;
line-height: 1.2em;
.available-funds {
color: #6F6F70;
text-align: left;
}
+ .button {
margin-left: 10px;
}
.change-currency {
text-align: right;
}
span {
display: flex;
align-items: center;
justify-content: center;
}
.warning {
color: $v-warning-color-2;
}
.extra {
flex: 1;
line-height: normal;
.button {
background: none;
border: none;
border-radius: 0;
color: #000;
font-family: 'ProximaNova';
font-size: 14px;
line-height: normal;
min-height: auto;
min-width: auto;
padding: 0;
}
.button .icon:before {
font-size: 14px;
line-height: normal;
}
.button {
span {
display: flex;
align-items: center;
justify-content: center;
}
}
}
@ -394,37 +445,58 @@
.keypad-container {
position: relative;
font-size: 18px;
line-height: 2em;
//flex: 0 1 196px;
@media (min-height: 667px) {
font-size: 24px;
}
@media(max-height: 480px) {
font-size: 12px;
}
@media (min-height: 667px) {
//flex: 0 1 224px;
}
.sendmax {
background: $v-off-black;
.button {
color: white;
background: black;
border: 1px solid $v-off-black;
border-radius: 0;
font-size: 0.8em;
line-height: 2em;
width: 100%;
.available-funds-amount {
color: #C9C9C9;
}
&:active {
background-color: $v-dark-gray;
}
}
}
.keypad {
text-align: center;
font-size: 18px;
font-weight: lighter;
position: absolute;
bottom: 0;
width: 100%;
color: $v-mid-gray;
color: $v-text-primary-color;
@media (min-height: 667px) {
font-size: 24px;
}
.row {
padding: 0 !important;
margin: 0 !important;
}
.col {
line-height: 38px;
@media (min-height: 667px) {
line-height: 45px;
}
}
.row {
&:last-child {
@ -458,23 +530,34 @@
.digit{
cursor: pointer;
border-top: 1px solid $v-subtle-gray;
border-left: 1px solid $v-subtle-gray;
background-color: #000;
border: 1px solid $v-off-black;
transition: all 0.1s ease;
&:active {
background-color: $v-subtle-gray;
background-color: $v-dark-gray;
}
}
@media(max-height: 480px) {
font-size: 12px;
}
}
}
.button-primary {
background-color: $v-primary-color;
border-radius: 0;
font-weight: bold;
}
.button-primary[disabled] {
background-color: $v-button-primary-disabled-bg;
opacity: 1;
}
}
background: #494949;
.warning {
color: $v-warning-color-2;
}
background: $v-background-under-card;
ion-content {
margin-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */

View file

@ -26,16 +26,10 @@
height: 100%;
.qr-code {
text-align: center;
margin-top: 24vh;
margin-bottom: 7vh;
@media(max-height: 800px) {
margin-top: 18vh;
}
@media(max-height: 700px) {
margin-top: 14vh;
}
@media(max-height: 600px) {
margin-top: 8vh;
margin-top: 6px;
qrcode canvas {
height: 30vh;
max-height: 220px;
}
}
.info {
@ -91,5 +85,34 @@
.address-types {
text-align: center;
}
.amount {
margin-top: 20vh;
margin-bottom: 4vh;
@media(max-height: 800px) {
margin-top: 12vh;
margin-bottom: 6vh;
}
@media(max-height: 700px) {
margin-top: 10vh;
margin-bottom: 4vh;
}
@media(max-height: 600px) {
margin-top: 6vh;
margin-bottom: 2vh;
}
width: 100%;
text-align: center;
//padding-top: 30px;
display: block;
align-items: center;
justify-content: center;
&-alternative {
line-height: 36px;
}
}
}
}

View file

@ -8,6 +8,7 @@ click-to-accept {
.click-to-accept {
&__button.button.button-primary.button-standard {
border-radius: 0;
height: 100%;
max-width: 9999px;
width: 100%;

View file

@ -13,6 +13,9 @@ slide-to-accept {
}
.slide {
.button {
border-radius: 0;
}
&__listener {
height: 100%;
width: 100%;

View file

@ -12,12 +12,6 @@ slide-to-accept-success {
.slide-success {
$duration: 400ms;
&__windows-background {
background: $v-success-bg-color;
height: 100%;
width: 100%;
position: fixed;
}
&__background {
$start-radius: 5;
$scale-factor: 20;
@ -40,9 +34,11 @@ slide-to-accept-success {
&__content {
position: relative;
z-index: 1;
margin-top: -20vh;
margin-top: -10vh;
> img {
width: 45vw;
max-width: 166px;
margin-bottom: 1.8rem;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
@ -59,7 +55,7 @@ slide-to-accept-success {
&__header {
color: #FFFFFF;
font-size: 26px;
font-size: 29px;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
opacity: 0;
@ -72,6 +68,26 @@ slide-to-accept-success {
opacity: 1;
}
}
&__share {
transition: transform $duration ease, opacity $duration ease;
transition-delay: 600ms;
opacity: 0;
margin-top: 15vh;
span {
color: #FFF;
font-size: 22px;
height: 28px;
}
img {
height: 28px;
width: auto;
vertical-align: bottom;
margin-right: 4px;
}
&.reveal {
opacity: 0.79;
}
}
}
&__footer {
@ -98,11 +114,11 @@ slide-to-accept-success {
&__btn {
display: block;
color: #FFFFFF;
font-size: 18px;
font-size: 22px;
font-weight: 600;
letter-spacing: 2.86px;
padding: 1rem 0 1.1rem;
border-top: 1px solid rgba(255, 255, 255, .45);
padding: 2rem 0 2.1rem;
border-top: 1px solid rgba(255, 255, 255, 0.25);
cursor: pointer;
}
}

View file

@ -1,5 +1,4 @@
#view-review {
background-color: #494949;
slide-to-accept, slide-to-accept-success {
margin-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */
@ -10,4 +9,12 @@
position: absolute;
bottom: 92px;
}
.shapeshift-banner, .bitpay-banner, .egifter-banner {
box-shadow: none;
}
.warning {
color: $v-warning-color-2;
}
}

View file

@ -0,0 +1,23 @@
#shapeshift {
.swap-image {
width: auto;
max-width: 400px;
max-height: 25vh;
}
.empty-case {
@include empty-case();
}
.button-shapeshift {
@extend %button-standard;
@include button-style(#243F5D, #FFF, #606060, #FFF, #FFF);
@include button-clear(#FFF);
@include button-outline(#C1C1C1);
border: 0px;
@include button-shadow();
}
}
.header.shapeshift {
background: url(../img/shapeshiftbg.jpg) center center repeat #28394d;
opacity: 0.99;
}

View file

@ -69,6 +69,30 @@
}
}
}
.buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin: 6px auto -12px;
text-align: center;
width: 100%;
>.col {
padding: 5px 10px;
margin-bottom: 0;
}
.button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px;
}
}
.wallet-coin-logo {
vertical-align: middle;
margin-right: 5px;

View file

@ -2,15 +2,15 @@
@extend .deflash-blue;
&-header{
height: 300px;
//height: 300px;
width: 100%;
}
&-contacts {
height: calc(100vh - 300px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
//height: calc(100vh - 300px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
&.ios {
height: calc(100vh - 300px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
//height: calc(100vh - 300px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
}
overflow: scroll;
//overflow: scroll;
}
.input {
@ -88,6 +88,8 @@
&.contains-address {
.address {
display: inline;
border: none;
background-color: transparent;
}
.non-address {
display: none;
@ -133,42 +135,7 @@
padding-left: 30px;
}
.sendTip {
padding-top: 5vh;
text-align: center;
.item {
border-style: none;
}
& > .title {
font-size: 20px;
color: $v-dark-gray;
margin: 20px 10px;
}
& > .subtitle {
font-size: 1rem;
line-height: 1.5em;
font-weight: 300;
color: #6F6F70;
margin: 20px 1em 2.5em;
}
.big-icon-svg {
.bg.green {
padding: 0 10px;
box-shadow: none;
}
}
.buttons {
margin-top: 18px;
.button {
font-weight: bold;
font-size: 19px;
}
}
.button-first-contact img {
height: 19px;
width: 19px;
margin-right: 6px;
vertical-align: sub;
}
@include empty-case();
}
.item-heading {
line-height: 16px;
@ -256,12 +223,12 @@
}
}
#tab-send-header {
height: 270px;
//height: 270px;
}
#tab-send-contacts {
height: calc(100vh - 270px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
//height: calc(100vh - 270px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
&.ios {
height: calc(100vh - 270px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
//height: calc(100vh - 270px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
}
}
}

View file

@ -8,11 +8,13 @@
@import "tab-receive";
@import "tab-scan";
@import "tab-send";
@import "wallet-origin-destination";
@import "tab-settings";
@import "wallet-colors";
@import "walletBalance";
@import "walletDetails";
@import "advancedSettings";
@import "shapeshift";
@import "bitpayCard";
@import "bitpayCardIntro";
@import "buyandsell";

View file

@ -0,0 +1,74 @@
#wallet-origin-destination {
.header--request {
padding: 30px 24px;
width: 100%;
height: 139px;
background-color: #fff;
&__title {
width: 46px;
height: 20px;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.4px;
color: #000000;
}
&__amount {
font-size: 29px;
font-weight: 600;
letter-spacing: -0.7px;
color: #000000;
margin: 11px 0 2px;
}
&__amount-alt {
opacity: 0.45;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.4px;
color: #000000;
}
}
.wallets-header {
margin: 20px 14px 0px;
.title {
font-size: 16px;
font-weight: bold;
color: $v-dark-gray;
margin-bottom: -12px;
}
}
.card {
font-size: 12px;
margin: 20px 14px 0px;
.item-heading {
.subtitle {
font-size: 12px;
}
font-weight: 600;
}
&-insufficient {
.wallet {
opacity: 0.4;
}
.item-heading {
font-size: 12px;
>div {
display: inline-block;
vertical-align: text-bottom;
}
}
&__dot {
display: inline-block;
width: 16px;
height: 16px;
background-color: #ec5959;
border-radius: 8px;
margin: 2px 6px 2px 2px;
}
}
}
}

View file

@ -135,11 +135,12 @@
&.status-bar {
margin-top: 20px;
margin-top: env(safe-area-inset-top);
}
}
.bar-header {
border: 0;
background: none;
background: rgb(238, 182, 64);
.title, .button {
color: #fff;
}
@ -153,7 +154,7 @@
ion-content {
&.collapsible {
margin-top: 210px;
margin-top: 230px;
}
padding-top: 0;
@ -190,12 +191,38 @@
transform: translateY(100px);
}
}
.send-receive-buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
width: 100%;
position: absolute;
bottom: 20px;
>.col {
padding: 5px 10px;
margin-bottom: 0;
}
.button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px;
}
}
}
.amount {
width: 100%;
text-align: center;
color: #fff;
height: 210px;
height: 230px;
padding-top: 40px;
display: block;
align-items: center;
@ -234,6 +261,7 @@
.no-alternative {
padding-top: 45px;
}
.item.item-footer {
font-weight: lighter;
}

View file

@ -17,6 +17,8 @@ module.exports = function(config) {
files: [
'node_modules/angular/angular.js',
'bitanalytics/bitanalytics-0.1.0.js',
// From Gruntfile.js
'bower_components/qrcode-generator/js/qrcode.js',
'bower_components/qrcode-generator/js/qrcode_UTF8.js',

View file

@ -318,5 +318,33 @@ div.slide-success__background.fill-screen {
display: block;
float: left;
max-height: 100%;
max-width: 100%;
max-width: 100%;
}
.bitpay-banner {
background: #1A3A8B;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
}
.bitpay-logo {
display: block;
max-height: 100%;
width: 100%;
height: 4em;
}
.egifter-banner {
background: #066EAA;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
text-align: center;
}
.egifter-logo {
max-height: 100%;
max-width: 100%;
height: 4em;
}

View file

@ -10082,7 +10082,7 @@ ion-view.deflash-blue:before, ion-view#view-amount:before, ion-view#view-confirm
.onboarding .button.button-light.button-standard,
.onboarding .button.button-white.button-standard,
.onboarding .button.button-green.button-standard,
.onboarding .button.button-assertive.button-standard {
.onboarding .button.button-assertive.button-standard, #shapeshift .button-shapeshift {
width: 85%;
max-width: 300px;
margin-left: auto;
@ -10253,6 +10253,46 @@ ion-view.deflash-blue:before, ion-view#view-amount:before, ion-view#view-confirm
color: #fff; }
.button-white.activated {
color: #FFF; }
.button-white-outline {
border-color: #FFFFFF;
background-color: transparent;
color: #FFFFFF;
background: none;
box-shadow: none; }
.button-white-outline:hover {
color: #FFFFFF;
text-decoration: none; }
.button-white-outline.active, .button-white-outline.activated {
border-color: #FFF;
background-color: #FAFAFA; }
.button-white-outline.button-outline {
border-color: #FFFFFF;
background: transparent;
color: #FFFFFF; }
.button-white-outline.button-outline.active, .button-white-outline.button-outline.activated {
background-color: #FFFFFF;
box-shadow: none;
color: #fff; }
.button-grey-outline {
border-color: #727272;
background-color: transparent;
color: #727272;
background: none;
box-shadow: none; }
.button-grey-outline:hover {
color: #727272;
text-decoration: none; }
.button-grey-outline.active, .button-grey-outline.activated {
border-color: #727272;
background-color: #FAFAFA; }
.button-grey-outline.button-outline {
border-color: #727272;
background: transparent;
color: #727272; }
.button-grey-outline.button-outline.active, .button-grey-outline.button-outline.activated {
background-color: #727272;
box-shadow: none;
color: #fff; }
.button-clear {
background: none !important; }
@ -10271,8 +10311,8 @@ qrcode {
content: "";
background-size: 100% 100%;
display: block;
left: 88px;
margin-top: 88px;
left: calc(50% - 22px);
margin-top: calc(50% - 22px);
width: 44px;
height: 44px;
position: absolute; }
@ -10292,6 +10332,15 @@ qrcode {
top: 50%;
left: 50%; }
.third-party-notice {
font-size: 12px;
margin: 0px 14px;
font-weight: 600;
color: #6F6F70; }
@media (min-width: 768px) {
.third-party-notice {
text-align: center; } }
.tabs .tab-item .icon {
background-repeat: no-repeat;
background-position: center;
@ -10349,7 +10398,7 @@ qrcode {
padding: 10px; }
#view-amount {
background: #494949; }
background: #f2f2f2; }
#view-amount .recipient-label {
font-size: 14px;
padding-bottom: 0;
@ -10542,6 +10591,16 @@ qrcode {
display: flex;
flex-direction: column;
justify-content: center; }
#view-amount .scroll-content .send-amount .send-amount-header-footer {
flex: 1 1 auto;
min-height: 20px; }
#view-amount .scroll-content .send-amount .send-amount-header-footer .warning {
font-weight: bold;
font-size: 12px;
padding: 0 6px 6px 6px;
text-align: center; }
#view-amount .scroll-content .send-amount .send-amount-header-footer__max {
float: right; }
#view-amount .scroll-content .send-amount .send-amount-tool {
flex: 0 1 auto; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input {
@ -10553,53 +10612,56 @@ qrcode {
-moz-user-select: text;
-ms-user-select: text;
user-select: text; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 1.8em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 2.1em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 2.4em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 1.6em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 1.8em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 2em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 0.9em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 1.3em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 1.4em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input {
border: 0;
padding: 0;
white-space: normal;
background: none;
line-height: 1;
box-sizing: content-box;
display: inline-block;
vertical-align: middle;
margin: 0;
height: 1em;
margin-right: 5px;
font-family: 'ProximaNova'; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit,
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
display: inline-block;
vertical-align: middle;
line-height: 1em; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount {
color: #333;
font-weight: bold; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
margin-right: 5px;
word-break: break-all; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 1.8em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 2.1em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
font-size: 2.4em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 1.6em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 1.8em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
font-size: 2em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 0.9em; }
@media (min-width: 375px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 1.3em; } }
@media (min-width: 414px) {
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
font-size: 1.4em; } }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount input {
border: 0;
padding: 0;
white-space: normal;
background: none;
line-height: 1;
box-sizing: content-box;
display: inline-block;
vertical-align: middle;
margin: 0;
height: 1em;
margin-right: 5px;
font-family: 'ProximaNova'; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .unit,
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
display: inline-block;
vertical-align: middle;
line-height: 1em; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
margin-right: 5px;
word-break: break-all; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .alternative-amount {
color: #6F6F70; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .switch-currencies {
position: absolute;
right: 0;
@ -10608,20 +10670,40 @@ qrcode {
padding: 15px; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .switch-currencies img {
width: 18px; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-actions {
margin-top: 15px;
display: flex;
align-items: center;
justify-content: center; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-actions .button {
flex: 1 1 auto;
line-height: 1.2em; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-actions .button + .button {
margin-left: 10px; }
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-actions .button span {
display: flex;
align-items: center;
justify-content: center; }
#view-amount .scroll-content .send-amount-extras {
display: flex;
flex: 0 0 auto;
/* So that if only one item is present, it appears on the right. */
flex-direction: row-reverse;
font-size: 12px;
align-items: center;
justify-content: space-between;
margin: 0 14px; }
#view-amount .scroll-content .send-amount-extras .available-funds {
color: #6F6F70; }
#view-amount .scroll-content .send-amount-extras .warning {
color: #b7664d; }
#view-amount .scroll-content .send-amount-extras .extra,
#view-amount .scroll-content .send-amount-extras button.extra {
/*display: flex;*/
flex: 0 1 auto; }
#view-amount .scroll-content .send-amount-extras button.extra {
background: none;
border: none;
color: #000;
font-family: 'ProximaNova';
font-size: 14px;
line-height: normal;
min-height: auto;
min-width: auto;
padding: 0; }
#view-amount .scroll-content .send-amount-extras .button .icon:before {
font-size: 14px;
line-height: normal; }
#view-amount .scroll-content .send-amount-extras .button span {
display: flex;
align-items: center;
justify-content: center; }
#view-amount .scroll-content .button.no-margin {
margin: 0; }
#view-amount .scroll-content .notification-warning {
@ -10633,26 +10715,39 @@ qrcode {
line-height: 1.4em;
margin-bottom: 20px; }
#view-amount .scroll-content .keypad-container {
position: relative; }
position: relative;
font-size: 18px;
line-height: 2em; }
@media (min-height: 667px) {
#view-amount .scroll-content .keypad-container {
font-size: 24px; } }
@media (max-height: 480px) {
#view-amount .scroll-content .keypad-container {
font-size: 12px; } }
#view-amount .scroll-content .keypad-container .sendmax {
background: #262424; }
#view-amount .scroll-content .keypad-container .sendmax .button {
color: white;
background: black;
border: 1px solid #262424;
border-radius: 0;
font-size: 0.8em;
line-height: 2em;
width: 100%; }
#view-amount .scroll-content .keypad-container .sendmax .button .available-funds-amount {
color: #C9C9C9; }
#view-amount .scroll-content .keypad-container .sendmax .button:active {
background-color: #445; }
#view-amount .scroll-content .keypad-container .keypad {
text-align: center;
font-size: 18px;
font-weight: lighter;
position: absolute;
bottom: 0;
width: 100%;
color: #667; }
@media (min-height: 667px) {
#view-amount .scroll-content .keypad-container .keypad {
font-size: 24px; } }
color: #fff; }
#view-amount .scroll-content .keypad-container .keypad .row {
padding: 0 !important;
margin: 0 !important; }
#view-amount .scroll-content .keypad-container .keypad .col {
line-height: 38px; }
@media (min-height: 667px) {
#view-amount .scroll-content .keypad-container .keypad .col {
line-height: 45px; } }
#view-amount .scroll-content .keypad-container .keypad .row:last-child .col {
padding-bottom: 10px; }
#view-amount .scroll-content .keypad-container .keypad .operator {
@ -10671,14 +10766,20 @@ qrcode {
background-color: #eaeaea; }
#view-amount .scroll-content .keypad-container .keypad .digit {
cursor: pointer;
border-top: 1px solid #f2f2f2;
border-left: 1px solid #f2f2f2;
background-color: #000;
border: 1px solid #262424;
transition: all 0.1s ease; }
#view-amount .scroll-content .keypad-container .keypad .digit:active {
background-color: #f2f2f2; }
@media (max-height: 480px) {
#view-amount .scroll-content .keypad-container .keypad {
font-size: 12px; } }
background-color: #445; }
#view-amount .scroll-content .button-primary {
background-color: #fab915;
border-radius: 0;
font-weight: bold; }
#view-amount .scroll-content .button-primary[disabled] {
background-color: #667;
opacity: 1; }
#view-amount .warning {
color: #b7664d; }
#view-amount ion-content {
margin-bottom: constant(safe-area-inset-bottom);
/* iOS 11.0 */
@ -10825,6 +10926,28 @@ qrcode {
width: 100%;
display: block; }
#tab-home .buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin: 6px auto -12px;
text-align: center;
width: 100%; }
#tab-home .buttons > .col {
padding: 5px 10px;
margin-bottom: 0; }
#tab-home .buttons .button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px; }
#tab-home .wallet-coin-logo {
vertical-align: middle;
margin-right: 5px; }
@ -11045,16 +11168,8 @@ qrcode {
background-color: #fab915 !important; }
#tab-send-header {
height: 300px;
width: 100%; }
#tab-send-contacts {
height: calc(100vh - 300px - 50px - 44px);
/* screen size - button container - bottom-tab-menu - header top */
overflow: scroll; }
#tab-send-contacts.ios {
height: calc(100vh - 300px - 50px - 44px - 18px); }
#tab-send .input {
width: 100%; }
#tab-send .input input {
@ -11118,7 +11233,9 @@ qrcode {
#tab-send .send-wrapper .buttons .button-clipboard-paste.contains-address .icon, #tab-send .send-wrapper .buttons .button-clipboard-paste.contains-content .icon {
background: url(../img/icon-clipboard-paste-white.svg); }
#tab-send .send-wrapper .buttons .button-clipboard-paste.contains-address.contains-address .address, #tab-send .send-wrapper .buttons .button-clipboard-paste.contains-content.contains-address .address {
display: inline; }
display: inline;
border: none;
background-color: transparent; }
#tab-send .send-wrapper .buttons .button-clipboard-paste.contains-address.contains-address .non-address, #tab-send .send-wrapper .buttons .button-clipboard-paste.contains-content.contains-address .non-address {
display: none; }
#tab-send .send-wrapper .buttons .button span {
@ -11233,14 +11350,62 @@ qrcode {
#tab-send .send-wrapper .buttons .button-qr {
height: 60px; }
#tab-send .send-wrapper .buttons .button-qr span {
font-size: 16px; }
#tab-send #tab-send-header {
height: 270px; }
#tab-send #tab-send-contacts {
height: calc(100vh - 270px - 50px - 44px);
/* screen size - button container - bottom-tab-menu - header top */ }
#tab-send #tab-send-contacts.ios {
height: calc(100vh - 270px - 50px - 44px - 18px); } }
font-size: 16px; } }
#wallet-origin-destination .header--request {
padding: 30px 24px;
width: 100%;
height: 139px;
background-color: #fff; }
#wallet-origin-destination .header--request__title {
width: 46px;
height: 20px;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.4px;
color: #000000; }
#wallet-origin-destination .header--request__amount {
font-size: 29px;
font-weight: 600;
letter-spacing: -0.7px;
color: #000000;
margin: 11px 0 2px; }
#wallet-origin-destination .header--request__amount-alt {
opacity: 0.45;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.4px;
color: #000000; }
#wallet-origin-destination .wallets-header {
margin: 20px 14px 0px; }
#wallet-origin-destination .wallets-header .title {
font-size: 16px;
font-weight: bold;
color: #445;
margin-bottom: -12px; }
#wallet-origin-destination .card {
font-size: 12px;
margin: 20px 14px 0px; }
#wallet-origin-destination .card .item-heading {
font-weight: 600; }
#wallet-origin-destination .card .item-heading .subtitle {
font-size: 12px; }
#wallet-origin-destination .card-insufficient .wallet {
opacity: 0.4; }
#wallet-origin-destination .card-insufficient .item-heading {
font-size: 12px; }
#wallet-origin-destination .card-insufficient .item-heading > div {
display: inline-block;
vertical-align: text-bottom; }
#wallet-origin-destination .card-insufficient__dot {
display: inline-block;
width: 16px;
height: 16px;
background-color: #ec5959;
border-radius: 8px;
margin: 2px 6px 2px 2px; }
.settings .icon-bitpay {
background-image: url("../img/icon-bitpay.svg"); }
@ -11753,10 +11918,11 @@ qrcode {
height: 100%;
height: calc(100% - env(safe-area-inset-bottom) * 2); }
#walletDetails .bp-content.status-bar {
margin-top: 20px; }
margin-top: 20px;
margin-top: env(safe-area-inset-top); }
#walletDetails .bar-header {
border: 0;
background: none; }
background: #eeb640; }
#walletDetails .bar-header .title, #walletDetails .bar-header .button {
color: #fff; }
#walletDetails .bar-header .button {
@ -11768,7 +11934,7 @@ qrcode {
top: 0;
margin-bottom: 16px; }
#walletDetails ion-content.collapsible {
margin-top: 210px; }
margin-top: 230px; }
#walletDetails ion-content .scroll {
background: #f8f8f9;
min-height: 300px; }
@ -11793,11 +11959,32 @@ qrcode {
height: 200px;
-webkit-transform: translateY(100px);
transform: translateY(100px); }
#walletDetails .amount-wrapper .send-receive-buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
width: 100%;
position: absolute;
bottom: 20px; }
#walletDetails .amount-wrapper .send-receive-buttons > .col {
padding: 5px 10px;
margin-bottom: 0; }
#walletDetails .amount-wrapper .send-receive-buttons .button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px; }
#walletDetails .amount {
width: 100%;
text-align: center;
color: #fff;
height: 210px;
height: 230px;
padding-top: 40px;
display: block;
align-items: center;
@ -11911,6 +12098,73 @@ a.item {
color: #667;
font-size: 0.9em; }
#shapeshift .swap-image {
width: auto;
max-width: 400px;
max-height: 25vh; }
#shapeshift .empty-case {
padding-top: 5vh;
text-align: center; }
#shapeshift .empty-case .item {
border-style: none; }
#shapeshift .empty-case > .title {
font-size: 20px;
color: #445;
margin: 20px 10px; }
#shapeshift .empty-case > .subtitle {
font-size: 1rem;
line-height: 1.5em;
font-weight: 300;
color: #6F6F70;
margin: 20px 1em 2.5em; }
#shapeshift .empty-case .big-icon-svg .bg.green {
padding: 0 10px;
box-shadow: none; }
#shapeshift .empty-case .buttons {
margin-top: 18px; }
#shapeshift .empty-case .buttons .button {
font-weight: bold;
font-size: 19px; }
#shapeshift .empty-case .button-first-contact img {
height: 19px;
width: 19px;
margin-right: 6px;
vertical-align: sub; }
#shapeshift .button-shapeshift {
border-color: #FFF;
background-color: #243F5D;
color: #FFF;
border: 0px;
box-shadow: 0 2px 11px 0 #C1C1C1; }
#shapeshift .button-shapeshift:hover {
color: #FFF;
text-decoration: none; }
#shapeshift .button-shapeshift.active, #shapeshift .button-shapeshift.activated {
border-color: #FFF;
background-color: #606060; }
#shapeshift .button-shapeshift.button-clear {
border-color: transparent;
background: none;
box-shadow: none;
color: #FFF; }
#shapeshift .button-shapeshift.button-icon {
border-color: transparent;
background: none; }
#shapeshift .button-shapeshift.button-outline {
border-color: #C1C1C1;
background: transparent;
color: #C1C1C1; }
#shapeshift .button-shapeshift.button-outline.active, #shapeshift .button-shapeshift.button-outline.activated {
background-color: #C1C1C1;
box-shadow: none;
color: #fff; }
.header.shapeshift {
background: url(../img/shapeshiftbg.jpg) center center repeat #28394d;
opacity: 0.99; }
#bitpayCard {
background: white; }
#bitpayCard .status-label {
@ -13790,11 +14044,6 @@ slide-to-accept-success {
display: flex;
align-items: center;
justify-content: center; }
slide-to-accept-success .slide-success__windows-background {
background: #11D1A6;
height: 100%;
width: 100%;
position: fixed; }
slide-to-accept-success .slide-success__background {
height: 10vmax;
width: 10vmax;
@ -13811,8 +14060,10 @@ slide-to-accept-success {
slide-to-accept-success .slide-success__content {
position: relative;
z-index: 1;
margin-top: -20vh; }
margin-top: -10vh; }
slide-to-accept-success .slide-success__content > img {
width: 45vw;
max-width: 166px;
margin-bottom: 1.8rem;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
@ -13825,7 +14076,7 @@ slide-to-accept-success {
opacity: 1; }
slide-to-accept-success .slide-success__content__header {
color: #FFFFFF;
font-size: 26px;
font-size: 29px;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
opacity: 0;
@ -13835,6 +14086,22 @@ slide-to-accept-success {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1; }
slide-to-accept-success .slide-success__content__share {
transition: transform 400ms ease, opacity 400ms ease;
transition-delay: 600ms;
opacity: 0;
margin-top: 15vh; }
slide-to-accept-success .slide-success__content__share span {
color: #FFF;
font-size: 22px;
height: 28px; }
slide-to-accept-success .slide-success__content__share img {
height: 28px;
width: auto;
vertical-align: bottom;
margin-right: 4px; }
slide-to-accept-success .slide-success__content__share.reveal {
opacity: 0.79; }
slide-to-accept-success .slide-success__footer {
position: absolute;
left: 0;
@ -13857,11 +14124,11 @@ slide-to-accept-success {
slide-to-accept-success .slide-success__footer__btn {
display: block;
color: #FFFFFF;
font-size: 18px;
font-size: 22px;
font-weight: 600;
letter-spacing: 2.86px;
padding: 1rem 0 1.1rem;
border-top: 1px solid rgba(255, 255, 255, 0.45);
padding: 2rem 0 2.1rem;
border-top: 1px solid rgba(255, 255, 255, 0.25);
cursor: pointer; }
#tx-details .action-created.action-accepted {
@ -14803,17 +15070,10 @@ account-selector {
height: 100%; }
#custom-amount .address .qr-code {
text-align: center;
margin-top: 24vh;
margin-bottom: 7vh; }
@media (max-height: 800px) {
#custom-amount .address .qr-code {
margin-top: 18vh; } }
@media (max-height: 700px) {
#custom-amount .address .qr-code {
margin-top: 14vh; } }
@media (max-height: 600px) {
#custom-amount .address .qr-code {
margin-top: 8vh; } }
margin-top: 6px; }
#custom-amount .address .qr-code qrcode canvas {
height: 30vh;
max-height: 220px; }
#custom-amount .address .info {
position: absolute;
width: 100%;
@ -14853,6 +15113,28 @@ account-selector {
margin-left: 10px; }
#custom-amount .address .address-types {
text-align: center; }
#custom-amount .address .amount {
margin-top: 20vh;
margin-bottom: 4vh;
width: 100%;
text-align: center;
display: block;
align-items: center;
justify-content: center; }
@media (max-height: 800px) {
#custom-amount .address .amount {
margin-top: 12vh;
margin-bottom: 6vh; } }
@media (max-height: 700px) {
#custom-amount .address .amount {
margin-top: 10vh;
margin-bottom: 4vh; } }
@media (max-height: 600px) {
#custom-amount .address .amount {
margin-top: 6vh;
margin-bottom: 2vh; } }
#custom-amount .address .amount-alternative {
line-height: 36px; }
#pin {
background-color: #FAFAFA;
@ -15077,22 +15359,203 @@ log-options #check-bar .checkbox-icon {
#view-review .fee-summary {
position: absolute;
bottom: 92px; }
#view-review .shapeshift-banner, #view-review .bitpay-banner, #view-review .egifter-banner {
box-shadow: none; }
#view-review .warning {
color: #b7664d; }
.gravatar {
border-radius: 3px;
display: inline-block; }
(??)
.elastic {
width: 100%;
font-size: 14px; }
(??)
/*
* Extends Ionic v1 item
*/
.item.item-compact {
padding: 11px 13px; }
(??)
.item.item-gutterless {
padding: 0; }
(??)
.item .item-content.item-content-avatar {
min-height: 69px;
padding: 13px 11px 13px 68px; }
.item .item-content.item-content-avatar > img:first-child,
.item .item-content.item-content-avatar > i:first-child {
position: absolute;
max-width: 40px;
max-height: 40px;
width: 100%;
height: 100%;
border-radius: 50%;
left: 13px;
top: 50%;
padding: 0;
transform: translate(0, -50%); }
(??)
.item .item-content.item-content-compact {
min-height: 0;
padding: 13px 11px; }
(??)
.item .item-content .highlight {
color: #FAB915; }
.item .item-content + .item-content {
padding-top: 0; }
/*
* Extends Ionic v1 ion-content
*/
ion-content.bg-neutral {
background-color: #F2F2F2; }
ion-content.padded-bottom-cta {
bottom: 92px; }
ion-content.padded-bottom-cta-with-summary {
bottom: 134px; }
.card.card-gutter-compact {
margin: 10px 12px; }
.header {
padding: 29px 12px 61px;
background-color: #fab915;
color: #FFFFFF; }
.header.btc {
background-color: #535353; }
.header .title {
font-size: 18px;
font-weight: 400;
line-height: 1em;
color: #FFFFFF;
text-align: center; }
.header .title + .content {
margin-top: 23px; }
.header .content {
text-align: center; }
.header .content p {
margin: 0;
line-height: 1em;
font-size: 18px; }
.header .content p.large {
font-size: 29px;
font-weight: 600; }
.header .content p + p {
margin-top: 8px; }
.content-frame.negative-top {
margin-top: -40px; }
.content-frame.negative-top .card:first-child {
margin-top: 0; }
.address-frame {
background-color: #F8F8F8;
border: 0.5px solid #EDEBEB;
border-radius: 3px;
padding: 9px;
text-align: center;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis; }
.address-frame.expanded {
white-space: pre-wrap;
word-break: break-all; }
.address-frame .prefix {
color: #000000; }
.address-frame .mid {
color: #919191; }
.address-frame .suffix {
color: #000000; }
.action-minor {
margin: 20px 14px;
font-size: 14px; }
.action-minor.mt-negative {
margin-top: 0; }
.action-minor.text-right {
text-align: right; }
.action-minor > .action-icon {
width: 15px;
height: 15px;
vertical-align: middle;
margin-right: 3px; }
.action-minor > .action-text {
vertical-align: middle;
color: #444444; }
.expand-content-frame {
position: relative; }
.expand-content-frame .expand-content-trigger {
position: absolute;
top: 0;
transition: opacity 0.3s ease;
right: 0; }
.expand-content-frame .expand-content-trigger.expand-content-revealed {
opacity: 0; }
.expand-content-frame .expand-content {
opacity: 0;
transform-origin: 100% 0%;
transform: scale(0, 0);
transition: opacity 0.3s ease, transform 0.3s ease; }
.expand-content-frame .expand-content.expand-content-revealed {
opacity: 1;
transform: scale(1, 1); }
.fee-summary {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
padding: 5px 12px 15px;
box-sizing: border-box;
background-color: #F2F2F2; }
.fee-summary:before {
content: '';
position: absolute;
left: 0;
top: -15px;
width: 100%;
height: 15px;
background: linear-gradient(to bottom, rgba(242, 242, 242, 0) 0%, #f2f2f2 100%); }
.fee-summary .amount {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%; }
.fee-summary .amount .fee-fiat.positive {
color: #70955F; }
.fee-summary .amount .fee-fiat.negative {
color: #C24633; }
.fee-summary .amount .fee-crypto {
color: #A7A7A7; }
.formatted-amount {
display: inline-block; }
.formatted-amount .start,
.formatted-amount .middle,
.formatted-amount .end,
.formatted-amount .currency {
display: inline-block; }
.formatted-amount .start {
font-size: 1em; }
.formatted-amount .middle {
font-size: 0.7857em;
margin-left: 5px; }
.formatted-amount .end {
font-size: 0.7857em;
margin-left: 5px; }
.formatted-amount.size-equal .middle,
.formatted-amount.size-equal .end {
font-size: 1em; }
.formatted-amount .currency {
font-size: 1em;
margin-left: 5px;
text-transform: uppercase; }
/* This is for rules that don't yet have a home.
* Our goal is to delete this file. Search the regex: /class=".*CLASS.*?"/
@ -15275,6 +15738,9 @@ input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer
.size-24 {
font-size: 24px; }
.size-25 {
font-size: 25px; }
.size-28 {
font-size: 28px; }
@ -15449,3 +15915,6 @@ input[type=file] {
.white-space-initial {
white-space: initial; }
.height-spacer {
height: 15px; }

13
www/img/bitpay_banner.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
www/img/egifter_banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="17px" height="17px" viewBox="0 0 17 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>3A719124-019D-470F-908A-5D61F117A295</title>
<desc>Created with sketchtool.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icons" transform="translate(-324.000000, -770.000000)" stroke="#000000" stroke-width="0.7">
<g id="icons/list-items/sync" transform="translate(324.000000, 770.000000)">
<g id="Group" transform="translate(0.365217, 0.365217)">
<polyline id="Shape" points="10.5913043 11.6869565 0 11.6869565 0 0 16.0695652 0 16.0695652 7.96173913"></polyline>
<ellipse id="Oval" cx="8.03478261" cy="5.84347826" rx="1.46086957" ry="1.46086957"></ellipse>
<path d="M13.8782609,6.57391304 L13.8782609,4.3826087 C12.6365217,4.3826087 11.6869565,3.43304348 11.6869565,2.19130435 L4.3826087,2.19130435 C4.3826087,3.43304348 3.43304348,4.3826087 2.19130435,4.3826087 L2.19130435,7.30434783 C3.43304348,7.30434783 4.3826087,8.25391304 4.3826087,9.49565217 L10.5913043,9.49565217" id="Shape"></path>
<path d="M15.0469565,13.5130435 C15.6313043,13.8052174 16.0695652,14.1704348 16.0695652,14.6086957 C16.0695652,15.4121739 14.7547826,16.0695652 13.1478261,16.0695652 C11.5408696,16.0695652 10.226087,15.4121739 10.226087,14.6086957 C10.226087,14.1704348 10.5913043,13.8052174 11.2486957,13.5130435" id="Shape"></path>
<path d="M15.0469565,11.3217391 C15.6313043,11.613913 16.0695652,11.9791304 16.0695652,12.4173913 C16.0695652,13.2208696 14.7547826,13.8782609 13.1478261,13.8782609 C11.5408696,13.8782609 10.226087,13.2208696 10.226087,12.4173913 C10.226087,11.9791304 10.5913043,11.613913 11.1756522,11.3217391" id="Shape"></path>
<path d="M15.0469565,9.13043478 C15.6313043,9.4226087 16.0695652,9.78782609 16.0695652,10.226087 C16.0695652,11.0295652 14.7547826,11.6869565 13.1478261,11.6869565 C11.5408696,11.6869565 10.226087,11.0295652 10.226087,10.226087 C10.226087,9.78782609 10.5913043,9.4226087 11.1756522,9.13043478" id="Shape"></path>
<ellipse id="Oval" cx="13.1478261" cy="8.03478261" rx="2.92173913" ry="1.46086957"></ellipse>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
www/img/icon-egifter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 166">
<defs>
<style>
.cls-1 {
fill: #fff;
}
</style>
</defs>
<path id="_ionicons_svg_md-checkmark-circle-outline" class="cls-1" d="M96.969,115.231,85.35,126.85,122.7,164.2l83-83L194.081,69.581,122.7,140.544,96.969,115.231ZM197.4,131a66.116,66.116,0,1,1-48.138-63.91l12.863-12.865A77.206,77.206,0,0,0,131,48a83,83,0,1,0,83,83Z" transform="translate(-48 -48)"/>
</svg>

After

Width:  |  Height:  |  Size: 458 B

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="56 56 400 400" enable-background="new 56 56 400 400" xml:space="preserve">
<g>
<g>
<path fill="#FFFFFF" d="M350.833,297.017c-17.517,0-32.967,8.346-43.062,21.124l-93.629-47.881
c1.226-4.571,2.106-9.296,2.106-14.267c0-5.412-1.046-10.507-2.506-15.465l93.216-47.661
c10.039,13.358,25.889,22.089,43.888,22.089c30.489,0,55.153-24.664,55.153-55.125c0-30.435-24.664-55.112-55.152-55.112
c-30.42,0-55.111,24.677-55.111,55.111c0,4.985,0.882,9.723,2.12,14.308l-93.615,47.882
c-10.108-12.793-25.587-21.166-43.131-21.166c-30.462,0-55.111,24.691-55.111,55.139c0,30.447,24.65,55.125,55.111,55.125
c18.026,0,33.863-8.758,43.943-22.129l93.174,47.66c-1.46,4.943-2.52,10.081-2.52,15.507c0,30.447,24.691,55.125,55.111,55.125
c30.489,0,55.152-24.678,55.152-55.125C405.985,321.681,381.322,297.017,350.833,297.017z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
www/img/shapeshift_swap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

View file

@ -1,82 +1,99 @@
<ion-view id="view-amount" hide-tabs>
<ion-nav-bar class="bar-royal">
<ion-nav-title>
{{'Enter amount' | translate}}
{{'Enter Amount' | translate}}
</ion-nav-title>
<ion-nav-back-button ng-click="goBack()"></ion-nav-back-button>
<ion-nav-back-button ng-click="vm.goBack()"></ion-nav-back-button>
</ion-nav-bar>
<ion-content scroll="false" style="background: #fff;">
<ion-content scroll="false">
<div style="order: 0; position: relative;">
<div class="item send-amount">
<div ng-if="shapeshiftOrderId">
Minimum amount: {{minShapeshiftAmount}} <br/>
Maximum amount: {{maxShapeshiftAmount}} <br/>
<div class="card item send-amount">
<div class="send-amount-header-footer">
<span class="send-amount-header-footer__min" ng-if="vm.minAmount">Min: {{vm.minAmount}}</span> <span class="send-amount-header-footer__max" ng-if="vm.maxAmount">Max: {{vm.maxAmount}}</span>
</div>
<div class="send-amount-tool">
<div class="send-amount-tool-input amount">
<div class="primary-amount"
ng-class="{long: amountModel.amount.length > 5, 'very-long': amountModel.amount.length > 10}">
<span class="primary-amount-display text-selectable">{{ amountModel.amount || 0 }}</span><span class="unit">{{unit}}</span>
ng-class="{long: vm.amount.length > 5, 'very-long': vm.amount.length > 8}">
<span class="primary-amount-display text-selectable">
{{vm.amount || '0'}} {{vm.unit}}
</span>
</div>
<span ng-show="globalResult">{{globalResult}} {{unit}}</span>
<span ng-show="vm.globalResult"><formatted-amount value="{{vm.globalResult}}" currency="{{vm.unit}}"></formatted-amount></span>
<div class="alternative-amount">
<span class="text-selectable">{{alternativeAmount || '0.00'}}</span> <span>{{alternativeUnit}}</span>
<span class="text-selectable">{{vm.alternativeAmount || '0.00'}} {{vm.alternativeUnit}}</span>
</div>
<div class="switch-currencies" ng-click="changeUnit()"><img src="img/icon-convert.svg"></div>
<div class="switch-currencies" ng-click="vm.changeUnit()"><img src="img/icon-convert.svg"></div>
</div>
<div class="send-amount-actions text-center">
<button class="button button-sendmax" ng-click="sendMax()">
<span>
<i class="icon ion-ios-speedometer-outline"></i>&emsp;
<span translate>Send max amount</span>
</span>
</button>
<button class="button button-sendmax" ng-click="openPopup()">
<span>
<i class="icon ion-social-usd"></i>&emsp;
<span translate>Change currency</span>
</span>
</button>
<div class="send-amount-header-footer">
<div class="warning" ng-show="vm.errorMessage">
{{vm.errorMessage}}
</div>
</div>
</div>
</div>
<div class="send-amount-extras text-center">
<div class="extra change-currency">
<button class="button" ng-click="vm.openPopup()">
<span>
<img src="img/icon-alternative-currency-black.svg"/>
<pre> </pre>
<span translate>Change Currency</span>
</span>
</button>
</div>
<div class="extra available-funds"
ng-class="{warning: vm.fundsAreInsufficient}"
ng-if="!vm.isRequestingSpecificAmount" translate>
<span translate>Available Funds</span>: <span><formatted-amount value="{{vm.availableFunds}}" size-equal="true"></formatted-amount></span>
</div>
</div>
</div>
</div>
<div class="keypad-container" style="background: #fff; position: absolute; bottom: 0; margin-bottom: 57px; width: 100%;">
<div class="keypad" style="background: #f2f2f2; position: relative;">
<div class="sendmax" ng-if="vm.availableFunds && !vm.isRequestingSpecificAmount">
<button class="button button-sendmax" ng-click="vm.sendMax()">
<span>
<span translate>Use All Available Funds</span>&ensp;
<span class="available-funds-amount">(<formatted-amount value="{{vm.availableFunds}}"></formatted-amount>)</span>
</span>
</button>
</div>
<div class="keypad" style="position: relative;">
<div class="row">
<div class="col digit" ng-click="pushDigit('7')">7</div>
<div class="col digit" ng-click="pushDigit('8')">8</div>
<div class="col digit" ng-click="pushDigit('9')">9</div>
<div class="col digit" ng-click="vm.pushDigit('7')">7</div>
<div class="col digit" ng-click="vm.pushDigit('8')">8</div>
<div class="col digit" ng-click="vm.pushDigit('9')">9</div>
</div>
<div class="row">
<div class="col digit" ng-click="pushDigit('4')">4</div>
<div class="col digit" ng-click="pushDigit('5')">5</div>
<div class="col digit" ng-click="pushDigit('6')">6</div>
<div class="col digit" ng-click="vm.pushDigit('4')">4</div>
<div class="col digit" ng-click="vm.pushDigit('5')">5</div>
<div class="col digit" ng-click="vm.pushDigit('6')">6</div>
</div>
<div class="row">
<div class="col digit" ng-click="pushDigit('1')">1</div>
<div class="col digit" ng-click="pushDigit('2')">2</div>
<div class="col digit" ng-click="pushDigit('3')">3</div>
<div class="col digit" ng-click="vm.pushDigit('1')">1</div>
<div class="col digit" ng-click="vm.pushDigit('2')">2</div>
<div class="col digit" ng-click="vm.pushDigit('3')">3</div>
</div>
<div class="row">
<div class="col digit" ng-click="pushDigit('.')">.</div>
<div class="col digit" ng-click="pushDigit('0')">0</div>
<div class="col digit icon ion-backspace-outline" ng-click="removeDigit()"></div>
<div class="col digit" ng-click="vm.pushDigit('.')">.</div>
<div class="col digit" ng-click="vm.pushDigit('0')">0</div>
<div class="col digit icon ion-backspace-outline" ng-click="vm.removeDigit()"></div>
</div>
</div>
</div>
<button
class="button button-full button-primary no-margin"
ng-disabled="!allowSend"
ng-click="finish()"
ng-disabled="!vm.allowSend"
ng-click="vm.next()"
style="position: absolute; bottom: 0;"
translate>
Next

View file

@ -105,13 +105,13 @@
</ion-content>
<click-to-accept
ng-click="approve(tx, wallet, statusChangeHandler)"
ng-if="(!isCordova || isWindowsPhoneApp) && wallet"
ng-if="(!isCordova) && wallet"
click-send-status="sendStatus"
is-disabled="!wallet">
{{buttonText}}
</click-to-accept>
<slide-to-accept
ng-if="isCordova && !isWindowsPhoneApp && wallet"
ng-if="isCordova && wallet"
slide-on-confirm="approve(tx, wallet, statusChangeHandler)"
slide-send-status="sendStatus"
is-disabled="!wallet">
@ -120,6 +120,7 @@
<slide-to-accept-success
slide-success-show="sendStatus === 'success'"
slide-success-on-confirm="onSuccessConfirm()"
slide-success-on-share="shareTransaction"
slide-success-hide-on-confirm="true">
<span ng-show="wallet.m == 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Payment Sent</span>
<span ng-show="wallet.m > 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Proposal Created</span>

View file

@ -30,8 +30,22 @@
<br/>Return To Address<br/>
</p>
</div>
<div ng-show="!showingPaymentReceived" class="amount">
<div ng-show="selectedPriceDisplay=='fiat'">
<span class="size-36"><formatted-amount value="{{amountUnitStr}}"></formatted-amount></span>
<div class="size-14 amount-alternative">
<formatted-amount value="{{altAmountStr | uppercase}}"></formatted-amount>
</div>
</div>
<div ng-show="selectedPriceDisplay=='crypto'">
<span class="size-36"><formatted-amount value="{{altAmountStr | uppercase}}"></formatted-amount></span>
<div class="size-14 amount-alternative">
<formatted-amount value="{{amountUnitStr}}"></formatted-amount>
</div>
</div>
</div>
<div ng-show="!showingPaymentReceived" class="qr-code" copy-to-clipboard="copyToClipboard()">
<qrcode size="220" data="{{ protocolHandler }}:{{address + '?amount=' + amountBtc}}" color="#334"></qrcode>
<qrcode class="qr-overlay qr-overlay--{{ wallet.coin }}" size="220" data="{{ protocolHandler }}:{{address + '?amount=' + amountBtc}}" color="#334"></qrcode>
</div>
<div ng-show="!showingPaymentReceived" ng-show="address && coin == 'bch'" class="address-types">
<div>
@ -57,12 +71,6 @@
{{address}}
</span>
</div>
<div class="item single-line">
<span class="label" translate>Amount</span>
<span class="item-note">
{{amountUnitStr}} - {{altAmountStr}}
</span>
</div>
<div class="item single-line">
<div class="wallet">
<i class="icon big-icon-svg" ng-include="'views/includes/walletIcon.html'"></i>

View file

@ -1,4 +1,4 @@
<div class="amount"
ng-class="{ 'size-equal': displaySizeEqual }">
<span ng-if="start.length > 0" class="start">{{start}}</span><span ng-if="middle.length > 0" class="middle">{{middle}}</span><span ng-if="end.length > 0" class="end">{{end}}</span><span ng-if="currency.length > 0" class="currency">{{currency}}</span>
<div class="formatted-amount"
ng-class="{ 'size-equal': displaySizeEqual }" ng-show="canShow">
<span ng-if="start.length > 0" class="start">{{start}}</span><span ng-if="middle.length > 0" class="middle">{{middle}}</span><span ng-if="end.length > 0" class="end">{{end}}</span><span ng-if="vm.currency.length > 0" class="currency">{{vm.currency}}</span>
</div>

View file

@ -1,13 +1,16 @@
<div
class="slide-success__background"
ng-class="{'fill-screen': fillScreen, 'slide-success__windows-background': isWindowsPhoneApp}">
ng-class="{'fill-screen': fillScreen}">
</div>
<div ng-disabled="wallet" class="slide-success__content">
<img src="img/onboarding-success.svg" ng-class="{reveal: fillScreen}">
<img src="img/icon-sent-successful.svg" ng-class="{reveal: fillScreen}">
<div class="slide-success__content__header" ng-class="{reveal: fillScreen}">
<ng-transclude>Payment Sent</ng-transclude>
</div>
<div class="slide-success__content__share" ng-if="hasShareFunction" ng-class="{reveal: fillScreen}" ng-click="onShareButtonClick()">
<span><img src="img/icon-share-white.svg"></span><span translate>Share this transaction</span>
</div>
</div>
<div class="slide-success__footer" ng-class="{reveal: fillScreen}">

Some files were not shown because too many files have changed in this diff Show more