Skip to content

Commit

Permalink
Add steem/swap, add orders in steem/profiles, update menu
Browse files Browse the repository at this point in the history
  • Loading branch information
denis-skripnik committed Jan 12, 2021
1 parent f1e1bba commit 734b7b3
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 2 deletions.
13 changes: 12 additions & 1 deletion blockchains/steem/apps/profiles/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ function generateAppPages($blockchain_snippet) {
<th><a href="'.$conf['siteUrl'].'steem/profiles/'.$user.'/feed">Посты подписчиков</a></th>
<th><a href="'.$conf['siteUrl'].'steem/profiles/'.$user.'/comments">Комментарии</a></th>
<th><a href="'.$conf['siteUrl'].'steem/profiles/'.$user.'/witness">Делегат</a></th>
<th><a href="'.$conf['siteUrl'].'steem/profiles/'.$user.'/orders">Ордера</a></th>
</tr></table>';
if (!isset(pageUrl()[3])) {
$data['title'] .= ' - основное';
Expand Down Expand Up @@ -163,8 +164,18 @@ function generateAppPages($blockchain_snippet) {
$data['content'] .= $blockchain_snippet;
$data['content'] .= $pages;
$data['content'] .= require_once(__DIR__.'/page/feed.php');
} else if (isset(pageUrl()[3]) && pageUrl()[3] == 'orders') {
$data['title'] .= ' - ордера на dex';
$data['description'] .= ' - ордера на dex';
$data['content'] = '<script>
ajax_options.user = `'.$user.'`;
ajax_options.siteUrl = `'.$conf['siteUrl'].'`;
getLoad(`'.$conf['siteUrl'].'blockchains/steem/apps/profiles/page/orders.php`, `ajax_content`, `Следующие 10`, `Предыдущие 10`)(START_MODE)
</script>';
$data['content'] .= $blockchain_snippet;
$data['content'] .= $pages;
$data['content'] .= require_once(__DIR__.'/page/orders.php');
}

}
return $data;
}
Expand Down
87 changes: 87 additions & 0 deletions blockchains/steem/apps/profiles/page/orders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
define('AUTHOR_REWARDS_LIMIT', 10);
global $conf;
require 'snippets/get_account_history_chunk.php';

if (!isset($user) && isset($_REQUEST['options']['user'])) { // проверяем существование элемента
$user = $_REQUEST['options']['user'];
} else if (!isset($user) && !isset($_REQUEST['options']['user'])) {
return;
}

$site_url = '';
if (isset($_REQUEST['options']['siteUrl'])) {
$site_url = $_REQUEST['options']['siteUrl'];
} else if (isset($conf['siteUrl'])) {
$site_url = $conf['siteUrl'];
}

$rowCount = 0;

$startWith = $_REQUEST['start'] ?? 300000000;

$res = getAccountHistoryChunk($user, $startWith, ['select_ops' => ['fill_order']]);

$mass = $res['result'];

if (! $mass) {
$result['content'] = '<p>Результатов нет. Возможно все подходящие операции в истории далеко или такого пользователя не существует. Проверьте правильность написания логина. Сейчас введён: '.$user.'</p>';
if (isset($_REQUEST['options']) || isset($_GET['options'])) {
echo json_encode($result);
return;
} else {
return $result['content'];
}
}

krsort($mass);

