diff --git a/web/yaamp/commands/PayoutCommand.php b/web/yaamp/commands/PayoutCommand.php index 128e2ef..759b248 100644 --- a/web/yaamp/commands/PayoutCommand.php +++ b/web/yaamp/commands/PayoutCommand.php @@ -35,6 +35,10 @@ class PayoutCommand extends CConsoleCommand echo "Yiimp payout command\n"; echo "Usage: yiimp payout check [fixit]\n"; echo "Usage: payout coinswaps\n"; + echo "Usage: payout confirmations \n"; + if (YIIMP_CLI_ALLOW_TXS) + echo "Usage: payout redotx \n"; + return 1; } elseif ($command == 'check') { @@ -52,6 +56,14 @@ class PayoutCommand extends CConsoleCommand } elseif ($command == 'coinswaps') { $this->checkCoinSwaps($args); return 0; + + } elseif ($command == 'confirmations') { + $this->checkPayoutsConfirmations($args); + return 0; + + } elseif ($command == 'redotx' && YIIMP_CLI_ALLOW_TXS) { + $this->redoTransaction($args); + return 0; } } @@ -263,4 +275,93 @@ class PayoutCommand extends CConsoleCommand echo "earnings: all fine\n"; } } + + /** + * Can be used to redo a payment made on a bad fork... + */ + protected function redoTransaction($args) + { + $txid = arraySafeVal($args, 1); + if (empty($txid)) + die("Usage..\n"); + + $payouts = getdbolist('db_payouts', "tx=:txid", array(':txid'=>$txid)); + if (empty($payouts)) + die("Invalid payout txid\n"); + echo "users to pay: ".count($payouts)."\n"; + + $payout = $payouts[0]; + $coin = getdbo('db_coins', $payout->idcoin); + if (!$coin || !$coin->installed) + die("Invalid payout coin id\n"); + + $relayfee = 0.0001; + + $dests = array(); $total = 0.; + foreach ($payouts as $payout) { + $user = getdbo('db_accounts', $payout->account_id); + if (!$user || $user->coinid != $coin->id) continue; + if (doubleval($payout->amount) < $relayfee) continue; // dust if < relayfee + $dests[$user->username] = doubleval($payout->amount); + $total += doubleval($payout->amount); + } + + echo "$total {$coin->symbol} to pay...\n"; + + $nbnew = 0; + $remote = new WalletRPC($coin); + $res = $remote->sendmany((string) $coin->account, $dests); + if (!$res) var_dump($remote->error); + else { + $new_txid = $res; + echo "txid: $new_txid\n"; + foreach ($payouts as $payout) { + if (doubleval($payout->amount) < $relayfee) continue; + $p = new db_payouts; + $p->time = time(); + $p->idcoin = $coin->id; + $p->amount = doubleval($payout->amount); + $p->account_id = $payout->account_id; + $p->completed = 1; + $p->fee = 0; + $p->tx = $new_txid; + $nbnew += $p->insert(); + } + echo "payouts rows added: $nbnew\n"; + if ($nbnew == count($payouts)) { + $res = dborun("UPDATE payouts SET completed=0, tx='orphaned', memoid='redo' WHERE tx=:txid", array(':txid'=>$txid)); + echo "payouts marked as 'orphaned': $res\n"; + } + } + return $nbnew; + } + + /** + * List the last payouts made for a wallet and check if the tx have confirmations + */ + protected function checkPayoutsConfirmations($args) + { + $symbol = arraySafeVal($args, 1); + if (empty($symbol)) + die("payout confirmations \n"); + + $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); + if (!$coin) { + echo "wallet $symbol not found!\n"; + return 0; + } + $since = time() - (72 * 3600); + $data = dbolist("SELECT P.tx, MAX(P.time) as time, SUM(P.amount) as amount FROM payouts P ". + "WHERE P.time>$since AND P.idcoin=".$coin->id." ". + "GROUP BY P.tx ORDER BY time DESC" + ); + + $remote = new WalletRPC($coin); + foreach ($data as $row) { + $txid = $row['tx']; + $tx = $remote->gettransaction($txid); + echo strftime('%Y-%m-%d %H:%M', $row['time'])." $txid ".$tx['confirmations']. + " confs (".altcoinvaluetoa($row['amount'],4)." $symbol, fees: ".bitcoinvaluetoa($tx['fee']).")\n"; + } + } }