PHP WebShell

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

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

<?php
/**
 * Create (or fetch existing) user BTC wallet by making a BitGo secondary address.
 * - MAINNET
 * - Uses already-loaded $conn and BITGO_* constants from index.php
 * - Never echoes or exits; returns a result array with -> success, code, message, data
 *
 * Usage in index.php (after loading configs):
 *   $res = create_user_btc_wallet($user_id, $conn);
 *   if ($res['success']) { ... } else { ... }
 */

if (!function_exists('create_user_btc_wallet')) {
function create_user_btc_wallet($user_id, $conn) {
    // quick sanity checks
    if (!($conn instanceof mysqli)) {
        return ['success' => false, 'code' => 500, 'message' => 'Database connection not available.'];
    }
    if (!defined('BITGO_API_BASE_URL') || !defined('BITGO_ACCESS_TOKEN')) {
        return ['success' => false, 'code' => 500, 'message' => 'Wallet service configuration missing.'];
    }

    // business constants (MAINNET)
    $targetCoinDb     = 'BTC';
    $targetCoinSymbol = 'btc';
    $userWalletType   = 'secondary';
    $userWalletIcon   = 'btc.svg';
    $defaultBalance   = '0.00000';
    $walletStatus     = 'active';

    // tiny BitGo HTTP helper (local, no side effects)
    $bitgo_request = function($method, $path, $payload = null) {
        $url = rtrim(BITGO_API_BASE_URL, '/') . $path;
        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer ' . BITGO_ACCESS_TOKEN
        ];
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        if ($payload !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); // don’t hang your page
        $resp  = curl_exec($ch);
        $errno = curl_errno($ch);
        $err   = curl_error($ch);
        $code  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($errno) {
            if ($errno === 7) { // connection refused/unreachable
                return [false, 'Wallet service is currently unavailable. Please try again later.', 503, null];
            }
            return [false, 'Network error talking to wallet service: ' . $err, 502, null];
        }
        $json = json_decode($resp, true);
        if ($code < 200 || $code >= 300) {
            $msg = isset($json['error']) ? $json['error'] : ('HTTP ' . $code);
            return [false, 'Wallet service returned an error: ' . $msg, $code, $json];
        }
        return [true, null, $code, $json];
    };

    // validate user id
    $user_id = intval($user_id);
    if ($user_id <= 0) {
        return ['success' => false, 'code' => 400, 'message' => 'Invalid user id.'];
    }

    // 1) already has any BTC wallet?
    $sql  = "SELECT wallet_id, wallet_add, wallet_status
             FROM user_wallets
             WHERE user_id = ? AND coin = ?
             LIMIT 1";
    if (!$stmt = mysqli_prepare($conn, $sql)) {
        return ['success' => false, 'code' => 500, 'message' => 'Database error (user wallet check): ' . mysqli_error($conn)];
    }
    mysqli_stmt_bind_param($stmt, 'is', $user_id, $targetCoinDb);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    if (mysqli_stmt_num_rows($stmt) > 0) {
        mysqli_stmt_bind_result($stmt, $existingWalletId, $existingAddr, $existingStatus);
        mysqli_stmt_fetch($stmt);
        mysqli_stmt_close($stmt);
        return [
            'success' => true,
            'code'    => 200,
            'message' => 'BTC wallet already exists.',
            'data'    => [
                'wallet_id'     => $existingWalletId,
                'wallet_add'    => $existingAddr,
                'wallet_status' => $existingStatus,
                'coin'          => $targetCoinDb,
            ],
        ];
    }
    mysqli_stmt_close($stmt);

    // 2) find active central BTC wallet (cwallet); assumes wallet_add_id is BitGo walletId
    $sql  = "SELECT cwallet_id, wallet_add_id, wallet_add
             FROM cwallet
             WHERE coin = ? AND status = 'active'
             ORDER BY cwallet_id ASC
             LIMIT 1";
    if (!$stmt = mysqli_prepare($conn, $sql)) {
        return ['success' => false, 'code' => 500, 'message' => 'Database error (cwallet lookup): ' . mysqli_error($conn)];
    }
    mysqli_stmt_bind_param($stmt, 's', $targetCoinDb);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    if (mysqli_stmt_num_rows($stmt) === 0) {
        mysqli_stmt_close($stmt);
        return ['success' => false, 'code' => 404, 'message' => 'No active central BTC wallet configured.'];
    }
    mysqli_stmt_bind_result($stmt, $cwalletId, $bitgoWalletId, $centralAddr);
    mysqli_stmt_fetch($stmt);
    mysqli_stmt_close($stmt);

    if (empty($bitgoWalletId)) {
        return ['success' => false, 'code' => 500, 'message' => 'Central walletId missing in configuration.'];
    }

    // 3) create secondary address on BitGo (MAINNET)
    $label   = 'user_' . $user_id . '_' . time();
    $payload = [
        'label' => $label,
        // if policy requires passphrase, add in your config and uncomment:
        // 'walletPassphrase' => BITGO_WALLET_PASSPHRASE,
    ];
    list($ok, $errMsg, $http, $json) =
        $bitgo_request('POST', "/api/v2/{$targetCoinSymbol}/wallet/{$bitgoWalletId}/address", $payload);

    if (!$ok) {
        return ['success' => false, 'code' => $http ?: 502, 'message' => $errMsg];
    }
    if (empty($json['address'])) {
        return ['success' => false, 'code' => 502, 'message' => 'Wallet service responded without an address.'];
    }
    $newAddress   = $json['address'];
    $newAddressId = $json['id'] ?? null;

    // 4) insert user wallet
    $sql  = "INSERT INTO user_wallets
             (cwallet_id, user_id, wallet_add, coin, icon, balance, type, wallet_status)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
    if (!$stmt = mysqli_prepare($conn, $sql)) {
        return ['success' => false, 'code' => 500, 'message' => 'Database error (insert user wallet): ' . mysqli_error($conn)];
    }
    mysqli_stmt_bind_param(
        $stmt,
        'iissssss',
        $cwalletId,
        $user_id,
        $newAddress,
        $targetCoinDb,
        $userWalletIcon,
        $defaultBalance,
        $userWalletType,
        $walletStatus
    );
    if (!mysqli_stmt_execute($stmt)) {
        $msg = mysqli_stmt_error($stmt);
        mysqli_stmt_close($stmt);
        return ['success' => false, 'code' => 500, 'message' => 'Database error (insert failed): ' . $msg];
    }
    $newUserWalletId = mysqli_insert_id($conn);
    mysqli_stmt_close($stmt);

    return [
        'success' => true,
        'code'    => 201,
        'message' => 'BTC wallet created successfully.',
        'data'    => [
            'wallet_id'       => $newUserWalletId,
            'user_id'         => $user_id,
            'wallet_add'      => $newAddress,
            'coin'            => $targetCoinDb,
            'type'            => $userWalletType,
            'wallet_status'   => $walletStatus,
            'bitgo_address_id'=> $newAddressId,
            'cwallet_id'      => $cwalletId,
            'bitgo_wallet_id' => $bitgoWalletId,
            'label'           => $label,
        ],
    ];
}}

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


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