$result['content'] = '<div id="ajax_content"><h2>Ордера на внутренней бирже, связанные с пользователем '.$user.'</h2>
<table id="rewards-ol">
<tr><th>Дата и время</th>
<th>продавец</th>
<th>покупатель</th>
<th>сумма на продажу</th>
<th>Сумма на покупку</th>
</tr>';
foreach ($mass as $datas) {
if ($rowCount === AUTHOR_REWARDS_LIMIT) {
break;
}
$startWith = $datas[0] - 1;


$op = $datas[1]['op'];
$month = array('01' => 'января', '02' => 'февраля', '03' => 'марта', '04' => 'апреля', '05' => 'мая', '06' => 'июня', '07' => 'июля', '08' => 'августа', '09' => 'сентября', '10' => 'октября', '11' => 'ноября', '12' => 'декабря');
$timestamp1 = $datas[1]['timestamp'];
$timestamp2 = strtotime($timestamp1);
$month2 = date('m', $timestamp2);
$timestamp = date('j', $timestamp2).' '.$month[$month2].' '.date('Y г. H:i:s', $timestamp2);
$timestamp = '<a href="'.$site_url.'steem/explorer/tx/'.$datas[1]['trx_id'].'" target="_blank">'.$timestamp.'</a>';
$op1 = $op[1];
if ($op[0] == 'fill_order') {
$rowCount++;
$seller = $op[1]['current_owner'] ?? "";
$buyer = $op[1]['open_owner'] ?? "";
$sell_amount = $op[1]['current_pays'] ?? "";
$buy_amount = $op[1]['open_pays'];
$result['content'] .= '<tr><td>' . $timestamp . '</td>
<td><a href="'.$site_url.'steem/profiles/'.$seller.'" target="_blank">'.$seller.'</a></td>
<td><a href="'.$site_url.'steem/profiles/'.$buyer.'" target="_blank">'.$buyer.'</a></td>
<td>'.$sell_amount.'</td>
<td>'.$buy_amount.'</td></tr>';
}
}

$result['content'] .= '</table><br>';

$result['nextIsExists'] = $startWith !== '';
if ($result['nextIsExists']) {
$result['next'] = $startWith;
}
$result['content'] .= '</div>';
if (isset($_REQUEST['options']) || isset($_GET['options'])) {
echo json_encode($result);
} else {
return $result['content'];
}
6 changes: 6 additions & 0 deletions blockchains/steem/apps/swap/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"title": "Dpos.space Steem swap",
"description": "Dpos.space Steem swap - сервис по обмену STEEM и SBD.",
"in_menu": "Swap",
"category": "tools"
}
32 changes: 32 additions & 0 deletions blockchains/steem/apps/swap/content.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php if (!defined('NOTLOAD')) exit('No direct script access allowed');
return '<div id="active_auth_msg" style="display: none;"><p>Для обмена необходим активный ключ. Укажите его <a href="'.$conf['siteUrl'].'golos/accounts" target="_blank">на странице аккаунтов</a>. Если вы авторизованы, удалите аккаунт и добавьте с активным ключом; Если нет, авторизуйтесь с указанием обоих ключей.</p></div>
<div id="active_page">
<h2>Обменять</h2>
<p>Отображаются только токены с ненулевым балансом, т.к. если у вас 0, нечего обменивать.</p>
<hr>
<form class="form">
<select id="sell_token">
<option value="STEEM">STEEM</option>
<option value="SBD">SBD</option>
</select>
<p><label for="sell_amount">Сумма продажи (Максимум <span id="max_amount">0</span>): <br>
<input type="text" name="sell_amount" id="sell_amount" value="" placeholder="Сумма в виде числа без имени токена"></label></p>
<p><strong>Покупаем <span id="buy_token"></span></strong></p>
<p><label for="buy_amount">Сумма покупки (<a id="change_mode" data-mode="true">Создать произвольный ордер</a>): <br>
<input type="text" readonly name="buy_amount" id="buy_amount" value="" placeholder="Суммак получению"></label></p>
<hr>
<p align="center" color="red"><strong>Курс: <span id="market_price"></span></strong></p>
<p><input type="button" id="action_buy_token" value="Обменять"></p>
</form>
<div><h2>Открытые ордера</h2>
<table><thead>
<th>Дата создания</th>
<th>Сумма продажи</th>
<th>Сумма покупки</th>
<th>Курс</th>
<th>Действие</th>
</thead>
<tbody id="my_orders_list"></tbody>
</table></div>
<p><strong><a id="orders_history" target="_blank">История обменов</a></strong></p>
</div>'; ?>
2 changes: 2 additions & 0 deletions blockchains/steem/apps/swap/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php if (!defined('NOTLOAD')) exit('No direct script access allowed');
?>
220 changes: 220 additions & 0 deletions blockchains/steem/apps/swap/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
Number.prototype.toFixedNoRounding = function(n) {
const reg = new RegExp(`^-?\\d+(?:\\.\\d{0,${n}})?`, 'g')
const a = this.toString().match(reg)[0];
const dot = a.indexOf('.');

if (dot === -1) {
return a + '.' + '0'.repeat(n);
}

const b = n - (a.length - dot) + 1;

return b > 0 ? (a + '0'.repeat(b)) : a;
}

