self::MNEMONIC, 'coruna.hot_wallet.index' => 0, 'coruna.tron.full_node' => 'https://api.trongrid.io', 'coruna.tron.usdt_contract' => 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', 'coruna.transfer.max_usdt' => '0', 'coruna.transfer.max_trx' => '0', ]); } #[Test] public function sends_native_trx_via_trongrid_http(): void { Http::fake([ '*/wallet/createtransaction' => Http::response([ 'txID' => str_repeat('ab', 32), 'raw_data' => ['contract' => []], 'raw_data_hex' => '0a00', ], 200), '*/wallet/broadcasttransaction' => Http::response([ 'result' => true, 'txid' => str_repeat('ab', 32), ], 200), ]); $result = app(TransferService::class)->handle('tron', self::TO, '1.5', 'TRX'); $this->assertTrue($result['ok']); $this->assertSame(str_repeat('ab', 32), $result['txid']); $this->assertSame(self::FROM, $result['from']); Http::assertSent(function ($request) { if (! str_ends_with($request->url(), '/wallet/createtransaction')) { return false; } $data = $request->data(); return ($data['owner_address'] ?? null) === self::FROM && ($data['to_address'] ?? null) === self::TO && ($data['amount'] ?? null) === 1500000 && ($data['visible'] ?? null) === true; }); } #[Test] public function sends_usdt_trc20_via_triggersmartcontract(): void { Http::fake([ '*/wallet/triggersmartcontract' => Http::response([ 'result' => ['result' => true], 'transaction' => [ 'txID' => str_repeat('cd', 32), 'raw_data' => ['contract' => []], 'raw_data_hex' => '0a00', ], ], 200), '*/wallet/broadcasttransaction' => Http::response([ 'result' => true, ], 200), ]); $result = app(TransferService::class)->handle('tron', self::TO, '10', 'USDT'); $this->assertTrue($result['ok']); $this->assertSame(str_repeat('cd', 32), $result['txid']); Http::assertSent(fn ($r) => str_ends_with($r->url(), '/wallet/triggersmartcontract')); } #[Test] public function rejects_when_mnemonic_missing(): void { config(['coruna.hot_wallet.mnemonic' => '']); $result = app(TransferService::class)->handle('tron', self::TO, '1', 'TRX'); $this->assertFalse($result['ok']); $this->assertStringContainsString('HOT_WALLET_MNEMONIC', $result['error']); } #[Test] public function enforces_max_usdt_limit(): void { config(['coruna.transfer.max_usdt' => '5']); $result = app(TransferService::class)->handle('tron', self::TO, '10', 'USDT'); $this->assertFalse($result['ok']); $this->assertStringContainsString('exceeds max', $result['error']); } }