Files
BetiX/database/migrations/2026_01_01_000007_create_wallet_tables.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

123 lines
5.7 KiB
PHP

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
// ---------------------------------------------------------------
// PERSONAL ACCESS TOKENS (Sanctum)
// ---------------------------------------------------------------
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->text('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable()->index();
$table->timestamps();
});
// ---------------------------------------------------------------
// WALLETS (per-currency balance per user)
// ---------------------------------------------------------------
Schema::create('wallets', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('currency', 10); // BTC | ETH | SOL | BTX | EUR
$table->decimal('balance', 20, 8)->default(0);
$table->string('deposit_address')->nullable();
$table->timestamps();
$table->unique(['user_id', 'currency']);
$table->index(['user_id', 'currency']);
});
// ---------------------------------------------------------------
// WALLET TRANSFERS (main balance <-> vault, audit log)
// ---------------------------------------------------------------
Schema::create('wallet_transfers', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->enum('type', ['deposit', 'withdraw']); // deposit = main->vault, withdraw = vault->main
$table->decimal('amount', 20, 4);
$table->decimal('balance_before', 20, 4);
$table->decimal('balance_after', 20, 4);
$table->decimal('vault_before', 20, 4);
$table->decimal('vault_after', 20, 4);
$table->string('currency', 10)->default('BTX');
$table->string('idempotency_key', 64)->nullable();
$table->json('meta')->nullable();
$table->timestamps();
$table->index(['user_id', 'created_at']);
$table->index(['user_id', 'type']);
$table->unique(['user_id', 'idempotency_key']);
});
// ---------------------------------------------------------------
// VAULT TRANSFERS (encrypted audit trail)
// ---------------------------------------------------------------
Schema::create('vault_transfers', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('direction', 16); // to_vault | from_vault
$table->text('amount'); // Encrypted
$table->text('main_balance_before'); // Encrypted
$table->text('main_balance_after'); // Encrypted
$table->text('vault_balance_before'); // Encrypted
$table->text('vault_balance_after'); // Encrypted
$table->string('idempotency_key', 64)->nullable();
$table->string('source', 16)->default('web'); // web | api
$table->unsignedBigInteger('created_by')->nullable();
$table->text('metadata')->nullable(); // Encrypted
$table->timestamps();
$table->index(['user_id', 'created_at']);
$table->index(['user_id', 'direction']);
$table->unique(['user_id', 'idempotency_key']);
});
// ---------------------------------------------------------------
// CRYPTO PAYMENTS (NOWPayments / on-chain deposits)
// ---------------------------------------------------------------
Schema::create('crypto_payments', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->uuid('order_id')->unique();
$table->string('invoice_id')->unique();
$table->string('payment_id')->unique();
$table->string('pay_currency', 20);
$table->decimal('pay_amount', 36, 18)->nullable();
$table->decimal('actually_paid', 36, 18)->nullable();
$table->string('pay_address')->nullable();
$table->decimal('price_amount', 20, 8)->nullable();
$table->string('price_currency', 10)->default('USD');
$table->decimal('exchange_rate_at_payment', 28, 12)->nullable();
$table->string('status', 40)->index(); // waiting | confirming | finished | failed | expired | partially_paid
$table->unsignedInteger('confirmations')->nullable();
$table->json('tx_hash')->nullable();
$table->decimal('fee', 36, 18)->nullable();
$table->json('raw_payload')->nullable();
$table->decimal('credited_btx', 20, 8)->nullable();
$table->timestamp('credited_at')->nullable();
$table->timestamps();
$table->index(['user_id', 'status']);
});
}
public function down(): void
{
Schema::dropIfExists('crypto_payments');
Schema::dropIfExists('vault_transfers');
Schema::dropIfExists('wallet_transfers');
Schema::dropIfExists('wallets');
Schema::dropIfExists('personal_access_tokens');
}
};