async function deleteOrder(orderid) {
let q = window.confirm('Вы действительно хотите удалить этот ордер?');
if (q == true) {
try {
await steem.broadcast.limitOrderCancelAsync(active_key, steem_login, orderid);
window.alert('Ордер удалён.');
await myOrders();
await getSelectedToken();
} catch(e) {
console.log(e);
}
}
}

function fast_str_replace(search,replace,str){
return str.split(search).join(replace);
}

function date_str(timestamp,add_time,add_seconds,remove_today=false){
if(-1==timestamp){
var d=new Date();
}
else{
var d=new Date(timestamp);
}
var day=d.getDate();
if(day<10){
day='0'+day;
}
var month=d.getMonth()+1;
if(month<10){
month='0'+month;
}
var minutes=d.getMinutes();
if(minutes<10){
minutes='0'+minutes;
}
var hours=d.getHours();
if(hours<10){
hours='0'+hours;
}
var seconds=d.getSeconds();
if(seconds<10){
seconds='0'+seconds;
}
var datetime_str=day+'.'+month+'.'+d.getFullYear();
if(add_time){
datetime_str=datetime_str+' '+hours+':'+minutes;
if(add_seconds){
datetime_str=datetime_str+':'+seconds;
}
}
if(remove_today){
datetime_str=fast_str_replace(date_str(-1)+' ','',datetime_str);
}
return datetime_str;
}

async function myOrders() {
$('#my_orders_list').css('display', 'block');
let sell_token = $('#sell_token').val();
let buy_token = $('#buy_token').html();
try {
let orders = await steem.api.getOpenOrdersAsync(steem_login);
const timezoneOffset = (new Date()).getTimezoneOffset() * 60000;
let table = '';
for (let order of orders) {
let sell_price = order.sell_price;
let get_time = Date.parse(order.created);

table += `<tr>
<td>${date_str(get_time - timezoneOffset, true, false, true)}</td>
<td>${sell_price.base}</td>
<td>${sell_price.quote}</td>
<td>${parseFloat(order.real_price).toFixed(5)} ${buy_token} / ${sell_token}</td>
<td><a onclick="deleteOrder(${order.orderid});">Удалить</a></td>
</tr>`;
}
$('#my_orders_list').html(table);
} catch(e) {
console.log('Ошибка: ' + e);
}
}

