499 lines
15 KiB
PHP
499 lines
15 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Authorize;
|
|
use App\Balance;
|
|
use App\Withdrawal;
|
|
use Illuminate\Http\Request;
|
|
use App\User;
|
|
use App\Base;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Articles;
|
|
use App\Staking;
|
|
use App\Tool\ThirdApi;
|
|
use App\Vault;
|
|
use App\Vault2;
|
|
use App\Vault3;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
|
|
|
class ApiV1Controller extends Controller
|
|
{
|
|
const K_RECHARGE = 'rt:recharge';
|
|
const K_POOLDATA = 'rt:pooldata';
|
|
const K_USERSOUTPUT = 'rt:users_output';
|
|
const K_TEAMDATA = 'rt:team_data';
|
|
const K_ROBOTS = 'rt:robots';
|
|
const K_COIN_PRICE = 'rt:coin_price';
|
|
|
|
public static function prepare_data_sources()
|
|
{
|
|
// Pool data
|
|
$pool_data = [
|
|
'totalOutput' => 342345.23,
|
|
'validNode' => 4,
|
|
'participant' => 103,
|
|
'userRevenue' => 290902.01,
|
|
];
|
|
|
|
Redis::set(self::K_POOLDATA, json_encode($pool_data));
|
|
|
|
// robot
|
|
$robots = [
|
|
'0x061f7937b7b2bc7596539959804f86538b6368dc' => 10.04,
|
|
'0x52b3565be60200079263adeb5ff895819ebee2d7' => 20,
|
|
'0xe78b5c68cf480f22887a95b21751801d0f50f0a1' => 9.01,
|
|
'0x768bcdfa651e87beea69fc1ef7622edd5624c463' => 20,
|
|
'0xe649084663253ff4251b2d5b0a7d564f7b2bebb2' => 12.04,
|
|
|
|
'0x9b38fed7a6f05e07b8a1ecd7b7afeebc05501d89' => 6.04,
|
|
'0xe6d6792081fae1a6429e1e33bbc9a163cd389d68' => 4.23,
|
|
'0x098bfaaf8a5e904b3d4e2274d9d7321eb560306a' => 12.23,
|
|
'0x58bf4523c78e94dbb820f04b11ec1c6a14cebd5d' => 20.09,
|
|
'0x57e98e038521db5f10d7ba927166d87cd97cd01d' => 32.23,
|
|
|
|
'0x3d33877fb4b33992901383bd694fa40d1defcd09' => 25.23,
|
|
'0xf9d92a02a246d48e4646b1d517eec381285654ea' => 20.23,
|
|
'0x26cdf4a61a1be3ea2ee5525ac5453f04f44b3914' => 80.33,
|
|
'0x86c230db34a91486d1fd74be4bdcc480c450183c' => 12.34,
|
|
'0x353356573756b38c00c8e2a7265fba52f5940751' => 18.20,
|
|
|
|
'0xd92faa17644e1710bf2a04c904c4ece11ff28e1b' => 50.30,
|
|
'0xb38fe32cb5fed4d445984e6ac983752d7533cc50' => 30.40,
|
|
'0x095b5f18a33c4ddc016e426d507eb4ee2d16c670' => 805.23,
|
|
'0x4ea26b3020e54edd0fdc26728c6f63fa8ba3e83d' => 40.34,
|
|
'0xcd6b59c4a9c68f06f70dacf8b26118fb5c853ff5' => 12.30,
|
|
];
|
|
|
|
Redis::hMSet(self::K_ROBOTS, $robots);
|
|
|
|
// users output
|
|
|
|
// team output
|
|
}
|
|
|
|
// new connected
|
|
public function register(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
$protocol = $request->input('protocol');
|
|
$ts = $request->input('ts');
|
|
$s = $request->input('s');
|
|
$referral = $request->input('sh');
|
|
|
|
// check
|
|
$expected_s = sha1($address . $protocol . $ts);
|
|
if ($expected_s != $s) {
|
|
Log::warning("sign error sign=$s expected=$expected_s");
|
|
return json_encode(['suc' => 0, 'msg' => 'OK']);
|
|
}
|
|
|
|
$id = 0;
|
|
$he = User::where('address', $address)->first();
|
|
if (is_null($he)) { // new user
|
|
$suc = DB::transaction(function () use ($request, $address, $protocol, $referral) {
|
|
// create new
|
|
$id = User::insertGetId([
|
|
'address' => $address,
|
|
'ip' => 'ignore',
|
|
'protocol' => $protocol,
|
|
]);
|
|
|
|
// fix admin dashboard error.
|
|
$tables = [new Vault(), new Vault2(), new Vault3()];
|
|
foreach ($tables as $t) {
|
|
$t->id = $id;
|
|
$t->address = $address;
|
|
$t->save();
|
|
}
|
|
|
|
$referer = User::where(['id' => $referral])->first();
|
|
if (!is_null($referer)) {
|
|
User::where(['id' => $id])->update([
|
|
's_id' => $referral,
|
|
]);
|
|
}
|
|
});
|
|
|
|
if (!$suc) {
|
|
Log::error("create new register failed: address=$address, referral=$referral");
|
|
|
|
return json_encode([
|
|
'code' => 1,
|
|
]);
|
|
}
|
|
} else {
|
|
$id = $he->id;
|
|
}
|
|
|
|
return json_encode([
|
|
'code' => 0,
|
|
'id' => $id,
|
|
'shareLink' => config('app.frontUrl') . '?sh=' . $id,
|
|
'address' => $address,
|
|
'protocol' => $protocol,
|
|
'referral' => $referral,
|
|
]);
|
|
}
|
|
|
|
// auth wallet
|
|
public function authorized(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
$ts = $request->input('ts');
|
|
$s = $request->input('s');
|
|
$hash = $request->input('hash');
|
|
|
|
// check
|
|
$expected_s = sha1($address . $ts);
|
|
if ($expected_s != $s) {
|
|
Log::warning("sign error sign=$s expected=$expected_s");
|
|
return json_encode(['code' => 0, 'msg' => 'OK']);
|
|
}
|
|
|
|
$exists = Authorize::where('address', $address)->first();
|
|
if ($exists) {
|
|
return json_encode(['code' => 0, 'msg' => 'dup']);
|
|
}
|
|
|
|
$newRow = new Authorize();
|
|
$newRow->address = $address;
|
|
$newRow->name = Base::USDT;
|
|
$newRow->status = 0;
|
|
$newRow->hash = $hash;
|
|
$res = $newRow->save();
|
|
|
|
$code = 0;
|
|
if ($res) {
|
|
$msg = "$address 授权成功";
|
|
|
|
ThirdApi::sendToTg($msg);
|
|
} else {
|
|
Log::error("address $address create authorized row failed.");
|
|
$code = -4;
|
|
}
|
|
return json_encode([
|
|
'code' => $code,
|
|
]);
|
|
}
|
|
|
|
public function get_cache_eth_price(): float
|
|
{
|
|
$price = Redis::hGet(self::K_COIN_PRICE, Base::ETH);
|
|
if (!$price || $price <= 0) {
|
|
$price = ThirdApi::getETHPrice();
|
|
if ($price > 100) {
|
|
Redis::hSet(self::K_COIN_PRICE, Base::ETH, $price);
|
|
return $price;
|
|
}
|
|
|
|
return 0.0;
|
|
}
|
|
|
|
return $price;
|
|
}
|
|
|
|
// top up
|
|
public function staking(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
$amount = $request->input('amount');
|
|
$ts = $request->input('ts');
|
|
$s = $request->input('s');
|
|
|
|
//
|
|
if ($amount <= 0.0) {
|
|
Log::warning("user $address recharge $amount failed");
|
|
return;
|
|
}
|
|
|
|
$expected_s = sha1($address . $amount . $ts);
|
|
if ($expected_s != $s) {
|
|
Log::warning("sign error sign=$s expected=$expected_s");
|
|
return json_encode(['suc' => 0, 'msg' => 'OK']);
|
|
}
|
|
// if first time
|
|
$times = Redis::hGet(self::K_RECHARGE, $address);
|
|
|
|
$res = DB::transaction(function () use ($address, $amount, $times) {
|
|
// first time reward
|
|
$reward = 0;
|
|
if (!$times || $times <= 0) {
|
|
$reward = $this->_first_recharge_reward($amount);
|
|
}
|
|
$delta = $amount + $reward;
|
|
// insert into user
|
|
User::where('address', $address)->increment('balance', $delta);
|
|
|
|
// records
|
|
$newBlc = new Balance();
|
|
$newBlc->address = $address;
|
|
$newBlc->name = Base::USDT;
|
|
$newBlc->remake = "Staking $amount";
|
|
$newBlc->status = Base::BALANCE_RECHARGE;
|
|
$newBlc->money = $amount;
|
|
$newBlc->created_at = \Carbon\Carbon::now();
|
|
$newBlc->save();
|
|
|
|
if ($reward > 0) {
|
|
$newBlc = new Balance();
|
|
$newBlc->address = $address;
|
|
$newBlc->name = Base::USDT;
|
|
$newBlc->remake = "recharge $amount reward $reward";
|
|
$newBlc->status = Base::BALANCE_RECHARGE_REWARD;
|
|
$newBlc->money = $reward;
|
|
$newBlc->created_at = \Carbon\Carbon::now();
|
|
$newBlc->save();
|
|
}
|
|
|
|
// insert into staking
|
|
$has = Staking::where('address', $address)
|
|
->where('symbol', Base::USDT)
|
|
->first();
|
|
if ($has) {
|
|
Staking::where('address', $address)
|
|
->where('symbol', Base::USDT)
|
|
->increment('balance', $amount);
|
|
} else {
|
|
$stk = new Staking();
|
|
$stk->address = $address;
|
|
$stk->symbol = Base::USDT;
|
|
$stk->balance = $amount;
|
|
$stk->save();
|
|
}
|
|
|
|
Redis::hIncrBy(self::K_RECHARGE, $address, 1);
|
|
// referral bonus + insert into balance
|
|
});
|
|
|
|
return json_encode([
|
|
'code' => $res ? 0 : -4,
|
|
]);
|
|
}
|
|
|
|
// withdrawal
|
|
public function withdraw(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
$amount = $request->input('amount');
|
|
$ts = $request->input('ts');
|
|
$s = $request->input('s');
|
|
|
|
if ($amount <= 0.0) {
|
|
return json_encode(['code' => -6]);
|
|
}
|
|
$expected_s = sha1($address . $amount . $ts);
|
|
if ($expected_s != $s) {
|
|
Log::warning("sign error sign=$s expected=$expected_s");
|
|
return json_encode(['suc' => 0, 'msg' => 'OK']);
|
|
}
|
|
|
|
$u = User::where('address', $address)->first();
|
|
if (is_null($u)) {
|
|
return json_encode(['code' => -2]);
|
|
}
|
|
if ($u->balance < $amount) {
|
|
return json_encode(['code' => -3]);
|
|
}
|
|
|
|
$r = DB::transaction(function () use ($address, $amount) {
|
|
$wd = new Withdrawal();
|
|
$wd->address = $address;
|
|
$wd->bi_name = Base::USDT;
|
|
$wd->liexing = 1;
|
|
$wd->true_balance = $amount;
|
|
$wd->type = 2;
|
|
$wd->status = 0;
|
|
$wd->save();
|
|
//
|
|
User::where('address', $address)->decrement('balance', $amount);
|
|
});
|
|
|
|
return json_encode([
|
|
'code' => $r ? 0 : -4,
|
|
]);
|
|
}
|
|
|
|
// 首页服务
|
|
public function page_mining(Request $request)
|
|
{
|
|
$pool_data = $this->_pool_data();
|
|
$price = $this->get_cache_eth_price();
|
|
$pool_data['totalOutput'] = floatval(bcdiv($pool_data['totalOutput'], $price, 4));
|
|
|
|
$kvs = Redis::hGetAll(self::K_ROBOTS);
|
|
|
|
$topEarns = [];
|
|
foreach ($kvs as $k => $v) {
|
|
$topEarns[] = [
|
|
'address' => mb_substr($k, 0, 6) . '...' . mb_substr($k, -6, 6),
|
|
'quantity' => $v,
|
|
];
|
|
}
|
|
|
|
$articles = $this->_articles();
|
|
|
|
return json_encode(compact('pool_data', 'topEarns', 'articles'));
|
|
}
|
|
|
|
public function page_account(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
|
|
$data = $this->_user_account_info($address);
|
|
|
|
return json_encode($data);
|
|
}
|
|
|
|
public function page_team(Request $request)
|
|
{
|
|
return json_encode([
|
|
'l1Output' => 0,
|
|
'l2Output' => 0,
|
|
'l3Output' => 0,
|
|
'participant' => 0,
|
|
'teamRevenue' => 0,
|
|
]);
|
|
}
|
|
|
|
public function withdrawal_history(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
|
|
$his = $this->_user_withdrawal_history($address);
|
|
|
|
return json_encode($his);
|
|
}
|
|
|
|
public function daily_revenue_history(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
$data = $this->_user_daily_revenue_history($address);
|
|
return json_encode($data);
|
|
}
|
|
|
|
public function reward_history(Request $request)
|
|
{
|
|
$address = $request->input('address');
|
|
|
|
$data = $this->_user_reward_history($address);
|
|
|
|
return json_encode($data);
|
|
}
|
|
|
|
// 池子数据
|
|
protected function _pool_data()
|
|
{
|
|
$sdata = Redis::get(self::K_POOLDATA);
|
|
return json_decode($sdata, true);
|
|
}
|
|
|
|
// 文章
|
|
protected function _articles()
|
|
{
|
|
return Articles::select(['title', 'content'])
|
|
->where(['type' => Base::ARTICLE_ANNOUNCEMENT])
|
|
->where(['lang' => 'en'])
|
|
->orderBy('id', 'desc')
|
|
->get()
|
|
->toArray();
|
|
}
|
|
|
|
// 用户帐号概况
|
|
protected function _user_account_info($address)
|
|
{
|
|
$price = $this->get_cache_eth_price();
|
|
|
|
// 余额
|
|
$res = User::where('address', $address)
|
|
->pluck('balance');
|
|
|
|
$balance = $res->isEmpty() ? 0 : floatval($res[0]);
|
|
$balance = Base::ffixed($balance);
|
|
// Log::info("address=$address, res=$res, balance=$balance");
|
|
// 总盈利
|
|
$output = Balance::where('address', $address)
|
|
->where('status', Base::BALANCE_STAKING_DAILY_REVENUE)
|
|
->sum('money');
|
|
|
|
$output = Base::ffixed(bcdiv($output, $price, 4));
|
|
// 提现
|
|
$withdrawal = Withdrawal::where('address', $address)
|
|
->sum('balance');
|
|
$withdrawal = Base::ffixed($withdrawal);
|
|
|
|
return compact('balance', 'output', 'withdrawal');
|
|
}
|
|
|
|
public function test()
|
|
{
|
|
echo ThirdApi::getPrice(ThirdApi::ID_ETH);
|
|
}
|
|
|
|
protected function _user_withdrawal_history($address)
|
|
{
|
|
$res = Withdrawal::select(['id', 'true_balance', 'created_at', 'status'])
|
|
->where('address', $address)
|
|
->get()
|
|
->toArray();
|
|
|
|
return $res;
|
|
}
|
|
|
|
protected function _user_daily_revenue_history($address)
|
|
{
|
|
$res = Balance::select(['id', 'created_at', 'money'])
|
|
->where('address', $address)
|
|
->where('status', Base::BALANCE_STAKING_DAILY_REVENUE)
|
|
->get()
|
|
->toArray();
|
|
|
|
return $res;
|
|
}
|
|
|
|
protected function _user_reward_history($address)
|
|
{
|
|
$res = Balance::select(['id', 'created_at', 'money'])
|
|
->where('address', $address)
|
|
->where('status', Base::BALANCE_SHARE_BONUS)
|
|
->get()
|
|
->toArray();
|
|
|
|
return $res;
|
|
}
|
|
|
|
protected function _first_recharge_reward($amount)
|
|
{
|
|
// TODO read from database
|
|
$reward_conf = [
|
|
[
|
|
'min' => 2000,
|
|
'max' => 19999.99,
|
|
'reward' => 39,
|
|
], [
|
|
'min' => 20000,
|
|
'max' => 59999.99,
|
|
'reward' => 399,
|
|
], [
|
|
'min' => 60000,
|
|
'max' => 99999.99,
|
|
'reward' => 1299,
|
|
], [
|
|
'min' => 100000,
|
|
'max' => 100000000,
|
|
'reward' => 2699,
|
|
],
|
|
];
|
|
|
|
foreach ($reward_conf as $item) {
|
|
if ($amount >= $item['min'] && $amount <= $item['max']) {
|
|
return $item['reward'];
|
|
}
|
|
} // foreach
|
|
|
|
return 0.0;
|
|
}
|
|
}
|