Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

581 market fees #665

Merged
merged 12 commits into from
Oct 30, 2017
3 changes: 2 additions & 1 deletion app/assets/locales/locale-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"copy_password": "Click here to copy the password to your clipboard",
"sync_yes": "The current node is in sync with the blockchain",
"sync_no": "The current node is out of sync with the blockchain, try switching to another one",
"disconnected": "You are not connected to an API node, try reloading or setting a new access point in the Settings"
"disconnected": "You are not connected to an API node, try reloading or setting a new access point in the Settings",
"market_fee": "The owner of %(asset)s charges a market fee of %(percent)s%% for buy orders. This fee will be subtracted from the amount you receive when your order fills, it is not paid when placing an order."
},
"propose": "Propose",
"cancel": "Cancel",
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/vendors/_perfect-scrollbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
display: none;
position: absolute;
/* please don't change 'position' */
opacity: 0;
opacity: 0.6;
-webkit-transition: background-color .2s linear, opacity .2s linear;
-o-transition: background-color .2s linear, opacity .2s linear;
-moz-transition: background-color .2s linear, opacity .2s linear;
Expand Down
2 changes: 1 addition & 1 deletion app/components/Account/AccountAssetCreate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class AccountAssetCreate extends React.Component {
break;

case "max_market_fee":
if ((new big(inputValue)).times(Math.pow(10, precision)).gt(GRAPHENE_MAX_SHARE_SUPPLY)) {
if ((new big(inputValue)).times(precision).gt(GRAPHENE_MAX_SHARE_SUPPLY)) {
errors.max_market_fee = "The number you tried to enter is too large";
return this.setState({errors});
}
Expand Down
2 changes: 1 addition & 1 deletion app/components/Account/AccountAssetUpdate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class AccountAssetUpdate extends React.Component {

case "max_market_fee":
let marketFee = e.amount.replace(/,/g, "");
if ((new big(marketFee)).times(Math.pow(10, precision)).gt(GRAPHENE_MAX_SHARE_SUPPLY)) {
if ((new big(marketFee)).times(precision).gt(GRAPHENE_MAX_SHARE_SUPPLY)) {
updateState = false;
return this.setState({errors: {max_market_fee: "The number you tried to enter is too large"}});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ class BlockTradesBridgeDepositRequest extends React.Component {
let conversion_limit = this.getCachedOrFreshDepositLimit("conversion", conversion_input_coin_type, conversion_output_coin_type);

if (this.unMounted) return;

this.setState({
coin_info_request_state: this.coin_info_request_states.request_complete,
coins_by_type: coins_by_type,
Expand Down Expand Up @@ -719,14 +719,21 @@ class BlockTradesBridgeDepositRequest extends React.Component {
// functions for managing input addresses
getCachedInputAddress(input_coin_type, output_coin_type, memo)
{
let account_name = this.props.account.get('name');
let account_name = this.props.account.get("name");
return this.deposit_address_cache.getCachedInputAddress(this.props.gateway, account_name, input_coin_type, output_coin_type);
}

cacheInputAddress(input_coin_type, output_coin_type, address, memo)
{
let account_name = this.props.account.get('name');
this.deposit_address_cache.cacheInputAddress(this.props.gateway, account_name, input_coin_type, output_coin_type, address, memo);
let account_name = this.props.account.get("name");
this.deposit_address_cache.cacheInputAddress(
this.props.gateway,
account_name,
input_coin_type,
output_coin_type,
address,
memo
);
}

getCachedOrGeneratedInputAddress(input_coin_type, output_coin_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ class BlockTradesGatewayDepositRequest extends React.Component {
componentWillMount() {
let account_name = this.props.account.get("name");
let receive_address = this.deposit_address_cache.getCachedInputAddress(this.props.gateway, account_name, this.props.deposit_coin_type, this.props.receive_coin_type);
if (!receive_address) {
if (!receive_address || receive_address.address === "unknown") {
requestDepositAddress(this._getDepositObject());
} else {
this.setState({receive_address});
}
}

Expand All @@ -89,7 +91,14 @@ class BlockTradesGatewayDepositRequest extends React.Component {

addDepositAddress( receive_address ) {
let account_name = this.props.account.get("name");
this.deposit_address_cache.cacheInputAddress(this.props.gateway, account_name, this.props.deposit_coin_type, this.props.receive_coin_type, receive_address.address, receive_address.memo);
this.deposit_address_cache.cacheInputAddress(
this.props.gateway,
account_name,
this.props.deposit_coin_type,
this.props.receive_coin_type,
receive_address.address,
receive_address.memo
);
this.setState( {receive_address} );
}

Expand All @@ -114,7 +123,7 @@ class BlockTradesGatewayDepositRequest extends React.Component {
}

render() {

const isDeposit = this.props.action === "deposit";
let emptyRow = <div style={{display:"none", minHeight: 150}}></div>;
if( !this.props.account || !this.props.issuer_account || !this.props.receive_asset )
return emptyRow;
Expand Down Expand Up @@ -158,7 +167,7 @@ class BlockTradesGatewayDepositRequest extends React.Component {
receive_address = this.deposit_address_cache.getCachedInputAddress(this.props.gateway, account_name, this.props.deposit_coin_type, this.props.receive_coin_type);
}

if( !receive_address ) {
if( !receive_address) {
requestDepositAddress(this._getDepositObject());
return <div style={{margin: "3rem"}}><LoadingIndicator type="three-bounce"/></div>;
}
Expand Down Expand Up @@ -200,11 +209,11 @@ class BlockTradesGatewayDepositRequest extends React.Component {
var withdraw_memo_prefix = "";
}

if (!this.props.isAvailable) {
if (!this.props.isAvailable || (isDeposit && !this.props.deposit_account && !this.state.receive_address)) {
return <div><Translate className="txtlabel cancel" content="gateway.unavailable" component="h4" /></div>;
}

if (this.props.action === "deposit") {
if (isDeposit) {
return (
<div className="Blocktrades__gateway grid-block no-padding no-margin">
<div className="small-12 medium-5">
Expand Down
87 changes: 87 additions & 0 deletions app/components/Exchange/BuySell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import SimpleDepositWithdraw from "../Dashboard/SimpleDepositWithdraw";
import SimpleDepositBlocktradesBridge from "../Dashboard/SimpleDepositBlocktradesBridge";
import {Asset} from "common/MarketClasses";
import ExchangeInput from "./ExchangeInput";
import assetUtils from "common/asset_utils";
import Icon from "../Icon/Icon";

class BuySell extends React.Component {

Expand Down Expand Up @@ -80,10 +82,93 @@ class BuySell extends React.Component {
if (this.props.total) total = this.props.total;

let balanceAmount = new Asset({amount: balance ? balance.get("balance") : 0, precision: balancePrecision, asset_id: this.props.balanceId});

const maxBaseMarketFee = new Asset({
amount: base.getIn(["options", "max_market_fee"]),
asset_id: base.get("asset_id"),
precision: base.get("precision")
});
const maxQuoteMarketFee = new Asset({
amount: quote.getIn(["options", "max_market_fee"]),
asset_id: quote.get("asset_id"),
precision: quote.get("precision")
});
const quoteFee = !amount ? 0 : Math.min(maxQuoteMarketFee.getAmount({real: true}), amount * quote.getIn(["options", "market_fee_percent"]) / 10000);
const baseFee = !amount ? 0 : Math.min(maxBaseMarketFee.getAmount({real: true}), total * base.getIn(["options", "market_fee_percent"]) / 10000);
const baseFlagBooleans = assetUtils.getFlagBooleans(base.getIn(["options", "flags"]), base.has("bitasset_data_id"));
const quoteFlagBooleans = assetUtils.getFlagBooleans(quote.getIn(["options", "flags"]), quote.has("bitasset_data_id"));


const hasMarketFee = baseFlagBooleans["charge_market_fee"] || quoteFlagBooleans["charge_market_fee"];
var baseMarketFee = baseFlagBooleans["charge_market_fee"] ? (
<div className="grid-block no-padding buy-sell-row">
<div className="grid-block small-3 no-margin no-overflow buy-sell-label">
<Translate content="explorer.asset.summary.market_fee" />:
</div>
<div className="grid-block small-5 no-margin no-overflow buy-sell-input">
<input disabled type="text" id="baseMarketFee" value={baseFee} autoComplete="off"/>
</div>
<div className="grid-block small-4 no-margin no-overflow buy-sell-box">
<AssetName noTip name={base.get("symbol")} />
<span
data-tip={counterpart.translate(
"tooltip.market_fee",
{
percent: base.getIn(["options", "market_fee_percent"]) / 100,
asset: base.get("symbol")
}
)
}
className="inline-block tooltip"
>
&nbsp;<Icon style={{position: "relative", top: 3}} name="question-circle" />
</span>
</div>
</div>
) : hasMarketFee ?
<div className="grid-block no-padding buy-sell-row">
<div style={{visibility: "hidden"}} className="grid-block small-3 no-margin no-overflow buy-sell-label">
<Translate content="explorer.asset.summary.market_fee" />:
</div>
</div> : null;
var quoteMarketFee = quoteFlagBooleans["charge_market_fee"] ? (
<div className="grid-block no-padding buy-sell-row">
<div className="grid-block small-3 no-margin no-overflow buy-sell-label">
<Translate content="explorer.asset.summary.market_fee" />:
</div>
<div className="grid-block small-5 no-margin no-overflow buy-sell-input">
<input disabled type="text" id="baseMarketFee" value={quoteFee} autoComplete="off"/>
</div>
<div className="grid-block small-4 no-margin no-overflow buy-sell-box">
<AssetName noTip name={quote.get("symbol")} />
<span
data-tip={counterpart.translate(
"tooltip.market_fee",
{
percent: quote.getIn(["options", "market_fee_percent"]) / 100,
asset: quote.get("symbol")
}
)
}
className="inline-block tooltip"
>
&nbsp;<Icon style={{position: "relative", top: 3}} name="question-circle" />
</span>
</div>
</div>
) : hasMarketFee ?
<div className="grid-block no-padding buy-sell-row">
<div style={{visibility: "hidden"}} className="grid-block small-3 no-margin no-overflow buy-sell-label">
<Translate content="explorer.asset.summary.market_fee" />:
</div>
</div> : null;

// if (!balanceAmount) {
// balanceAmount = 0;
// }
const isBid = type === "bid";
let marketFee = isBid && quoteMarketFee ? quoteMarketFee : !isBid && baseMarketFee ? baseMarketFee : null;
console.log("isBid", isBid, "quoteMarketFee", !!quoteMarketFee, "baseMarketFee", !!baseMarketFee);
let hasBalance = isBid ? balanceAmount.getAmount({real: true}) >= parseFloat(total) : balanceAmount.getAmount({real: true}) >= parseFloat(amount);

let buttonText = isPredictionMarket ? counterpart.translate("exchange.short") : isBid ? counterpart.translate("exchange.buy") : counterpart.translate("exchange.sell");
Expand Down Expand Up @@ -201,6 +286,8 @@ class BuySell extends React.Component {
</select>
</div>
</div>

{marketFee}
</div>
<div>
<div className="grid-content clear-fix no-padding">
Expand Down
18 changes: 13 additions & 5 deletions app/components/Exchange/Exchange.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Exchange extends React.Component {

this._getWindowSize = debounce(this._getWindowSize.bind(this), 150);
this._checkFeeStatus = this._checkFeeStatus.bind(this);
this.psInit = true;
}

_initialState(props) {
Expand Down Expand Up @@ -148,10 +149,6 @@ class Exchange extends React.Component {
}

componentDidMount() {
let centerContainer = this.refs.center;
if (centerContainer) {
Ps.initialize(centerContainer);
}
SettingsActions.changeViewSetting.defer({
[this._getLastMarketKey()]: this.props.quoteAsset.get("symbol") + "_" + this.props.baseAsset.get("symbol")
});
Expand Down Expand Up @@ -191,10 +188,21 @@ class Exchange extends React.Component {
height: innerHeight,
width: innerWidth
});
let centerContainer = this.refs.center;
if (centerContainer) {
Ps.update(centerContainer);
}
}
}

componentWillReceiveProps(nextProps) {
if (this.refs.center && this.psInit) {
let centerContainer = this.refs.center;
if (centerContainer) {
Ps.initialize(centerContainer);
this.psInit = false;
}
}
if (
nextProps.quoteAsset !== this.props.quoteAsset ||
nextProps.baseAsset !== this.props.baseAsset ||
Expand Down Expand Up @@ -1128,7 +1136,7 @@ class Exchange extends React.Component {
showVolumeChart={showVolumeChart}
/>

<div className="grid-block vertical no-padding" id="CenterContent" ref="center">
<div className="grid-block vertical no-padding ps-container" id="CenterContent" ref="center">
{!showDepthChart ? (
<div className="grid-block shrink no-overflow" id="market-charts" >
{/* Price history chart */}
Expand Down
20 changes: 12 additions & 8 deletions app/components/Exchange/OrderBook.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,12 @@ class OrderBook extends React.Component {
<span> (<AssetName name={quoteSymbol} />)</span>
</div>
</div>
<table className="table order-table table-hover fixed-table text-right">
{!this.state.flip ? rightHeader : leftHeader}
</table>
<div className="grid-block" ref="hor_asks" style={{paddingRight: !showAllAsks ? 0 : 15, overflow: "hidden", maxHeight: 210}}>
<div style={{paddingRight: "0.6rem"}}>
<table className="table order-table table-hover fixed-table text-right">
{!this.state.flip ? rightHeader : leftHeader}
</table>
</div>
<div className="grid-block" ref="hor_asks" style={{paddingRight: "0.6rem", overflow: "hidden", maxHeight: 210}}>
<table style={{paddingBottom: 5}} className="table order-table table-hover fixed-table text-right no-overflow">
<TransitionWrapper
ref="askTransition"
Expand Down Expand Up @@ -442,10 +444,12 @@ class OrderBook extends React.Component {
<span> (<AssetName name={baseSymbol} />)</span>
</div>
</div>
<table className="table order-table table-hover fixed-table text-right">
{this.state.flip ? rightHeader : leftHeader}
</table>
<div className="grid-block" ref="hor_bids" style={{paddingRight: !showAllBids ? 0 : 15, overflow: "hidden", maxHeight: 210}}>
<div style={{paddingRight: "0.6rem"}}>
<table className="table order-table table-hover fixed-table text-right">
{this.state.flip ? rightHeader : leftHeader}
</table>
</div>
<div className="grid-block" ref="hor_bids" style={{paddingRight: "0.6rem", overflow: "hidden", maxHeight: 210}}>
<table style={{paddingBottom: 5}} className="table order-table table-hover fixed-table text-right no-overflow">
<TransitionWrapper
ref="bidTransition"
Expand Down
1 change: 1 addition & 0 deletions app/lib/common/BlockTradesDepositAddressCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class BlockTradesDepositAddressCache {

cacheInputAddress(exchange_name, account_name, input_coin_type, output_coin_type, address, memo)
{
if (!address) return;
let wallet = WalletDb.getWallet();
wallet = null;

Expand Down
4 changes: 2 additions & 2 deletions app/lib/common/blockTradesMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ export function requestDepositAddress({inputCoinType, outputCoinType, outputAddr
}, error => {
// console.log( "error: ",error );
delete depositRequests[body_string];
if (stateCallback) stateCallback({"address": "unknown", "memo": null});
if (stateCallback) stateCallback(null);
});
}, error => {
// console.log( "error: ",error );
delete depositRequests[body_string];
if (stateCallback) stateCallback({"address": "unknown", "memo": null});
if (stateCallback) stateCallback(null);
}).catch(err => {
console.log("fetch error:", err);
delete depositRequests[body_string];
Expand Down