async function creationOrder(sell_amount, selected_sell_token, selected_buy_token) {
$('#buy_amount').val('');
$('#market_price').html('');
$('#action_buy_token').attr('disabled', true);

let get_orders = await steem.api.getOrderBookAsync(100);
let orders = get_orders.bids;
if (selected_sell_token === 'SBD') {
orders = get_orders.asks;
}
if (orders.length > 0) {
let asset1_counter = 0;
let price_counter = 0;
let orders_counter = 0;
for (let order of orders) {
orders_counter++;
asset1_counter += parseFloat(order[selected_sell_token.toLowerCase()]) / (10 ** 3);
price_counter += parseFloat(order.real_price);
if (asset1_counter >= sell_amount) {
break;
}
}
if (asset1_counter < sell_amount) {
window.alert(`Сумма продажи больше имеющейся на рынке ${asset1_counter.toFixedNoRounding(3)} ${selected_buy_token}. Попробуйте позже или измените цену продажи на меньшую.`);
$('#action_buy_token').attr('disabled', true);
} else {
$('#action_buy_token').attr('disabled', false);
let price = price_counter / orders_counter;
price = price.toFixedNoRounding(8);
price = parseFloat(price);
let buy_amount = sell_amount * price;
if (selected_sell_token === 'SBD') {
buy_amount = sell_amount / price;
}
if (buy_amount && parseFloat(buy_amount.toFixedNoRounding(3)) === 0) $('#action_buy_token').attr('disabled', true); // Либо добавить атрибут disabled window.alert(buu)
$('#buy_amount').val(buy_amount.toFixedNoRounding(3));
$('#market_price').html(`${price.toFixed(5)} ${selected_buy_token} / ${selected_sell_token}`);
}
} else {
window.alert(`Ордеров на покупку ${selected_sell_token} за ${selected_buy_token} нет.`);
}
}

async function getSelectedToken() {
let accounts = await steem.api.getAccountsAsync([steem_login]);
if (accounts && accounts.length > 0) {
let acc = accounts[0];
let selected = $('#sell_token').val();
if (selected === 'STEEM') {
$('#max_amount').html(parseFloat(acc.balance));
$('#buy_token').html('SBD');
} else {
$('#max_amount').html(parseFloat(acc.sbd_balance));
$('#buy_token').html('STEEM');
}
}
}

$(document).ready(async function() {
$('#orders_history').attr('href', `https://dpos.space/steem/profiles/${steem_login}/orders`);
$('#action_buy_token').attr('disabled', true); // Либо добавить атрибут disabled

await getSelectedToken();
await myOrders();

$('#sell_token').change(async function() {
await getSelectedToken();
await myOrders();
});

$('#max_amount').click(async function() {
let max_amount = $('#max_amount').html();
$('#sell_amount').val(max_amount);
await creationOrder(max_amount, $('#sell_token').val(), $('#buy_token').html());
});

$('#sell_amount').change(async function() {
await creationOrder($('#sell_amount').val(), $('#sell_token').val(), $('#buy_token').html());
});

$('#action_buy_token').click(async function() {
let selected_sell_token = $('#sell_token').val();
let selected_buy_token = $('#buy_token').html();
let sell_amount = parseFloat($('#sell_amount').val());
let buy_amount = parseFloat($('#buy_amount').val());
let q = window.confirm('Вы действительно хотите совершить обмен?');
if (q == true) {
let orderid = Math.floor(Date.now() / 1000); // it is steemit.com way and it is preferred
let expiration = new Date();
expiration.setHours(expiration.getHours() + 24);
expiration = expiration.toISOString().substr(0, 19); // i.e. 2020-09-07T11:33:00
let moment_swap = JSON.parse($('#change_mode').attr('data-mode'));
try {
let res = await steem.broadcast.limitOrderCreateAsync(active_key, steem_login, orderid, sell_amount.toFixedNoRounding(3) + ' ' + selected_sell_token, buy_amount.toFixedNoRounding(3) + ' ' + selected_buy_token, moment_swap, expiration);
if (res) {
if (moment_swap === true) {
window.alert('Обмен произведён');
} else {
window.alert('Ордер успешно создан.');
await myOrders();
}
location.reload();
}
} catch(e) {
window.alert(e);
}
}
});

$('#change_mode').on('click', function() {
let moment_swap = $('#change_mode').attr('data-mode');
if (moment_swap === 'true') {
$('#change_mode').attr('data-mode', `false`);
$('#change_mode').html('Моментальный обмен');
$('#buy_amount').attr('readonly', false);
} else {
$('#change_mode').attr('data-mode', `true`);
$('#change_mode').html('Создать произвольный ордер');
$('#buy_amount').attr('readonly', true);
}
});
}); // end document ready function.
Loading

0 comments on commit 734b7b3

Please sign in to comment.