Skip to content

Commit

Permalink
Merge branch 'testnet' into desktop
Browse files Browse the repository at this point in the history
  • Loading branch information
shrpne committed Jun 26, 2019
2 parents 18fcb96 + 94e1899 commit 92153ac
Show file tree
Hide file tree
Showing 42 changed files with 6,303 additions and 2,816 deletions.
6 changes: 5 additions & 1 deletion api/accounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export default instance;
* @param {TokenData} tokenData
*/
export function setAuthToken(tokenData) {
instance.defaults.headers = JSON.parse(JSON.stringify(instance.defaults.headers)); // unset links from core object, will be fixed in https://github.com/axios/axios/pull/1395
instance.defaults.headers.common['Authorization'] = tokenData.tokenType + ' ' + tokenData.accessToken;
localStorage.setItem(TOKEN_KEY, JSON.stringify(tokenData));
}
Expand All @@ -33,3 +32,8 @@ export function resetAuthToken() {
export function hasAuthToken() {
return 'Authorization' in instance.defaults.headers.common;
}


export function getCoinIconUrl(coinSymbol) {
return `${ACCOUNTS_API_URL}avatar/by/coin/${coinSymbol}`;
}
16 changes: 6 additions & 10 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {addressEncryptedFromMnemonic, getPasswordToSend, getPasswordToStore} fro
import accounts from '~/api/accounts';
import explorer from '~/api/explorer';
import autoDelegation from '~/api/auto-delegation';
import {COIN_NAME} from '~/assets/variables';

const formDataHeaders = {'Content-Type': 'multipart/form-data'};

Expand Down Expand Up @@ -92,13 +93,6 @@ export function putProfileAvatar(avatar) {
}


export function postLinkConfirmation({id, code}) {
const methodUrl = 'profile/link/' + id + '/confirm';
return accounts.post(methodUrl, {
'code': code,
}).then((response) => response.data.data);
}


/**
* @typedef {Object} TransactionListInfo
Expand All @@ -125,10 +119,12 @@ export function getAddressTransactionList(address, params = {}) {
*/
export function getBalance(addressHash) {
return explorer.get('addresses/' + addressHash)
.then((response) => response.data.data.balances.sort((coinItem) => {
// set MNT first
if (coinItem.coin === 'MNT') {
.then((response) => response.data.data.balances.sort((a, b) => {
// set base coin first
if (a.coin === COIN_NAME) {
return -1;
} else if (b.coin === COIN_NAME) {
return 1;
} else {
return 0;
}
Expand Down
166 changes: 166 additions & 0 deletions assets/fee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import Vue from 'vue';
import Big from 'big.js';
import {getFeeValue} from 'minterjs-util/src/fee';
import {COIN_NAME} from '~/assets/variables';
import {estimateCoinBuy} from '~/api/gate';


let coinPricePromiseList = {};

/**
* @typedef {Object} FeeData
* @property {boolean} isBaseCoin
* @property {number|string} baseCoinValue
* @property {number|string} value
* @property {string} coinSymbol
*/

/**
*
* @param {string} txType
* @param {Object} [txFeeOptions]
* @param {number} [messageLength]
* @param {string} [selectedCoinSymbol]
* @param {string} [selectedFeeCoinSymbol]
* @param {number} [baseCoinAmount]
* @param {boolean} [isOffline]
* @return {Vue}
* @constructor
*/

export default function FeeBus({txType, txFeeOptions, messageLength = 0, selectedCoinSymbol, selectedFeeCoinSymbol, baseCoinAmount = 0, isOffline}) {
return new Vue({
data: {
txType,
txFeeOptions,
messageLength,
selectedCoinSymbol,
selectedFeeCoinSymbol,
baseCoinAmount,
coinPriceList: {},
isOffline,
},
computed: {
baseCoinFeeValue() {
return getFeeValue(this.txType, this.messageLength, this.txFeeOptions) || 0;
},
isBaseCoinEnough() {
return baseCoinAmount >= this.baseCoinFeeValue;
},
isBaseCoinFee() {
// use selectedFeeCoinSymbol if it is defined
if (this.selectedFeeCoinSymbol && this.selectedFeeCoinSymbol !== COIN_NAME) {
return false;
}
// no coins selected: show base
if (!this.selectedCoinSymbol) {
return true;
}
// base coin is selected or it is enough to pay fee
return this.selectedFeeCoinSymbol === COIN_NAME || this.selectedCoinSymbol === COIN_NAME || this.isBaseCoinEnough;
},
feeValue() {
if (this.isBaseCoinFee) {
return this.baseCoinFeeValue;
} else {
const coinEstimation = this.coinPriceList[this.feeCoinSymbol];
if (coinEstimation) {
return new Big(coinEstimation.coinAmount).div(coinEstimation.baseCoinAmount).times(this.baseCoinFeeValue);
} else {
return 0;
}
}
},
feeCoinSymbol() {
// use selectedFeeCoinSymbol if it is defined
if (this.selectedFeeCoinSymbol) {
return this.selectedFeeCoinSymbol;
}
if (this.isBaseCoinFee) {
return COIN_NAME;
} else {
return this.selectedCoinSymbol;
}
},
fee() {
return {
baseCoinValue: this.baseCoinFeeValue,
isBaseCoin: this.isBaseCoinFee,
isBaseCoinEnough: this.isBaseCoinEnough,
value: this.feeValue,
coinSymbol: this.feeCoinSymbol,
};
},
},
watch: {
fee: {
handler(newVal) {
this.$emit('updateFee', newVal);
},
deep: true,
},
},
created() {
this.$on('updateParams', function(params) {
Object.keys(params).forEach((key) => {
this[key] = params[key];
});
if (this.isOffline) {
return;
}
// wait for computed to recalculate
this.$nextTick(() => {
if (!this.isBaseCoinFee) {
const feeCoinSymbol = this.feeCoinSymbol;
getEstimation(feeCoinSymbol, this.baseCoinFeeValue)
.then((result) => this.$set(this.coinPriceList, feeCoinSymbol, result));
}
});
});
},
});
}


/**
* is older than 1 min?
* @param coinPricePromise
* @return {boolean}
*/
function isEstimationOutdated(coinPricePromise) {
return coinPricePromise.timestamp && (Date.now() - coinPricePromise.timestamp) > 60 * 1000;
}

/**
*
* @param coinSymbol
* @param baseCoinAmount
* @return {Promise<{coinSymbol: string, coinAmount: string, baseCoinAmount: string}>}
*/
function getEstimation(coinSymbol, baseCoinAmount) {
// if estimation exists and not outdated return it
if (coinPricePromiseList[coinSymbol] && !isEstimationOutdated(coinPricePromiseList[coinSymbol])) {
return coinPricePromiseList[coinSymbol].promise;
}

coinPricePromiseList[coinSymbol] = {};
coinPricePromiseList[coinSymbol].promise = estimateCoinBuy({
coinToSell: coinSymbol,
valueToBuy: baseCoinAmount,
coinToBuy: COIN_NAME,
})
.then((result) => {
coinPricePromiseList[coinSymbol].timestamp = Date.now();
return {
coinSymbol,
coinAmount: result.will_pay,
baseCoinAmount,
};
})
.catch((e) => {
delete coinPricePromiseList[coinSymbol];
throw e;
});

return coinPricePromiseList[coinSymbol].promise;
}
13 changes: 3 additions & 10 deletions assets/img/icon-qr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions assets/less/include/general.less
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ dd {overflow-wrap: break-word; margin: 0;}
.is-error > & {border-color: @c-red;}
.form-field--dashed > & {border-bottom-style: dashed;}
.form-field--with-icon > & {padding-right: 26px;}
.form-field--with-use-max > & {padding-right: 65px;}
}
.form-field__input--select {appearance: none; background: url(../img/icon-dropdown.svg) no-repeat 100% 50%; padding-right: 24px;}
.form-field__label {
Expand All @@ -249,6 +250,7 @@ dd {overflow-wrap: break-word; margin: 0;}
.form-field__input:focus ~ & {color: @c-main;}
.form-field.is-error > & {color: @c-red;}
}
.form-field__use-max {position: absolute; right: 0; top: (4px + @field-padding); z-index: 1; cursor: pointer; pointer-events: auto; text-transform: uppercase; font-weight: 700;}
.form-field__icon {position: absolute; right: 0; top: (2px + @field-padding); z-index: 1; cursor: pointer; pointer-events: auto; font-size: 0;}
.form-field__icon--copy {top: calc((100% - 12px) / 2 - 2px);}
.form-field__help {
Expand Down
33 changes: 31 additions & 2 deletions assets/less/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
from {transform: scale(.98);}
to {transform: scale(1.01);}
}
// qr-modal
.qr-modal {padding-left: 0; padding-right: 0; width: auto;}
.qr-modal__layer {
padding: 20px; background: #fff;
canvas {vertical-align: top;}
}
// file-input
.file-input {opacity: 0; position: absolute; width: 100%; height: 100%; left: 0; top: 0; font-size: 0; cursor: pointer;}
.file-input__drag-layer {
Expand Down Expand Up @@ -73,6 +79,11 @@
svg {fill: currentColor; vertical-align: top;}
}
.u-icon--copy--right {margin-left: 16px;}
.u-icon--qr {
display: inline-block; vertical-align: middle; flex: 0 0 30px; width: 30px;
svg {fill: currentColor; vertical-align: top;}
}
.u-icon--qr--right {margin-left: 8px;}


// nuxt page transition
Expand Down Expand Up @@ -115,6 +126,18 @@
}



.testnet-notice {background: #F13C3C; color: #fff; padding-top: 12px; padding-bottom: 12px; box-shadow: inset 0 -2px 0 #BD1A1A;}
.testnet-notice__container {display: flex; align-items: center; justify-content: center;}
.testnet-notice__icon {font-size: 20px; line-height: 1; flex-shrink: 0;}
.testnet-notice__caption {font-weight: 700; text-transform: uppercase; font-size: 13px; line-height: 1.2; margin: -2px 14px 0;}
@media (min-width: @breakpoint-small-up) {
.testnet-notice__icon {font-size: 30px;}
.testnet-notice__caption {font-size: 18px; margin: -4px 20px 0;}
}



@header-height: 64px;
.header {box-shadow: 0 2px 5px rgba(0,0,0,0.1); background: #2c2c2c; color: #fff; width: 100%;}
.header__container {display: flex; justify-content: space-between; align-items: center; height: @header-height;}
Expand Down Expand Up @@ -205,7 +228,10 @@

.wallet__info {background: #2C2C2C; color: #fff; }
.wallet__value {font-size: 20px; line-height: 1.25; font-weight: 700; margin-top: 1px;}
.wallet__address {display: flex; align-items: center; margin-bottom: 20px;}
.wallet__address {
display: flex; align-items: center; margin-bottom: 20px;
&:only-child {margin-bottom: 0;}
}
.wallet__address-icon {margin-right: 24px; flex-shrink: 0; margin-top: 4px;}
.wallet__address-content {overflow: hidden;}
.wallet__balance {flex-grow: 2;}
Expand All @@ -214,7 +240,10 @@

@media (min-width: @breakpoint-xlarge-up) {
.wallet__info {display: flex; justify-content: space-between;}
.wallet__address {flex-grow: 1; margin-right: 24px; margin-bottom: 0;}
.wallet__address {
flex-grow: 1; margin-right: 24px; margin-bottom: 0;
&:only-child {margin-right: 0;}
}
}


Expand Down
47 changes: 41 additions & 6 deletions assets/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import parseISO from "date-fns/esm/parseISO";
import format from "date-fns/esm/format";
import decode from 'entity-decode';
import prettyNum from 'pretty-num';
import prettyNum, {PRECISION_SETTING} from 'pretty-num';
import stripZeros from 'pretty-num/src/strip-zeros';
import fromExponential from 'from-exponential';
import {txTypeList} from 'minterjs-tx/src/tx-types';
import {EXPLORER_HOST} from "~/assets/variables";

Expand Down Expand Up @@ -76,20 +78,42 @@ export function getExplorerValidatorUrl(pubKey) {
* @return {string}
*/
export function pretty(value) {
if (value > 0.001 || value < -0.001 || Number(value) === 0) {
return decode(prettyNum(value, {precision: 4, rounding: 'fixed', thousandsSeparator: '&#x202F;'}));
const PRECISION = 2;
if (value >= 1 || value <= -1 || Number(value) === 0) {
return decode(prettyNum(value, {precision: PRECISION, precisionSetting: PRECISION_SETTING.FIXED, thousandsSeparator: '&#x202F;'}));
} else {
return decode(prettyNum(value, {precision: 2, rounding: 'significant', thousandsSeparator: '&#x202F;'}));
value = decode(prettyNum(value, {precision: PRECISION, precisionSetting: PRECISION_SETTING.REDUCE_SIGNIFICANT, thousandsSeparator: '&#x202F;'}));
value = value.substr(0, 10);
if (value === '0.00000000') {
return '0.00';
}
return value;
}
}

/**
* Ensure value to have from 2 to 8 decimal digits
* @param {string|number} value
* @return {string}
*/
export function prettyPrecise(value) {
const parts = stripZeros(fromExponential(value)).split('.');
const isReduced = parts[1] && parts[1].length > 2;
if (isReduced) {
return decode(prettyNum(value, {precision: 8, precisionSetting: PRECISION_SETTING.REDUCE, thousandsSeparator: '&#x202F;'}));
} else {
// ensure at least 2 decimal digits
return decode(prettyNum(value, {precision: 2, precisionSetting: PRECISION_SETTING.FIXED, thousandsSeparator: '&#x202F;'}));
}
}

/**
* Ensure value to have minimum 4 decimal digits
* Ensure value to have minimum 2 decimal digits
* @param {string|number} value
* @return {string}
*/
export function prettyExact(value) {
return decode(prettyNum(value, {precision: 4, rounding: 'increase', thousandsSeparator: '&#x202F;'}));
return decode(prettyNum(value, {precision: 2, precisionSetting: PRECISION_SETTING.INCREASE, thousandsSeparator: '&#x202F;'}));
}

/**
Expand Down Expand Up @@ -118,6 +142,17 @@ export function txTypeFilter(value) {
}


export function fromBase64(str) {
//@TODO utf8 https://github.com/dankogai/js-base64
const asci = window.atob(str);
try {
return decodeURIComponent(escape(asci));
} catch (e) {
return asci;
}
}



// support
export let support = {};
Expand Down
Loading

0 comments on commit 92153ac

Please sign in to comment.