-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add steem/swap, add orders in steem/profiles, update menu
- Loading branch information
1 parent
f1e1bba
commit 734b7b3
Showing
7 changed files
with
360 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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']; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>'; ?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<?php if (!defined('NOTLOAD')) exit('No direct script access allowed'); | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
Oops, something went wrong.