PHP WebShell

Текущая директория: /var/www/bitcardoApp

Просмотр файла: create_primary_wallet.php

<?php
/**
 * create_primary_wallet.php
 *
 * Creates ONE primary wallet on BitGo MAINNET for ETH, SOL, or USDT-TRC20.
 * If COIN = 'USDT', we create a TRX wallet (TRON), because USDT-TRC20 lives on TRON.
 *
 * HOW TO USE
 * 1) Set constants below.
 * 2) Run: php create_primary_wallet.php
 *    or browse: https://wallet.bitcardo.com/path/to/create_primary_wallet.php
 *
 * Outputs: wallet id, primary receive address, and BitGo Keycard (BitGo keychain metadata).
 */

header('Content-Type: application/json');

// -------------------- CONFIG (SET THESE) --------------------

// 'ETH' | 'SOL' | 'USDT'  (USDT => TRX wallet for TRC20)
const COIN = 'USDT';

// IMPORTANT: This is BitGo EXPRESS (local), NOT app.bitgo.com
// We already confirmed this is healthy via /api/v2/ping
const BITGO_EXPRESS_URL       = 'http://127.0.0.1:3090/api/v2';

const BITGO_ACCESS_TOKEN      = 'v2x1e7e3ce1f27a35c97485f981f66a0d7ca718ed70a966d52aa582124909a76f57';
const BITGO_ENTERPRISE_ID     = '69160fbdcddce9e68c4ff42d943f37f4'; // your real enterprise id
const BITGO_WALLET_PASSPHRASE = 'CorrectHorse!BatteryStaple#2025-Blue-Mango$Rare7';
// ------------------------------------------------------------

function fail($msg, $code = 400) {
    http_response_code($code);
    echo json_encode(['ok' => false, 'error' => $msg], JSON_PRETTY_PRINT);
    exit;
}

function bitgo_request($method, $path, $payload = null) {
    // $path should start with "/{coin}/..." or "/key/..."
    $base = rtrim(BITGO_EXPRESS_URL, '/');
    $url  = $base . $path;

    $ch = curl_init($url);
    $headers = [
        'Authorization: Bearer ' . BITGO_ACCESS_TOKEN,
        'Content-Type: application/json',
    ];
    $opts = [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_TIMEOUT        => 60,
        CURLOPT_SSL_VERIFYPEER => false, // http only, but harmless
        CURLOPT_SSL_VERIFYHOST => false,
    ];
    if (strtoupper($method) === 'POST') {
        $opts[CURLOPT_POST] = true;
        if ($payload !== null) {
            $opts[CURLOPT_POSTFIELDS] = json_encode($payload);
        }
    }

    curl_setopt_array($ch, $opts);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlErr  = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        fail("cURL error: {$curlErr}", 500);
    }

    $data = json_decode($response, true);

    if ($httpCode < 200 || $httpCode >= 300) {
        fail([
            'message'  => "BitGo returned HTTP {$httpCode}",
            'endpoint' => $url,
            'request'  => $payload,
            'response' => $data ?: $response
        ], 502);
    }

    return $data;
}

// Map requested coin to BitGo coin code
$coinMap = [
    'ETH'  => 'eth',
    'SOL'  => 'sol',
    'USDT' => 'trx', // USDT-TRC20 uses TRON wallet (TRX)
];

$requestedCoin = strtoupper(trim(COIN));
if (!isset($coinMap[$requestedCoin])) {
    fail("Unsupported coin '".COIN."'. Use ETH, SOL, or USDT (TRC20).");
}

$bitgoCoin = $coinMap[$requestedCoin];

// Build wallet label
$labelCoin = ($requestedCoin === 'USDT') ? 'TRX (for USDT-TRC20)' : $requestedCoin;
$label     = "Primary {$labelCoin} Wallet - " . date('Ymd-His');

// Build payload for wallet generation
$payload = [
    'label'      => $label,
    'passphrase' => BITGO_WALLET_PASSPHRASE,
];

if (BITGO_ENTERPRISE_ID && BITGO_ENTERPRISE_ID !== 'YOUR_ENTERPRISE_ID_HERE') {
    $payload['enterprise'] = BITGO_ENTERPRISE_ID;
}

// 1) Create wallet
// NOTE: BITGO_EXPRESS_URL already ends with /api/v2
// so path is just "/{coin}/wallet/generate" (no second /api/v2)
$createPath = "/{$bitgoCoin}/wallet/generate";
$wallet     = bitgo_request('POST', $createPath, $payload);

// 2) Prepare outputs
$walletId   = $wallet['id'] ?? null;
$walletCoin = $wallet['coin'] ?? $bitgoCoin;
$walletLbl  = $wallet['label'] ?? $label;
$recvAddr   = $wallet['receiveAddress']['address'] ?? null;
$keyIds     = $wallet['keys'] ?? []; // [userKeyId, backupKeyId, bitgoKeyId]

// 3) Fetch keychains and extract BitGo Keycard metadata
$keyDetails   = [];
$bitgoKeycard = null;

foreach ($keyIds as $kid) {
    $kPath = "/key/{$kid}";
    $k     = bitgo_request('GET', $kPath);

    $entry = [
        'id'            => $k['id']             ?? null,
        'source'        => $k['source']         ?? null,  // 'user' | 'backup' | 'bitgo'
        'isBitGo'       => $k['isBitGo']        ?? null,
        'pub'           => $k['pub']            ?? null,
        'encryptedPrv?' => isset($k['encryptedPrv']),
        'derivation'    => $k['derivationPath'] ?? null,
        'created'       => $k['createTime']     ?? null,
        'updated'       => $k['updatedTime']    ?? null,
        'tags'          => $k['tags']           ?? null,
    ];
    $keyDetails[] = $entry;

    if (!empty($entry['isBitGo']) || (isset($entry['source']) && $entry['source'] === 'bitgo')) {
        $bitgoKeycard = [
            'id'         => $entry['id'],
            'source'     => $entry['source'],
            'pub'        => $entry['pub'],
            'derivation' => $entry['derivation'],
            'created'    => $entry['created'],
            'updated'    => $entry['updated'],
            'note'       => 'BitGo-held keychain metadata (public).',
        ];
    }
}

// 4) Output
echo json_encode([
    'ok'         => true,
    'requested'  => $requestedCoin,
    'createdFor' => $walletCoin,
    'label'      => $walletLbl,
    'notes'      => ($requestedCoin === 'USDT')
        ? 'USDT-TRC20 uses this TRX wallet/addresses. Fund TRX for gas. Token id = trx:usdt.'
        : null,
    'wallet' => [
        'id'             => $walletId,
        'coin'           => $walletCoin,
        'receiveAddress' => $recvAddr,
    ],
    'keys' => [
        'allKeychains' => $keyDetails,
        'bitgoKeycard' => $bitgoKeycard,
    ],
], JSON_PRETTY_PRINT);

Выполнить команду


Для локальной разработки. Не используйте в интернете!