mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 18:11:36 +01:00
553 lines
30 KiB
Plaintext
553 lines
30 KiB
Plaintext
@using BTCPayServer.Abstractions.Extensions
|
|
@using BTCPayServer.Abstractions.Custodians
|
|
@using BTCPayServer.Abstractions.TagHelpers
|
|
@using BTCPayServer.Views.CustodianAccounts
|
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
|
|
@model BTCPayServer.Models.CustodianAccountViewModels.ViewCustodianAccountViewModel
|
|
@{
|
|
ViewData.SetActivePage(CustodianAccountsNavPages.View, "Custodian account: " + @Model?.CustodianAccount.Name, Model.CustodianAccount.Id);
|
|
Csp.UnsafeEval();
|
|
}
|
|
|
|
@section PageHeadContent
|
|
{
|
|
<link href="~/main/qrcode.css" rel="stylesheet" asp-append-version="true"/>
|
|
}
|
|
|
|
@section PageFootContent {
|
|
<partial name="_ValidationScriptsPartial"/>
|
|
}
|
|
|
|
<style>
|
|
.trade-qty label{display: block; }
|
|
</style>
|
|
|
|
<div id="custodianAccountView" v-cloak>
|
|
<div class="sticky-header-setup"></div>
|
|
<div class="sticky-header d-flex flex-wrap gap-3 align-items-center justify-content-between">
|
|
<h2 class="mb-0">
|
|
@ViewData["Title"]
|
|
</h2>
|
|
<div class="d-flex flex-wrap gap-3">
|
|
<a class="btn btn-primary" role="button" v-if="account?.depositablePaymentMethods?.length > 0" v-on:click="openDepositModal()" href="#">
|
|
<span class="fa fa-download"></span> Deposit
|
|
</a>
|
|
<a asp-action="EditCustodianAccount" asp-route-storeId="@Model.CustodianAccount.StoreId" asp-route-accountId="@Model.CustodianAccount.Id" class="btn btn-primary" role="button" id="EditCustodianAccountConfig">
|
|
<span class="fa fa-gear"></span> Configure
|
|
</a>
|
|
<!--
|
|
<button type="submit" class="btn btn-primary order-sm-1" id="SaveSettings">Save</button>
|
|
<a class="btn btn-secondary" id="ViewApp" target="app_" href="/apps/MQ2sCVsmQ95JBZ4aZDtoSwMAnBY/pos">View</a>
|
|
-->
|
|
</div>
|
|
</div>
|
|
|
|
<partial name="_StatusMessage"/>
|
|
|
|
<div class="row">
|
|
<div class="col-xl-12">
|
|
<div v-if="!account" class="loading d-flex justify-content-center p-3">
|
|
<div class="spinner-border text-light" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="account">
|
|
<p class="alert alert-danger" v-if="account.assetBalanceExceptionMessage">
|
|
{{ account.assetBalanceExceptionMessage }}
|
|
</p>
|
|
|
|
<h2>Balances</h2>
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" v-model="hideDustAmounts" id="hideDustAmounts">
|
|
<label class="form-check-label" for="hideDustAmounts">
|
|
Hide holdings worth less than {{ account.dustThresholdInFiat }} {{ account.storeDefaultFiat }}.
|
|
</label>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-responsive-md">
|
|
<thead>
|
|
<tr>
|
|
<th>Asset</th>
|
|
<th class="text-end">Balance</th>
|
|
<th class="text-end">Unit Price (Bid)</th>
|
|
<th class="text-end">Unit Price (Ask)</th>
|
|
<th class="text-end">Fiat Value</th>
|
|
<th class="text-end">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="row in sortedAssetRows" :key="row.asset">
|
|
<td>{{ row.asset }}</td>
|
|
<!-- TODO format as number? How? -->
|
|
<th class="text-end">{{ row.formattedQty }}</th>
|
|
<th class="text-end">
|
|
{{ row.formattedBid }}
|
|
</th>
|
|
<th class="text-end">
|
|
{{ row.formattedAsk }}
|
|
</th>
|
|
<th class="text-end">
|
|
{{ row.formattedFiatValue }}
|
|
</th>
|
|
<th class="text-end">
|
|
<a v-if="row.tradableAssetPairs" v-on:click="openTradeModal(row)" href="#">Trade</a>
|
|
<a v-if="canDepositAsset(row.asset)" v-on:click="openDepositModal(row)" href="#">Deposit</a>
|
|
<a v-if="row.withdrawablePaymentMethods.length" v-on:click="openWithdrawModal(row)" href="#">Withdraw</a>
|
|
</th>
|
|
</tr>
|
|
<tr v-if="account.assetBalances.length === 0">
|
|
<td colspan="999" class="text-center">No assets are stored with this custodian (yet).</td>
|
|
</tr>
|
|
<tr v-if="account.assetBalances.length > 0 && sortedAssetRows.length === 0">
|
|
<td colspan="999" class="text-center">No holdings are worth more than {{ account.dustThresholdInFiat }} {{ account.storeDefaultFiat }}.</td>
|
|
</tr>
|
|
<tr v-if="account.assetBalanceExceptionMessage !== null">
|
|
<td colspan="999" class="text-center">An error occured while loading assets and balances.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h2>Features</h2>
|
|
<p>The @Model?.Custodian.Name custodian supports:</p>
|
|
<ul>
|
|
<li>Viewing asset balances</li>
|
|
@if (Model?.Custodian is ICanTrade)
|
|
{
|
|
<li>Converting assets using market orders</li>
|
|
}
|
|
@if (Model?.Custodian is ICanDeposit)
|
|
{
|
|
<li>Depositing</li>
|
|
}
|
|
@if (Model?.Custodian is ICanWithdraw)
|
|
{
|
|
<li>Withdrawing</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal" tabindex="-1" role="dialog" id="withdrawModal">
|
|
<div class="modal-dialog" role="document">
|
|
<form class="modal-content" id="withdrawForm" v-on:submit="onWithdrawSubmit" method="post" asp-action="Withdraw" asp-route-accountId="@Model?.CustodianAccount?.Id" asp-route-storeId="@Model?.CustodianAccount?.StoreId">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Withdraw {{ withdraw.qty}} {{ withdraw.asset }}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" v-if="!withdraw.isExecuting">
|
|
<vc:icon symbol="close"/>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="loading d-flex justify-content-center p-3" v-if="withdraw.isExecuting">
|
|
<div class="spinner-border text-light" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
<div v-if="!withdraw.isExecuting && withdraw.results === null">
|
|
|
|
<p v-if="withdraw.errorMsg" class="alert alert-danger">{{ withdraw.errorMsg }}</p>
|
|
<div v-if="withdraw.badConfigFields?.length > 0" class="alert alert-danger">
|
|
Please go to <a class="alert-link" asp-action="EditCustodianAccount" asp-route-storeId="@Model.CustodianAccount.StoreId" asp-route-accountId="@Model.CustodianAccount.Id">Configure</a> and fill out these fields to enable withdrawals for {{ withdraw.paymentMethod }}.
|
|
<ul>
|
|
<li v-for="badConfigField in withdraw.badConfigFields">
|
|
{{ badConfigField }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawAsset">Asset to Withdraw</label>
|
|
<select class="form-control" v-model="withdraw.asset" id="WithdrawAsset">
|
|
<option v-for="option in availableAssetsToWithdraw" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawPaymentMethod">Payment Method</label>
|
|
<select class="form-control" v-model="withdraw.paymentMethod" id="WithdrawPaymentMethod">
|
|
<option v-for="option in availablePaymentMethodsToWithdraw" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawDestination">Destination</label>
|
|
<select class="form-control" id="WithdrawDestination">
|
|
<option selected="selected">
|
|
Store wallet
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawQty">Quantity</label>
|
|
<input type="number" :min="withdraw.minQty" :max="withdraw.maxQty" step="any" class="form-control" v-model="withdraw.qty" id="WithdrawQty"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="btn-group" role="group" aria-label="Set qty to a percentage of holdings">
|
|
<button v-on:click="setWithdrawQtyPercent(10)" class="btn btn-secondary" type="button">10%</button>
|
|
<button v-on:click="setWithdrawQtyPercent(25)" class="btn btn-secondary" type="button">25%</button>
|
|
<button v-on:click="setWithdrawQtyPercent(50)" class="btn btn-secondary" type="button">50%</button>
|
|
<button v-on:click="setWithdrawQtyPercent(75)" class="btn btn-secondary" type="button">75%</button>
|
|
<button v-on:click="setWithdrawQtyPercent(90)" class="btn btn-secondary" type="button">90%</button>
|
|
<button v-on:click="setWithdrawQtyPercent(100)" class="btn btn-secondary" type="button">100%</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="withdraw.badConfigFields?.length === 0 && !withdraw.isUpdating">
|
|
<div class="form-group">
|
|
<span v-if="withdrawFees.length === 0">
|
|
No fee for this withdrawal
|
|
</span>
|
|
<span v-if="withdrawFees.length === 1">
|
|
Fee: {{ -1 * withdrawFees[0].qty}} {{ withdrawFees[0].asset}}
|
|
<span v-if="trade.priceForPair[withdrawFees[0].asset + '/' + account.storeDefaultFiat ]">
|
|
or {{ -1 * withdrawFees[0].qty * trade.priceForPair[withdrawFees[0].asset + '/' + account.storeDefaultFiat ] }} {{ account.storeDefaultFiat }}
|
|
</span>
|
|
</span>
|
|
<ul v-if="withdrawFees.length > 1">
|
|
<li v-for="entry in withdrawFees" v-if="entry.type === 'Fee'">
|
|
{{ entry.qty}} {{ entry.asset}}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<p v-if="canExecuteWithdrawal">
|
|
After withdrawing {{ account.assetBalances[withdraw.asset].qty - withdraw.qty }} {{ withdraw.asset }} will remain in your account.
|
|
</p>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
<div v-if="withdraw.results !== null">
|
|
|
|
<p class="alert alert-success" v-if="withdraw.results.status === 'Queued' || withdraw.results.status === 'Unknown'">
|
|
Successfully requested withdrawal.
|
|
</p>
|
|
<p class="alert alert-success" v-if="withdraw.results.status === 'Complete'">
|
|
Successfully completed withdrawal.
|
|
</p>
|
|
<p class="alert alert-danger" v-if="withdraw.results.status === 'Failed'">
|
|
Withdrawal failed.
|
|
</p>
|
|
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th colspan="2">Asset</th>
|
|
<th>Comment</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="entry in withdraw.results.ledgerEntries">
|
|
<td class="text-end" v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }"><span v-if="entry.qty > 0">+</span>{{ entry.qty }}</td>
|
|
<td v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }">{{ entry.asset }}</td>
|
|
<td v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }">
|
|
<span v-if="entry.type !== 'Trade'">{{ entry.type}}</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<!-- TODO Add "Copy to Clipboard" buttons -->
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawalId">Withdrawal ID</label>
|
|
<input type="text" class="form-control" v-model="withdraw.results.withdrawalId" id="WithdrawalId" readonly/>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawalTransactionId">Transaction ID</label>
|
|
<input type="text" class="form-control" v-model="withdraw.results.transactionId" id="WithdrawalTransactionId" readonly/>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="WithdrawalTargetAddress">Target Address</label>
|
|
<input type="text" class="form-control" v-model="withdraw.results.targetAddress" id="WithdrawalTargetAddress" readonly/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer" v-if="!withdraw.isExecuting">
|
|
<div class="modal-footer-left">
|
|
<span v-if="withdraw.isUpdating">
|
|
Updating...
|
|
</span>
|
|
</div>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-primary" v-if="canExecuteWithdrawal">Withdraw</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="modal" tabindex="-1" role="dialog" id="depositModal">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Deposit</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
|
<vc:icon symbol="close"/>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p v-if="deposit.errorMsg" class="alert alert-danger">{{ deposit.errorMsg }}</p>
|
|
<div class="form-group">
|
|
<label class="form-label" for="DepositAsset">Asset to Deposit</label>
|
|
<select class="form-select" v-model="deposit.asset" name="DepositAsset">
|
|
<option v-for="option in availableAssetsToDeposit" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" for="DepositPaymentNetwork">Payment Method</label>
|
|
<select class="form-select" v-model="deposit.paymentMethod" id="DepositPaymentNetwork">
|
|
<option v-for="option in availablePaymentMethodsToDeposit" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="loading d-flex justify-content-center p-3" v-if="deposit.isLoading">
|
|
<div class="spinner-border text-light" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="!deposit.isLoading && (deposit.link || deposit.address)">
|
|
<div class="tab-content text-center">
|
|
<div v-if="deposit.link" class="tab-pane" id="link-tab" role="tabpanel">
|
|
<div class="qr-container mb-3">
|
|
<img :src="deposit.cryptoImageUrl" class="qr-icon" :alt="deposit.asset"/>
|
|
<qrcode v-bind:value="deposit.link" :options="{ width: 256, margin: 1, color: {dark:'#000', light:'#f5f5f7'} }" tag="svg"></qrcode>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="input-group" :data-clipboard="deposit.link">
|
|
<input type="text" class="form-control" readonly="readonly" :value="deposit.link" id="payment-link"/>
|
|
<button type="button" class="btn btn-outline-secondary px-3">
|
|
<vc:icon symbol="copy"/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-if="deposit.address" class="tab-pane show active" id="address-tab" role="tabpanel">
|
|
<div class="qr-container mb-3">
|
|
<img v-bind:src="deposit.cryptoImageUrl" class="qr-icon" :alt="deposit.asset"/>
|
|
<qrcode v-bind:value="deposit.address" :options="{ width: 256, margin: 1, color: {dark:'#000', light:'#f5f5f7'} }" tag="svg"></qrcode>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="input-group" :data-clipboard="deposit.address">
|
|
<input type="text" class="form-control" readonly="readonly" :value="deposit.address" id="address"/>
|
|
<button type="button" class="btn btn-outline-secondary px-3">
|
|
<vc:icon symbol="copy"/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="nav justify-content-center">
|
|
<a v-if="deposit.address" :class="{active: deposit.tab === 'address' }" class="btcpay-pill" data-bs-toggle="tab" href="#address-tab">Address</a>
|
|
<a v-if="deposit.link" :class="{active: deposit.tab === 'link' }" class="btcpay-pill" data-bs-toggle="tab" href="#link-tab">Link</a>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<a v-if="deposit.createTransactionUrl" class="btn btn-primary" :href="deposit.createTransactionUrl">
|
|
Create Transaction
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal" tabindex="-1" role="dialog" id="tradeModal">
|
|
<div class="modal-dialog" role="document">
|
|
<form class="modal-content" id="tradeForm" v-on:submit="onTradeSubmit" method="post" asp-action="Trade" asp-route-accountId="@Model?.CustodianAccount?.Id" asp-route-storeId="@Model?.CustodianAccount?.StoreId">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Trade {{ trade.qty }} {{ trade.fromAsset }} into {{ trade.toAsset }}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" v-if="!trade.isExecuting">
|
|
<vc:icon symbol="close"/>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="loading d-flex justify-content-center p-3" v-if="trade.isExecuting">
|
|
<div class="spinner-border text-light" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="!trade.isExecuting && trade.results === null">
|
|
<p v-if="trade.errorMsg" class="alert alert-danger">{{ trade.errorMsg }}</p>
|
|
|
|
<div class="row mb-2 trade-qty">
|
|
<div class="col-side">
|
|
<label class="form-label">
|
|
Convert
|
|
<div class="input-group has-validation">
|
|
<!--
|
|
getMinQtyToTrade() = {{ getMinQtyToTrade(this.trade.toAsset, this.trade.fromAsset) }}
|
|
<br/>
|
|
Max Qty to Trade = {{ trade.maxQty }}
|
|
-->
|
|
<input name="Qty" type="number" min="0" step="any" :max="trade.maxQty" :min="getMinQtyToTrade()" class="form-control qty" v-bind:class="{ 'is-invalid': trade.qty < getMinQtyToTrade() || trade.qty > trade.maxQty }" v-model="trade.qty"/>
|
|
<select name="FromAsset" v-model="trade.fromAsset" class="form-select">
|
|
<option v-for="option in availableAssetsToTrade" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
<div class="col-center text-center">
|
|
|
|
<br/>
|
|
<button v-if="canSwapTradeAssets()" type="button" class="btn btn-secondary btn-square" v-on:click="swapTradeAssets()" aria-label="Swap assets">
|
|
<i class="fa fa-arrows-h" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
<div class="col-side">
|
|
<label class="form-label">
|
|
Into
|
|
<div class="input-group">
|
|
<input disabled="disabled" type="number" class="form-control qty" v-model="tradeQtyToReceive"/>
|
|
<select name="ToAsset" v-model="trade.toAsset" class="form-select">
|
|
<option v-for="option in availableAssetsToTradeInto" v-bind:value="option">
|
|
{{ option }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="btn-group" role="group" aria-label="Set qty to a percentage of holdings">
|
|
<button v-on:click="setTradeQtyPercent(10)" class="btn btn-secondary" type="button">10%</button>
|
|
<button v-on:click="setTradeQtyPercent(25)" class="btn btn-secondary" type="button">25%</button>
|
|
<button v-on:click="setTradeQtyPercent(50)" class="btn btn-secondary" type="button">50%</button>
|
|
<button v-on:click="setTradeQtyPercent(75)" class="btn btn-secondary" type="button">75%</button>
|
|
<button v-on:click="setTradeQtyPercent(90)" class="btn btn-secondary" type="button">90%</button>
|
|
<button v-on:click="setTradeQtyPercent(100)" class="btn btn-secondary" type="button">100%</button>
|
|
</div>
|
|
</div>
|
|
|
|
<p v-if="trade.price">
|
|
<br/>
|
|
1 {{ trade.toAsset }} = {{ trade.price }} {{ trade.fromAsset }}
|
|
<br/>
|
|
1 {{ trade.fromAsset }} = {{ 1 / trade.price }} {{ trade.toAsset }}
|
|
</p>
|
|
<p v-if="canExecuteTrade">
|
|
After the trade
|
|
{{ trade.maxQty - trade.qty }} {{ trade.fromAsset }} will remain in your account.
|
|
</p>
|
|
|
|
<!--
|
|
<p>
|
|
trade.priceForPair = {{ trade.priceForPair }}
|
|
</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>From</th>
|
|
<th>To</th>
|
|
<th>Min Qty to Trade</th>
|
|
<th>Price</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>EUR</td>
|
|
<td>BTC</td>
|
|
<td>{{getMinQtyToTrade('EUR', 'BTC')}}</td>
|
|
<td>{{trade.priceForPair['EUR/BTC']}}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>BTC</td>
|
|
<td>EUR</td>
|
|
<td>{{getMinQtyToTrade('BTC', 'EUR')}}</td>
|
|
<td>{{trade.priceForPair['BTC/EUR']}}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EUR</td>
|
|
<td>LTC</td>
|
|
<td>{{getMinQtyToTrade('EUR', 'LTC')}}</td>
|
|
<td>{{trade.priceForPair['EUR/LTC']}}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>LTC</td>
|
|
<td>EUR</td>
|
|
<td>{{getMinQtyToTrade('LTC', 'EUR')}}</td>
|
|
<td>{{trade.priceForPair['LTC/EUR']}}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>BTC</td>
|
|
<td>LTC</td>
|
|
<td>{{getMinQtyToTrade('BTC', 'LTC')}}</td>
|
|
<td>{{trade.priceForPair['BTC/LTC']}}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>LTC</td>
|
|
<td>BTC</td>
|
|
<td>{{getMinQtyToTrade('LTC', 'BTC')}}</td>
|
|
<td>{{trade.priceForPair['LTC/BTC']}}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
-->
|
|
<div class="form-text">Final results may vary due to trading fees and slippage.</div>
|
|
</div>
|
|
<div v-if="trade.results !== null">
|
|
<p class="alert alert-success">Successfully traded {{ trade.results.fromAsset}} into {{ trade.results.toAsset}}.</p>
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th colspan="2">Asset</th>
|
|
<th>Comment</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="entry in trade.results.ledgerEntries">
|
|
<td class="text-end" v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }"><span v-if="entry.qty > 0">+</span>{{ entry.qty }}</td>
|
|
<td v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }">{{ entry.asset }}</td>
|
|
<td v-bind:class="{ 'text-success': entry.qty > 0, 'text-danger': entry.qty < 0 }">
|
|
<span v-if="entry.type !== 'Trade'">{{ entry.type}}</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Trade ID: {{ trade.results.tradeId }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer" v-if="!trade.isExecuting">
|
|
<div class="modal-footer-left">
|
|
<span v-if="trade.isUpdating">
|
|
Updating quote...
|
|
</span>
|
|
</div>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
<span v-if="trade.results">Close</span>
|
|
<span v-if="!trade.results">Cancel</span>
|
|
</button>
|
|
<button v-if="canExecuteTrade" type="submit" class="btn btn-primary">Execute</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
|
|
<script src="~/vendor/vue-qrcode/vue-qrcode.min.js" asp-append-version="true"></script>
|
|
<script type="text/javascript">
|
|
var ajaxBalanceUrl = "@Url.Action("ViewCustodianAccountJson", "UICustodianAccounts", new { storeId = Model?.CustodianAccount.StoreId, accountId = Model?.CustodianAccount.Id })";
|
|
var ajaxTradeSimulateUrl = "@Url.Action("SimulateTradeJson", "UICustodianAccounts", new { storeId = Model?.CustodianAccount.StoreId, accountId = Model?.CustodianAccount.Id })";
|
|
var ajaxDepositUrl = "@Url.Action("GetDepositPrepareJson", "UICustodianAccounts", new { storeId = Model?.CustodianAccount.StoreId, accountId = Model?.CustodianAccount.Id })";
|
|
var ajaxWithdrawSimulateUrl = "@Url.Action("SimulateWithdrawJson", "UICustodianAccounts", new { storeId = Model?.CustodianAccount.StoreId, accountId = Model?.CustodianAccount.Id })";
|
|
var ajaxWithdrawUrl = "@Url.Action("Withdraw", "UICustodianAccounts", new { storeId = Model?.CustodianAccount.StoreId, accountId = Model?.CustodianAccount.Id })";
|
|
</script>
|
|
<script src="~/js/custodian-account.js" asp-append-version="true"></script>
|