Merge pull request #1 from ranchimall/master

This commit is contained in:
Sai Raj 2023-07-07 04:39:58 +05:30 committed by GitHub
commit c97969c605
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 138 additions and 553 deletions

View File

@ -453,24 +453,6 @@ ul {
align-content: flex-start;
}
.logo {
display: grid;
align-items: center;
grid-template-columns: auto 1fr;
gap: 0 0.3rem;
margin-right: auto;
}
.logo h4 {
text-transform: capitalize;
font-weight: 600;
}
.logo .main-logo {
height: 1.4rem;
width: 1.4rem;
fill: rgba(var(--text-color), 1);
stroke: none;
}
details:not(:last-of-type) {
border-bottom: thin solid rgba(var(--text-color), 0.3);
}
@ -683,6 +665,22 @@ sm-checkbox {
align-items: center;
}
.app-brand {
display: flex;
gap: 0.3rem;
align-items: center;
}
.app-brand .icon {
height: 1.7rem;
width: 1.7rem;
}
.app-name__company {
font-size: 0.8rem;
font-weight: 500;
color: rgba(var(--text-color), 0.8);
}
#user_popup_button {
background-color: rgba(var(--text-color), 0.06);
border-radius: 2rem;
@ -745,7 +743,7 @@ sm-checkbox {
user-select: none;
color: inherit;
grid-template-columns: auto 1fr auto auto;
grid-template-areas: "icon name rate right-arrow" "icon name countdown right-arrow";
grid-template-areas: "icon name rate right-arrow";
}
.listed-asset__icon {
grid-area: icon;
@ -766,28 +764,6 @@ sm-checkbox {
.listed-asset__rate {
grid-area: rate;
}
.listed-asset__countdown {
display: flex;
align-items: center;
grid-area: countdown;
justify-self: flex-end;
font-size: 0.8rem;
color: var(--accent-color);
}
.listed-asset__countdown .icon {
margin-left: 0.3rem;
overflow: visible;
stroke-width: 3;
fill: none;
}
.listed-asset__countdown .icon .path-a {
stroke: var(--accent-color);
stroke-dashoffset: var(--path-length, 0);
stroke-dasharray: 63;
}
.listed-asset__countdown .icon .path-b {
stroke: rgba(var(--text-color), 0.2);
}
.listed-asset__right-arrow {
grid-area: right-arrow;
background-color: rgba(var(--text-color), 0.1);

File diff suppressed because one or more lines are too long

View File

@ -427,24 +427,6 @@ ul {
align-content: flex-start;
}
}
.logo {
display: grid;
align-items: center;
grid-template-columns: auto 1fr;
gap: 0 0.3rem;
margin-right: auto;
h4 {
text-transform: capitalize;
font-weight: 600;
}
.main-logo {
height: 1.4rem;
width: 1.4rem;
fill: rgba(var(--text-color), 1);
stroke: none;
}
}
details {
&:not(:last-of-type) {
border-bottom: thin solid rgba(var(--text-color), 0.3);
@ -643,6 +625,22 @@ sm-checkbox {
width: 100%;
align-items: center;
}
.app-brand{
display: flex;
gap: 0.3rem;
align-items: center;
.icon{
height: 1.7rem;
width: 1.7rem;
}
}
.app-name{
&__company{
font-size: 0.8rem;
font-weight: 500;
color: rgba(var(--text-color), 0.8);
}
}
#user_popup_button {
background-color: rgba(var(--text-color), 0.06);
border-radius: 2rem;
@ -702,7 +700,7 @@ sm-checkbox {
user-select: none;
color: inherit;
grid-template-columns: auto 1fr auto auto;
grid-template-areas: "icon name rate right-arrow" "icon name countdown right-arrow";
grid-template-areas: "icon name rate right-arrow";
&__icon {
grid-area: icon;
padding: 0.5rem;
@ -722,28 +720,6 @@ sm-checkbox {
&__rate {
grid-area: rate;
}
&__countdown {
display: flex;
align-items: center;
grid-area: countdown;
justify-self: flex-end;
font-size: 0.8rem;
color: var(--accent-color);
.icon {
margin-left: 0.3rem;
overflow: visible;
stroke-width: 3;
fill: none;
.path-a {
stroke: var(--accent-color);
stroke-dashoffset: var(--path-length, 0);
stroke-dasharray: 63;
}
.path-b {
stroke: rgba(var(--text-color), 0.2);
}
}
}
&__right-arrow {
grid-area: right-arrow;
background-color: rgba(var(--text-color), 0.1);

View File

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RanchiMall Exchange</title>
<title>RanchiMall BitFlo</title>
<meta name="description" content="Trade FLO and FLO based RanchiMall tokens.">
<meta name="theme-color" content="#516beb" />
<script src="scripts/components.js" defer></script>
@ -62,7 +62,7 @@
</path>
</svg>
<div class="grid gap-0-5">
<h4>RanchiMall Exchange</h4>
<h4>RanchiMall BitFlo</h4>
<p>Getting everything ready</p>
</div>
<line-loader></line-loader>
@ -71,14 +71,16 @@
</div>
<article id="home" class="page hidden">
<header id="main_header">
<div class="logo">
<svg class="main-logo" viewBox="0 0 27.25 32">
<div class="app-brand margin-right-auto">
<svg id="main_logo" class="icon" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
<path d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z"></path>
</svg>
<div class="grid">
<h4>RanchiMall Exchange</h4>
<div class="app-name">
<div class="app-name__company">RanchiMall</div>
<h4 class="app-name__title">
BitFlo
</h4>
</div>
</div>
<theme-toggle id="theme_toggle"></theme-toggle>
@ -103,11 +105,6 @@
<sm-input type="password" id="login_form__priv_key" placeholder="Private key"
error-text="Invalid private key" data-private-key autofocus animate required>
</sm-input>
<!-- <sm-checkbox id="remember_me" checked>
<span class="margin-left-0-5">
Remember me
</span>
</sm-checkbox> -->
<div class="loader-button-wrapper">
<button id="login_button" class="button button--primary" onclick="UI_evt.login('login');"
type="submit">Log
@ -163,14 +160,24 @@
</div>
<section id="exchange_wrapper" class="hidden user-content">
<div id="asset_list_wrapper" class="grid gap-1 align-start">
<div class="grid gap-0-3">
<div class="flex align-center space-between">
<h5>ASSETS</h5>
<h5>PRICE</h5>
</div>
<p>Countdown shows est. time until asset prices are updated</p>
<div class="flex align-center space-between">
<h5>ASSETS</h5>
<h5>PRICE</h5>
</div>
<ul id="listed_assets" class="user-content hidden"></ul>
<ul id="listed_assets" class="user-content hidden">
<li>
<a href="#/exchange?asset=FLO" class="listed-asset grid align-center">
<div class="listed-asset__icon">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" />
</svg>
</div>
<h4 class="listed-asset__name">FLO</h4>
<b id="flo_exchange_rate" class="listed-asset__rate">0</b>
</a>
</li>
</ul>
</div>
<div id="asset_page" class="hide-on-mobile">
<nav id="asset_page__header" class="hide-on-desktop">
@ -209,7 +216,7 @@
required animate>
</sm-input>
</sm-input>
<sm-input id="get_total" placeholder="Locked amount (₹)" type="number" min="0.00000001"
<sm-input id="set_price" placeholder="Price" type="number" min="0.00000001"
step="0.00000001" required animate>
</sm-input>
<div class="grid gap-0-5">
@ -349,7 +356,6 @@
</div>
<div id="market_orders_wrapper">
<div class="grid gap-1">
<p>Order placement denotes priority at which orders will get executed.</p>
<div class="flex text-center">
<b class="flex-1" style="color: var(--green);">Buy</b>
<b class="flex-1" style="color: var(--danger-color);">Sell</b>
@ -422,13 +428,13 @@
</div>
</div>
</div>
<p>Deposit rupee from your FLO ID to exchange to purchase assets.</p>
<p>Deposit BTC to exchange to purchase assets.</p>
<div class="grid gap-1">
<div id="exchange_rupee_balance"></div>
<div id="exchange_btc_balance"></div>
<div class="grid">
<div class="flex align-center space-between">
<span class="label">Tradable assets</span>
<span class="label">Quantity | value</span>
<span class="label">Quantity</span>
</div>
<fieldset id="my_assets" class="grid"></fieldset>
</div>
@ -446,44 +452,11 @@
d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
</svg>
<p class="banner">
You need to have rupee tokens in your FLO ID to purchase assets, which then can
be
deposited
to your exchange account.
You need to have BTC in your portfolio to purchase assets.
</p>
</div>
</div>
<div id="portfolio_cards_wrapper">
<div class="grid gap-0-5 personal-asset-balance">
<div class="flex align-center">
<svg class="icon" xmlns="http://www.w3.org/2000/svg"
enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<g>
<rect fill="none" height="24" width="24" />
</g>
<g>
<g>
<path
d="M13.66,7C13.1,5.82,11.9,5,10.5,5L6,5V3h12v2l-3.26,0c0.48,0.58,0.84,1.26,1.05,2L18,7v2l-2.02,0c-0.25,2.8-2.61,5-5.48,5 H9.77l6.73,7h-2.77L7,14v-2h3.5c1.76,0,3.22-1.3,3.46-3L6,9V7L13.66,7z" />
</g>
</g>
</svg>
<h5>Rupee token</h5>
</div>
<h1 class="h1" id="personal_rupee_balance"></h1>
<a href="https://ranchimall.github.io/flopay/#/home" target="_blank"
class="button interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px"
viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none"></path>
<path
d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z">
</path>
</svg>
Top-up
</a>
</div>
<div class="grid gap-0-5 personal-asset-balance">
<div class="flex align-center">
<svg class="icon flo-icon" width="64" height="64" viewBox="0 0 64 64"
@ -557,166 +530,6 @@
<p>No exchange transactions</p>
</div>
</div>
<div id="help" class="mobile-page hidden grid gap-2">
<h1>Hey there! How can we help you today?</h1>
<div class="grid gap-0-5">
<h5>F.A.Qs</h5>
<div class="grid gap-0-5">
<details>
<summary class="interact">
<h4>
What are the rules of the exchange that I must know?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<ul>
<li>Only the buyers of a token are permitted to sell that token</li>
<li>The maximum quantity of a token that can be sold is capped by the number of tokens
purchased for each token </li>
<li>You need sell-chips in order to sell. Sell-chips are given against each purchase
when current token prices are at least 10% higher</li>
<li><strong>Sell side priority</strong>: The first to buy gets the first priority to
sell no matter when
that person enters the order</li>
<li><strong>Buy side priority</strong>: the first to order gets the first priority to
buy</li>
<li>Launch sellers can sell without sell-chips in order to provide initial inventory
</li>
</ul>
</details>
<details>
<summary class="interact">
<h4>
What are rupee tokens?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
Rupee tokens are a digital asset which has value equal to 1 INR. Which can be used with
RanchiMall exchange and other RanchiMall products.
</p>
</details>
<details>
<summary class="interact">
<h4>
Where can I get rupee tokens?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
Rupee tokens can be acquired by paying equivalent amount of rupees using our <strong>
<a href="https://ranchimall.github.io/flopay/" target="_blank">FLO Pay</a>
</strong>
app.
</p>
</details>
<details>
<summary class="interact">
<h4>
Why is there a difference between current asset prices and prices shown as
buying/selling price?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
Contrary to other exchanges, the price you see as buying/selling price works as a upper
bound for buying and lower bound for selling. you order will bne executed at
best price determined by the exchange algorithm.
</p>
</details>
<details>
<summary class="interact">
<h4>
Why my order hasn't been filled yet?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
Our Exchange works a little differently than other exchanges. You can only buy or
sell at
the
market price.
If you have placed an order at lower/higher price than current price, your order will
not be
executed until the market price matches your order price.
</p>
</details>
<details>
<summary class="interact">
<h4>
Why am I not able to sell my assets?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
We only allows selling of assets that were bought in this exchange.
Assets bought in other exchanges can not be sold here.
</p>
</details>
<details>
<summary class="interact">
<h4>
I have rupee tokens in FLO ID, so why can't I see them in my portfolio?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
In order to user your rupee tokens in exchange, you have to deposit them in exchange
first.
Assets owned by a FLO ID are different than assets you own in exchange.
</p>
</details>
<details>
<summary class="interact">
<h4>
Why don't prices fluctuate often?
</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
</svg>
</summary>
<p>
Our exchange has a different pricing model than other exchanges. We have an algorithm
based
pricing model which updates prices every hour
based on predefined rules. This prevents rapid fluctuations in price and ensures that
you
can always buy or sell at the best price.
</p>
</details>
</div>
</div>
</div>
</section>
<nav id="main_navbar" class="flex align-center">
<a href="#/exchange" class="main_navbar__item main_navbar__item--active interact">
@ -767,15 +580,6 @@
</svg>
<div class="item__title">Portfolio</div>
</a>
<a href="#/help" class="main_navbar__item interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" />
</svg>
<div class="item__title">Help</div>
</a>
</nav>
</article>
<!--
@ -894,27 +698,6 @@
</sm-popup>
<!-- templates -->
<template id="listed_asset_template">
<li>
<a class="listed-asset interact grid align-center">
<div class="listed-asset__icon"></div>
<h4 class="listed-asset__name"></h4>
<b class="listed-asset__rate"></b>
<div class="listed-asset__countdown">
timer
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 24">
<path class="path-a" d="M11.5,2a10,10,0,1,1-10,10,10,10,0,0,1,10-10" />
<path class="path-b" d="M11.5,2a10,10,0,1,1-10,10,10,10,0,0,1,10-10" />
</svg>
</div>
<svg class="icon listed-asset__right-arrow hide-on-desktop" xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
</svg>
</a>
</li>
</template>
<template id="asset_balance_card_template">
<a class="balance-card interact">
<div class="balance-card__icon"></div>
@ -994,7 +777,7 @@
</div>
<div class="flex gap-0-5">
<div class="grid flex-1">
<span class="label">Valid upto</span>
<span class="label">Price</span>
<b class="transaction-card__price wrap-around"></b>
</div>
<div class="grid flex-1">
@ -1021,7 +804,7 @@
</button>
</div>
<div class="grid price-block">
<span class="label">Unit price</span>
<span class="label">Price</span>
<b class="completed-trade__price"></b>
</div>
<div class="grid amount-block">
@ -1400,7 +1183,7 @@
const urlSearchParams = new URLSearchParams('?' + searchParams);
params = Object.fromEntries(urlSearchParams.entries());
}
if (typeof proxy.userID === "undefined" && !['exchange', 'market', 'help'].includes(pageId)) {
if (typeof proxy.userID === "undefined" && !['exchange', 'market'].includes(pageId)) {
pageId = 'exchange'
history.replaceState(null, null, '#/exchange')
}
@ -1410,6 +1193,7 @@
case 'exchange':
if (document.body.classList.contains('is-signed-in')) {
getRef('login_section').classList.add('hidden')
if (!isMobileView && !params.hasOwnProperty('asset') || params.asset === '') {
if (getRef('listed_assets').querySelector(`[href="#/exchange?asset=FLO"]`))
getRef('listed_assets').querySelector(`[href="#/exchange?asset=FLO"]`).click()
@ -1419,10 +1203,9 @@
getRef('listed_assets').querySelector('.listed-asset--active').classList.remove('listed-asset--active')
getRef('listed_assets').querySelector(`[href="#/exchange?asset=${params.asset}"]`).classList.add('listed-asset--active')
getRef('chart_asset').textContent = `${params.asset}/INR`
showSuggestedPrice(params.asset)
getRef('traded_asset').textContent = `Trade ${params.asset}`
getRef('trade_button').textContent = `${tradeType} ${params.asset}`
getRef('quantity_type').textContent = tradeType === 'buy' ? formatAmount(allTokens.rupee.net, true) : `${parseFloat(allTokens[params.asset].net.toFixed(4))} ${params.asset}`
getRef('quantity_type').textContent = `${parseFloat(allTokens[tradeType === 'buy' ? 'BTC' : params.asset].net.toFixed(4))} ${tradeType === 'buy' ? 'BTC' : params.asset}`
updateTooltip(params.asset, tradeType)
}
const animOptions = {
@ -1476,6 +1259,11 @@
getRef('asset_list_wrapper').classList.remove('hide-on-mobile')
}
}
getLastTradePrice().then(price => {
getRef('set_price').value = price
}).catch(err => {
console.error(err)
})
} else {
getRef('login_section').classList.remove('hidden')
if (subPageId1 === 'generate') {
@ -1499,7 +1287,7 @@
if (params.asset) {
getRef('portfolio_asset__name').textContent = params.asset
const { net, locked } = allTokens[params.asset]
const lockedBalance = params.asset === 'rupee' ? formatAmount(locked, true) : toFixed(locked)
const lockedBalance = params.asset === 'rupee' ? formatAmount(locked) : toFixed(locked)
showChildElement('portfolio', 1, {
entry: slideInLeft,
exit: slideOutLeft,
@ -1507,8 +1295,8 @@
renderElem(getRef('portfolio_asset__balance'), html`
<div class="grid">
<span class="label">Available</span>
<b style="font-size:2rem">${params.asset === 'rupee' ? formatAmount(net, true) : toFixed(net)}</b>
${params.asset !== 'rupee' ? html`<span style="font-size: 1rem; opacity:0.8">₹${toFixed(net * floGlobals.exchangeRates[params.asset], 2)}</span>` : ''}
<b style="font-size:2rem">${params.asset === 'rupee' ? formatAmount(net) : toFixed(net)}</b>
${params.asset !== 'rupee' ? html`<span style="font-size: 1rem; opacity:0.8">₹${toFixed(net, 2)}</span>` : ''}
</div>
${locked ? html`
<div class="grid">
@ -1800,6 +1588,9 @@
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.0861 14.6534C22.3924 14.3472 22.7898 14.1486 23.2186 14.0876L44.6946 11.0319C45.2676 10.9504 45.8455 11.1432 46.2547 11.5524C47.2381 12.5358 46.8168 14.2128 45.4853 14.6146L28.6869 19.6843C28.3711 19.7796 28.0838 19.9515 27.8505 20.1848L27.0092 21.0261L28.3236 22.3404C29.0306 23.0475 29.0976 24.1522 28.5245 24.9346L52.2562 48.6662C53.0372 49.4473 53.0372 50.7136 52.2562 51.4946L51.4947 52.2561C50.7137 53.0372 49.4473 53.0372 48.6663 52.2561L24.9346 28.5245C24.1522 29.0976 23.0475 29.0306 22.3404 28.3236L21.0261 27.0092L20.1848 27.8505C19.9515 28.0838 19.7796 28.3711 19.6843 28.6869L14.6146 45.4853C14.2128 46.8168 12.5358 47.2381 11.5524 46.2547C11.1432 45.8455 10.9504 45.2675 11.0319 44.6946L14.0876 23.2186C14.1486 22.7898 14.3472 22.3924 14.6534 22.0861L15.3949 21.3447C14.8777 20.6386 14.8818 19.67 15.4072 18.9681C14.8209 18.1848 14.8837 17.0693 15.5958 16.3572L16.3573 15.5958C17.0694 14.8837 18.1848 14.8208 18.9681 15.4072C19.6701 14.8818 20.6386 14.8777 21.3447 15.3949L22.0861 14.6534Z"/>
</svg>`
},
BTC: {
icon: `<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M17.06,11.57C17.65,10.88,18,9.98,18,9c0-1.86-1.27-3.43-3-3.87L15,3h-2v2h-2V3H9v2H6v2h2v10H6v2h3v2h2v-2h2v2h2v-2 c2.21,0,4-1.79,4-4C19,13.55,18.22,12.27,17.06,11.57z M10,7h4c1.1,0,2,0.9,2,2s-0.9,2-2,2h-4V7z M15,17h-5v-4h5c1.1,0,2,0.9,2,2 S16.1,17,15,17z"/></g></svg>`
},
default: {
icon: `<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z"/></svg>`
}
@ -1808,15 +1599,8 @@
return listedAssets.hasOwnProperty(asset) ? listedAssets[asset].icon : listedAssets.default.icon;
}
function formatAmount(amount = 0, shorten = false) {
return amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR', maximumFractionDigits: shorten ? 2 : 8 })
}
// Convert milliseconds to time left in HH:MM:SS format
function getTimeLeft(milliseconds) {
const diff = milliseconds - Date.now()
const minutes = Math.floor((diff % 3600000) / 60000)
const seconds = Math.floor(((diff % 3600000) % 60000) / 1000)
return [`${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`, ((diff % 3600000) / 60000).toFixed(2)]
function formatAmount(amount = 0, currency = 'BTC') {
return amount.toLocaleString(`en-US`, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 8 })
}
// remove digitals after specified decimal places without rounding
@ -1829,35 +1613,6 @@
return parseFloat(match[0]);
}
function getSuggestedPrice(asset = pagesData.params.asset || 'FLO') {
return toFixed(parseFloat(floGlobals.exchangeRates[asset]) * deviation[tradeType])
}
function showSuggestedPrice(asset = pagesData.params.asset || 'FLO') {
renderElem(
getRef('get_price'),
html`
<div class="grid">
<div style="font-size: 0.8rem; font-weight: 500; margin-bottom: 0.3rem;">Current price</div>
<h3>${formatAmount(floGlobals.exchangeRates[asset])}</h3>
</div>
<div class="grid">
<div style="font-size: 0.8rem; font-weight: 500; margin-bottom: 0.3rem;">Valid ${tradeType === 'buy' ? 'upto' : 'until'}</div>
<h3>${formatAmount(getSuggestedPrice(asset))}</h3>
</div>
<div class="tooltip">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
<p class="banner">
${tradeType === 'buy' ?
html`<b>Valid upto</b> is the max price upto which your order can be executed, which is <b>${DEFAULT_TRADE_PRICE_DEVIATION_BUY * 100}%</b> higher than current price.` :
html`<b>Valid until</b> is the min price until which your order can be executed, which is <b>${DEFAULT_TRADE_PRICE_DEVIATION_SELL * 100}%</b> lower than current price.`
} System will always try to execute your order at the <b>nearest price possible to current price</b>.
</p>
</div>`
)
}
const chartDimensions = {
height: 0,
width: 0
@ -1875,37 +1630,20 @@
let historyLazyLoader
let portfolioAssetHistoryLazyLoader
const render = {
listedAsset(asset, rate, countDown) {
const clone = getRef('listed_asset_template').content.cloneNode(true).firstElementChild
clone.firstElementChild.href = `#/exchange?asset=${asset}`
clone.firstElementChild.dataset.listedAsset = asset
clone.querySelector('.listed-asset__icon').innerHTML = getIcon(asset)
clone.querySelector('.listed-asset__rate').textContent = formatAmount(rate)
clone.querySelector('.listed-asset__name').textContent = asset
floGlobals.countDowns.intervals[asset] = setInterval(() => {
const [timeLeft, minutes] = getTimeLeft(countDown)
clone.querySelector('.listed-asset__countdown').firstChild.textContent = timeLeft;
const pathLength = 63 - Math.ceil((minutes / 60) * 63)
clone.querySelector('.listed-asset__countdown').style.setProperty('--path-length', pathLength)
}, 1000);
floGlobals.countDowns.timeouts[asset] = setTimeout(() => {
updateRate().catch(console.error)
delete floGlobals.countDowns.timeouts[asset]
}, countDown - Date.now());
return clone
},
orderCard(orderDetails = {}) {
const { id, asset, quantity, price, time, type } = orderDetails
console.log(orderDetails)
const { id, asset, quantity, price, time_placed, type, maxPrice } = orderDetails
const card = getRef('order_template').content.cloneNode(true).firstElementChild
const unitValue = price || maxPrice
card.dataset.id = id
card.dataset.type = type
card.querySelector('.order-card__type').textContent = type
card.querySelector('.order-card__quantity').textContent = `${quantity} ${asset}`
card.querySelector('.order-card__price-type').textContent = type === 'buy' ? 'Valid upto' : 'Valid until'
card.querySelector('.order-card__price').textContent = formatAmount(price)
card.querySelector('.order-card__amount-type').textContent = type === 'buy' ? 'Locked amount' : 'Min amount'
card.querySelector('.order-card__amount').textContent = formatAmount(price * quantity, true)
card.querySelector('.order-card__time').textContent = relativeTime.from(new Date(time).getTime())
card.querySelector('.order-card__price-type').textContent = 'Price'
card.querySelector('.order-card__price').textContent = formatAmount(unitValue)
card.querySelector('.order-card__amount-type').textContent = 'Amount'
card.querySelector('.order-card__amount').textContent = formatAmount(unitValue * quantity)
card.querySelector('.order-card__time').textContent = relativeTime.from(new Date(time_placed))
return card
},
transactionCard(transactionDetails = {}) {
@ -1916,21 +1654,20 @@
card.querySelector('.completed-trade__quantity').textContent = `${quantity} ${asset}`
card.querySelector('.completed-trade__time').textContent = getFormattedTime(time)
card.querySelector('.completed-trade__price').textContent = formatAmount(unitValue)
card.querySelector('.completed-trade__total').textContent = formatAmount(parseFloat(unitValue * quantity), true)
card.querySelector('.completed-trade__total').textContent = formatAmount(parseFloat(unitValue * quantity))
card.querySelector('.more-info').dataset.buyer = buyer
card.querySelector('.more-info').dataset.seller = seller
card.querySelector('.more-info').dataset.other = other
return card
},
marketOrderCard(orderDetails = {}) {
const { floID, asset, quantity, minPrice, maxPrice, time_placed, type } = orderDetails
const { floID, asset, quantity, price, time_placed, type } = orderDetails
const card = getRef('market_order_template').content.cloneNode(true).firstElementChild
const unitValue = minPrice || maxPrice;
card.dataset.type = type
card.classList.add(`transaction-card--${type}`)
card.querySelector('.transaction-card__quantity').textContent = `${quantity} ${asset}`
card.querySelector('.transaction-card__price').textContent = formatAmount(unitValue)
card.querySelector('.transaction-card__total').textContent = formatAmount(parseFloat(unitValue * quantity), true)
card.querySelector('.transaction-card__price').textContent = formatAmount(price)
card.querySelector('.transaction-card__total').textContent = formatAmount(parseFloat(price * quantity))
card.querySelector('.more-info').dataset.time = time_placed
card.querySelector('.more-info').dataset.buyer = type === 'buy' ? floID : undefined
card.querySelector('.more-info').dataset.seller = type === 'sell' ? floID : undefined
@ -1943,7 +1680,7 @@
card.querySelector('.completed-trade__quantity').textContent = `${quantity} ${asset}`
card.querySelector('.completed-trade__time').textContent = getFormattedTime(time)
card.querySelector('.completed-trade__price').textContent = `₹${unitValue}`
card.querySelector('.completed-trade__total').textContent = formatAmount(parseFloat(unitValue * quantity), true)
card.querySelector('.completed-trade__total').textContent = formatAmount(parseFloat(unitValue * quantity))
card.querySelector('.more-info').dataset.buyer = buyer
card.querySelector('.more-info').dataset.seller = seller
return card
@ -1957,8 +1694,8 @@
card.querySelector('.balance-card__icon').innerHTML = getIcon(asset)
const templateToClone = locked ? 'locked_balance_template' : 'net_balance_template';
const assetBalance = getRef(templateToClone).content.cloneNode(true)
const availableBalance = asset === 'rupee' ? formatAmount(net, true) : `${toFixed(net)} | <span style="font-size: 0.8rem">₹${toFixed(net * floGlobals.exchangeRates[asset], 2)}</span>`
const lockedBalance = asset === 'rupee' ? formatAmount(locked, true) : toFixed(locked)
const availableBalance = asset === 'rupee' ? formatAmount(net) : `${toFixed(net)}`
const lockedBalance = asset === 'rupee' ? formatAmount(locked) : toFixed(locked)
assetBalance.querySelector('.available-balance').innerHTML = availableBalance
if (locked) {
assetBalance.querySelector('.locked-balance').textContent = lockedBalance
@ -1994,19 +1731,12 @@
const frag = document.createDocumentFragment()
const ordersType = getRef('my_orders_category_selector').value
if (ordersType === 'open') {
getRef('my_orders__title').textContent = 'My orders'
getRef('my_orders__title').textContent = 'My orders';
buyOrders = buyOrders.map(order => ({ ...order, type: 'buy' }))
sellOrders = sellOrders.map(order => ({ ...order, type: 'sell' }))
const allOpenOrders = [...buyOrders, ...sellOrders].sort((a, b) => new Date(b.time_placed).getTime() - new Date(a.time_placed).getTime())
allOpenOrders.forEach(order => {
const { id, asset, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
const orderDetails = {
id,
asset,
quantity,
type: minPrice ? 'sell' : 'buy',
price: minPrice || maxPrice,
time: time_placed
}
frag.append(render.orderCard(orderDetails))
frag.append(render.orderCard(order))
})
} else {
getRef('my_orders__title').textContent = 'My trades'
@ -2181,7 +1911,7 @@
function updateTooltip(asset, tradeType) {
getRef('quantity_selector').querySelectorAll('.button').forEach(button => {
if (tradeType === 'buy') {
button.title = `Buy ${asset} worth ${button.textContent} of total rupee`
button.title = `Buy ${asset} worth ${button.textContent} of total ${floGlobals.currency}`
} else {
button.title = `Sell ${button.textContent} of total ${asset}`
}
@ -2204,20 +1934,27 @@
getRef('trade_type_selector').addEventListener('change', e => {
tradeType = e.target.value
const selectedAsset = pagesData.params.asset
showSuggestedPrice()
getRef('get_total').setAttribute('placeholder', tradeType === 'buy' ? `Locked amount (₹)` : `Min amount received (₹)`)
getRef('trade_button').textContent = `${tradeType} ${selectedAsset}`
getRef('quantity_type').textContent = tradeType === 'buy' ? formatAmount(allTokens.rupee.net, true) : `${parseFloat(allTokens[selectedAsset].net.toFixed(4))} ${selectedAsset}`
getRef('quantity_type').textContent = `${parseFloat(allTokens[tradeType === 'buy' ? 'BTC' : selectedAsset].net.toFixed(4))} ${tradeType === 'buy' ? 'BTC' : selectedAsset}`
updateTooltip(selectedAsset, tradeType)
})
getRef('price_duration_selector').addEventListener('change', e => {
render.chart(pagesData.params.asset)
})
function getLastTradePrice() {
return new Promise((resolve, reject) => {
floTradeAPI.getTradeList().then(tradeList => {
floGlobals.lastTradePrice = tradeList[0].unitValue || 0;
getRef('flo_exchange_rate').textContent = `${floGlobals.lastTradePrice} ${floGlobals.currency}`
resolve(floGlobals.lastTradePrice)
}).catch(reject)
})
}
async function tradeAsset() {
closePopup()
const asset = pagesData.params.asset;
const quantity = parseFloat(getRef('get_quantity').value)
const price = getSuggestedPrice()
const price = getLastTradePrice()
if (tradeType === 'buy' && accountDetails.sellOrders.some(order => order.asset === asset)) {
closePopup()
return notify('You have an open sell order for this asset. Please close it before buying.', 'error')
@ -2226,6 +1963,7 @@
return notify('You have an open buy order for this asset. Please close it before selling.', 'error')
}
buttonLoader('trade_button', true)
console.log(asset, quantity, price, proxy.userID, await proxy.secret)
try {
if (tradeType === 'buy') {
await floTradeAPI.buy(asset, quantity, price, proxy.userID, await proxy.secret)
@ -2247,7 +1985,7 @@
finally {
updateRate()
getRef('get_quantity').value = 0
getRef('get_total').value = 0
getRef('set_price').value = 0
setTimeout(() => {
buttonLoader('trade_button', false)
getRef('trade_button').disabled = true
@ -2259,42 +1997,14 @@
}
getRef('quantity_selector').addEventListener('click', e => {
if (e.target.closest('button')) {
const selectedAsset = pagesData.params.asset
const selectedAsset = pagesData.params.asset;
if (!selectedAsset) return notify('Please select an asset to trade', 'error')
const target = e.target.closest('button')
const unitValue = getSuggestedPrice()
const fraction = parseFloat(target.value)
if (tradeType === 'buy') {
getRef('get_total').value = toFixed(fraction * allTokens['rupee'].net)
getRef('get_quantity').value = toFixed((allTokens['rupee'].net * fraction) / getSuggestedPrice())
} else {
getRef('get_total').value = toFixed(fraction * allTokens[selectedAsset].net * getSuggestedPrice())
getRef('get_quantity').value = toFixed(allTokens[selectedAsset].net * fraction)
}
const price = parseFloat(getRef('set_price').value.trim()) || floGlobals.lastTradePrice || 0
getRef('get_quantity').value = toFixed((allTokens[selectedAsset].net / price) * fraction)
}
})
getRef('get_quantity').addEventListener('focusin', e => {
if (tradeType === 'buy') {
getRef('quantity_selector_tip').innerHTML = `<b>Locked amount</b> is highest total amount you'll be charged for buying specified quantity, most likely you'll charged less than locked amount.`
} else {
getRef('quantity_selector_tip').innerHTML = `<b>Min amount</b> received is lowest total amount you'll get by selling specified quantity, most likely you will get more than this amount. `
}
})
getRef('get_total').addEventListener('focusin', e => {
if (tradeType === 'buy') {
getRef('quantity_selector_tip').innerHTML = `<b>Locked amount</b> is highest total amount you'll be charged for buying specified quantity, most likely you'll charged less than locked amount.`
} else {
getRef('quantity_selector_tip').innerHTML = `<b>Min amount</b> received is lowest total amount you'll get by selling specified quantity, most likely you will get more than this amount. `
}
})
getRef('get_quantity').addEventListener('keyup', e => {
const unitValue = getSuggestedPrice()
getRef('get_total').value = toFixed(parseFloat(e.target.value) * unitValue)
})
getRef('get_total').addEventListener('keyup', e => {
const unitValue = getSuggestedPrice()
getRef('get_quantity').value = toFixed(parseFloat(e.target.value) / unitValue)
})
getRef('portfolio_pages_selector').addEventListener('change', e => {
if (e.target.value === 'exchange') {
@ -2310,7 +2020,7 @@
const type = target.value
const asset = pagesData.params.asset
getRef('portfolio_quantity_type').textContent = getRef('quantity_type').textContent = asset === 'rupee' ? formatAmount(allTokens.rupee.net, true) : `${toFixed(allTokens[asset].net)} ${asset}`
getRef('portfolio_quantity_type').textContent = getRef('quantity_type').textContent = `${toFixed(allTokens[type === 'buy' ? 'BTC' : asset].net)} ${asset}`
getRef('portfolio_popup__cta').textContent = `${type} ${asset}`
getRef('portfolio_popup__cta').setAttribute('value', type)
getRef('portfolio_popup__title').textContent = `${type} ${asset}`
@ -2416,7 +2126,7 @@
case 'deposit':
const privKey = getRef('get_private_key').value;
if (asset === 'FLO') {
response = await floTradeAPI.depositFLO(quantity, proxy.userID, proxy.sinkID, privKey, proxySecret)
response = await floTradeAPI.depositFLO(quantity, proxy.userID, await proxy.sinkID, privKey, proxySecret)
} else {
response = await floTradeAPI.depositToken(asset, quantity, proxy.userID, proxy.sinkID, privKey, proxySecret)
}
@ -2672,10 +2382,7 @@
case 'confirm_trade_popup':
const asset = pagesData.params.asset;
const quantity = parseFloat(getRef('get_quantity').value)
const currentPrice = toFixed(floGlobals.exchangeRates[asset]);
const price = toFixed(getSuggestedPrice());
const total = formatAmount(parseFloat(getRef('get_total').value))
const minTotal = formatAmount(toFixed(currentPrice * quantity))
const setPrice = formatAmount(parseFloat(getRef('set_price').value))
getRef('confirm_trade__title').textContent = `${tradeType} ${asset}`
getRef('confirm_trade__details').innerHTML = `
<div class="grid">
@ -2683,20 +2390,9 @@
<b>${quantity} ${asset}</b>
</div>
<div class="grid">
<p>${tradeType === 'buy' ? 'Min cost' : 'Max earned'}</p>
<div>
<b>${minTotal}</b><span> @ ${currentPrice}/${asset}</span>
</div>
<p>At price</p>
<b>${setPrice}</b>
</div>
<div class="grid gap-0-3">
<p>${tradeType === 'buy' ? 'Max cost (Amount locked)' : 'Min earned'}</p>
<div>
<b>${total}</b><span> @ ${price}/${asset}</span>
</div>
</div>
<p>
<strong>All trades will be executed at current price.</strong>
</p>
`;
break;
}
@ -2717,62 +2413,8 @@
function updateRate(init = false) {
return new Promise((resolve, reject) => {
floTradeAPI.getRates().then(({ rates, countDown }) => {
console.debug(rates);
floGlobals.exchangeRates = rates
if (init) {
Object.entries(rates).sort((a, b) => a[1] < b[1] ? 1 : -1).forEach(([asset, rate]) => {
if (!allTokens.hasOwnProperty(asset)) {
allTokens[asset] = {
total: 0,
locked: 0,
net: 0
}
}
// dynamically render listed assets if not already rendered
getRef('listed_assets').append(render.listedAsset(asset, formatAmount(parseFloat(rate)), countDown[asset]));
getRef('market_asset_rates').append(createElement('li', {
className: 'listed-asset grid align-center',
innerHTML: `
<div class="listed-asset__icon">${getIcon(asset)}</div>
<h4 class="listed-asset__name">${asset}</h4>
<b class="listed-asset__rate">${formatAmount(rate)}</b>
`
}))
})
resolve();
} else {
// update rates in UI
for (const asset in rates) {
const listedAsset = getRef(`listed_assets`).querySelector(`[data-listed-asset="${asset}"]`)
if (listedAsset) {
listedAsset.querySelector('.listed-asset__rate').textContent = formatAmount(parseFloat(rates[asset]))
if (floGlobals.countDowns.intervals.hasOwnProperty(asset)) {
clearInterval(floGlobals.countDowns.intervals[asset]);
}
floGlobals.countDowns.intervals[asset] = setInterval(() => {
const [timeLeft, minutes] = getTimeLeft(countDown[asset])
listedAsset.querySelector('.listed-asset__countdown').firstChild.textContent = timeLeft;
const pathLength = 63 - Math.ceil((minutes / 60) * 63)
listedAsset.querySelector('.listed-asset__countdown').style.setProperty('--path-length', pathLength)
}, 1000)
if (floGlobals.countDowns.timeouts.hasOwnProperty(asset)) {
clearTimeout(floGlobals.countDowns.timeouts[asset]);
delete floGlobals.countDowns.timeouts[asset]
}
floGlobals.countDowns.timeouts[asset] = setTimeout(() => {
updateRate()
}, countDown[asset] - Date.now());
}
}
resolve();
}
render.chart(pagesData.params.asset)
showSuggestedPrice()
}).catch(error => {
notify(error.message, 'error');
reject(error)
})
render.chart(pagesData.params.asset)
resolve();
}).catch(error => console.error(error))
}
@ -2810,8 +2452,8 @@
async function account() {
floTradeAPI.getAccount(proxy.userID, await proxy.secret).then(async acc => {
document.body.classList.add('is-signed-in');
getRef('market_asset_rates').parentNode.remove()
location.hash = `#/exchange`
if (getRef('market_asset_rates'))
getRef('market_asset_rates').parentNode.remove()
getRef('user_popup_button').addEventListener('click', () => openPopup('user_popup'));
getRef('trade_button').addEventListener('click', () => openPopup('confirm_trade_popup'));
accountDetails = acc
@ -2824,15 +2466,15 @@
if (acc.subAdmin)
console.info("logged in as subAdmin");
// rupee balance init
// FLO balance init
allTokens[floGlobals.currency] = {
total: 0,
locked: 0,
net: 0
}
// token balance
acc.tokenBalance.forEach(({ token, quantity }) => {
allTokens[token] = {
acc.tokenBalance.forEach(({ asset, quantity }) => {
allTokens[asset] = {
total: quantity,
locked: 0,
net: 0
@ -2845,27 +2487,22 @@
for (const token in allTokens) {
allTokens[token].net = allTokens[token].total - allTokens[token].locked
}
console.debug("FLO", allTokens['FLO']);
console.log(await floTradeAPI.getBalance(acc.floID))
console.debug("RUPEE", allTokens['rupee']);
// render all assets in portfolio
const frag = document.createDocumentFragment();
let totalPortfolio = 0;
Object.entries(allTokens).sort((a, b) => b[1].net - a[1].net).forEach(([asset], index) => {
if (asset !== floGlobals.currency) {
totalPortfolio += allTokens[asset].net * floGlobals.exchangeRates[asset]
totalPortfolio += allTokens[asset].net
frag.append(render.assetBalanceCard(asset))
}
else {
getRef('exchange_rupee_balance').innerHTML = ``
getRef('exchange_rupee_balance').append(render.assetBalanceCard(asset))
getRef('exchange_btc_balance').innerHTML = ``
getRef('exchange_btc_balance').append(render.assetBalanceCard(asset))
}
})
getRef('my_assets').innerHTML = ''
getRef('my_assets').append(frag)
getRef('portfolio_value').textContent = formatAmount(toFixed(totalPortfolio, 2), true)
getRef('portfolio_value').textContent = formatAmount(toFixed(totalPortfolio, 2))
//My orders
render.userOrders();
@ -2874,10 +2511,6 @@
const [beforeDecimal, afterDecimal = '00'] = String(balance).split('.')
getRef('personal_flo_balance').innerHTML = `<span><b>${beforeDecimal}</b></span>.<span>${afterDecimal}</span>`
})
floTokenAPI.getBalance(accountDetails.floID, 'rupee').then(balance => {
const [beforeDecimal, afterDecimal] = formatAmount(balance, true).split('₹')[1].split('.')
getRef('personal_rupee_balance').innerHTML = `<span><b>${beforeDecimal}</b></span>.<span>${afterDecimal}</span>`
})
proxy.secret.then(_ => null).catch(_ => null);
routeTo(window.location.hash);
}).catch(error => {