PHP WebShell
Текущая директория: /var/www/bitcardoApp
Просмотр файла: create_primary.php
<?php
/**
* create_trc20_mainnet_and_keycard.php (REV)
* - Mainnet TRON (TRC20) wallet via BitGo Express (prod)
* - Uses LOCAL BACKUP XPUB (fixes "unable to allocate backup key")
* - Points to Express on 127.0.0.1:3081
* - Saves printable HTML KeyCard
* - Prints summary in your exact format
*/
date_default_timezone_set('Africa/Lagos'); // GMT+1 output
// ===== CONFIG: use ENV VARS (recommended) or edit inline for a quick test =====
$BITGO_ACCESS_TOKEN = getenv('BITGO_ACCESS_TOKEN') ?: 'v2x47b80e4e874e1af4a227a13bbfc2b3c2684db6eafd1c3739e9f3f01cb0b57be2';
$BITGO_EXPRESS_BASE = getenv('BITGO_EXPRESS_BASE') ?: 'http://127.0.0.1:3081/api/v2';
$COIN = 'trx'; // MAINNET ONLY
$WALLET_LABEL = getenv('WALLET_LABEL') ?: 'BitcardoUSDT-Pioneer';
$WALLET_PASSPHRASE = getenv('WALLET_PASSPHRASE') ?: 'u5has4ifnClVE7OsyC8f69isYBRYfv9Q';
$BACKUP_XPUB = getenv('BITGO_BACKUP_XPUB') ?: 'xpub661MyMwAqRbcFURctUNiPcN5zauFR3i3hGozsLuNFrhv2rw6PiF36bocibPrb6E2CgMqVSu2WYgFgajjEUTTBw4ZseuUDP7k2jh8YvqTxo7';
$KEYCARD_DIR = __DIR__ . '/keycards';
// ===== Basic safety checks =====
if (
$BITGO_ACCESS_TOKEN === 'REPLACE_WITH_PROD_TOKEN' ||
$WALLET_PASSPHRASE === 'REPLACE_WITH_STRONG_UNIQUE_PASSPHRASE' ||
$BACKUP_XPUB === 'REPLACE_WITH_YOUR_LOCAL_BACKUP_pub'
) {
exit("Set BITGO_ACCESS_TOKEN, WALLET_PASSPHRASE, and BITGO_BACKUP_XPUB before running.\n");
}
if (!is_dir($KEYCARD_DIR)) { mkdir($KEYCARD_DIR, 0700, true); }
// ===== Helpers =====
function http_post_json($url, $token, $payload) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Bearer ' . $token,
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 20,
]);
$resp = curl_exec($ch);
if ($resp === false) { $err = curl_error($ch); curl_close($ch); throw new Exception("HTTP request failed: $err"); }
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code < 200 || $code >= 300) { throw new Exception("HTTP $code: $resp"); }
return json_decode($resp, true);
}
function safe($v) { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
function gmt_offset_label(DateTime $dt) {
$offset = (int)$dt->getOffset();
$sign = $offset >= 0 ? '+' : '-';
$h = (string) floor(abs($offset)/3600);
$m = str_pad((string) ((abs($offset)%3600)/60), 2, '0', STR_PAD_LEFT);
return "GMT{$sign}{$h}" . ($m !== '00' ? ":{$m}" : "");
}
// ===== 1) Create wallet (MAINNET trx) using local backup xpub =====
$generate_url = rtrim($BITGO_EXPRESS_BASE, '/') . '/' . $COIN . '/wallet/generate';
$payload = [
'label' => $WALLET_LABEL,
'passphrase' => $WALLET_PASSPHRASE,
'backupXpub' => $BACKUP_XPUB // <-- use your local backup pub (fixes 400 error)
// do NOT set backupXpubProvider here
];
try {
$result = http_post_json($generate_url, $BITGO_ACCESS_TOKEN, $payload);
} catch (Exception $e) {
$msg = $e->getMessage();
// Helpful hints
if (strpos($msg, 'ECONNREFUSED') !== false || strpos($msg, 'Connection refused') !== false) {
http_response_code(503);
exit("Cannot reach BitGo Express at {$BITGO_EXPRESS_BASE}. Ensure it is running on port 3081.\n");
}
if (strpos($msg, 'Coin unsupported on testnet: trx') !== false) {
http_response_code(400);
exit("Express is in TEST. Start it with --env prod and use a PROD token.\n");
}
http_response_code(500);
exit("Error: " . $msg . "\n");
}
$wallet = $result['wallet'] ?? [];
$userKeychain = $result['userKeychain'] ?? [];
$backupKeychain = $result['backupKeychain'] ?? [];
$bitgoKeychain = $result['bitgoKeychain'] ?? [];
// prefer receiveAddress.address if present
$receiveAddr = $wallet['receiveAddress']['address'] ?? ($wallet['receiveAddress'] ?? '');
// ===== 2) Save KeyCard (HTML) =====
$now = new DateTime('now', new DateTimeZone('Africa/Lagos'));
$keycardFileName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $wallet['label'] ?? 'Wallet') . '_KeyCard_' . date('Ymd_His') . '.html';
$keycardPath = $KEYCARD_DIR . DIRECTORY_SEPARATOR . $keycardFileName;
$html = "<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>KeyCard – " . safe($wallet['label'] ?? '') . "</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
body { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace; line-height: 1.35; padding: 24px; }
.box { border: 1px solid #999; border-radius: 6px; padding: 16px; margin: 16px 0; background: #fafafa; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.muted { color: #555; font-size: 0.92em; }
code { white-space: pre-wrap; word-break: break-word; }
@media print { body { padding:0; } .no-print { display:none; } }
</style>
</head>
<body>
<h1>KeyCard (TRON / TRC20)</h1>
<div class='box'><strong>SECURITY:</strong> Print and store offline. Keep your passphrase and this card safe.</div>
<div class='box'>
<h2>Wallet</h2>
<div class='grid'>
<div><strong>Label</strong><br><code>" . safe($wallet['label'] ?? '') . "</code></div>
<div><strong>Coin</strong><br><code>" . safe($wallet['coin'] ?? 'trx') . "</code></div>
<div><strong>Wallet ID</strong><br><code>" . safe($wallet['id'] ?? '') . "</code></div>
<div><strong>Receive Address</strong><br><code>" . safe($receiveAddr) . "</code></div>
</div>
</div>
<div class='box'>
<h2>User Keychain (You)</h2>
<div class='grid'>
<div><strong>xpub</strong><br><code>" . safe($userKeychain['xpub'] ?? '') . "</code></div>
<div><strong>encryptedXprv</strong><br><code>" . safe($userKeychain['encryptedXprv'] ?? '') . "</code></div>
</div>
<p class='muted'>Your private key is encrypted with your passphrase.</p>
</div>
<div class='box'>
<h2>Backup Keychain</h2>
<div class='grid'>
<div><strong>xpub</strong><br><code>" . safe($backupKeychain['xpub'] ?? '') . "</code></div>
<div><strong>provider</strong><br><code>" . safe($backupKeychain['provider'] ?? 'local') . "</code></div>
</div>
</div>
<div class='box'>
<h2>BitGo Keychain (Co-signer)</h2>
<div><strong>xpub</strong><br><code>" . safe($bitgoKeychain['xpub'] ?? '') . "</code></div>
</div>
<p class='no-print muted'>Generated: " . safe($now->format('c')) . " • File: <code>" . safe($keycardFileName) . "</code></p>
</body>
</html>";
file_put_contents($keycardPath, $html);
chmod($keycardPath, 0600);
// ===== 3) Print EXACT summary =====
$signatureProtocol = 'Multisignature';
$perm = 'Admin';
if (!empty($wallet['permissions']) && is_array($wallet['permissions'])) {
$pl = array_map('strtolower', $wallet['permissions']);
if (in_array('admin', $pl, true)) { $perm = 'Admin'; }
elseif (in_array('spend', $pl, true)) { $perm = 'Spend'; }
elseif (in_array('view', $pl, true)) { $perm = 'View'; }
else { $perm = ucfirst($wallet['permissions'][0]); }
}
$dateLabel = $now->format('M j, Y, g:i:s A') . ' ' . gmt_offset_label($now);
echo "Label: " . ($wallet['label'] ?? '') . PHP_EOL;
echo "Wallet ID: " . ($wallet['id'] ?? '') . PHP_EOL;
echo "Wallet Add: " . $receiveAddr . PHP_EOL;
echo "Signature Protocol: " . $signatureProtocol . PHP_EOL;
echo "Your Permissions: " . $perm . PHP_EOL;
echo "Creation Date: " . $dateLabel . PHP_EOL . PHP_EOL;
echo "KeyCard saved to: " . $keycardPath . PHP_EOL;
echo "Next: fund with ~100 TRX to activate the Tron account before using USDT (TRC20)." . PHP_EOL;
Выполнить команду
Для локальной разработки. Не используйте в интернете!