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'); } };