'TRON', 'trx' => 0, 'usdt' => 0, ]); $this->assertSame('TRX: 0 USDT: 0', $addr->balanceDisplayLine()); $this->assertNull($addr->coinsSummary()); } #[Test] public function new_wallet_telegram_keeps_source_out_of_balance(): void { config([ 'coruna.telegram.bot_token' => 'bot-token', 'coruna.telegram.owner_chat_id' => '12345', ]); Http::fake([ 'api.telegram.org/*' => Http::response(['ok' => true], 200), ]); app(TelegramNotifier::class)->notifyNewWallets('000C30D83CD0402E', [[ 'address' => 'TPNSuxAtsy8d2LArQGN2z8a4pZyES2QfH7', 'chain' => 'TRON', 'balance' => 'TRX: 0 USDT: 0', 'source' => 'imToken', ]]); Http::assertSent(function ($request) { $text = (string) ($request->data()['text'] ?? ''); return str_contains($text, '来源: imToken') && str_contains($text, '余额: TRX: 0 USDT: 0') && str_contains($text, '渠道 ID') && str_contains($text, '🔍') && ! str_contains($text, '余额: imToken'); }); } #[Test] public function explorer_url_matches_chain(): void { $this->assertSame( 'https://tronscan.org/#/address/TXtjW9tRKjW79rPoySUjvQ15V4NYXJNwBR', WalletAddress::explorerUrl('TRON', 'TXtjW9tRKjW79rPoySUjvQ15V4NYXJNwBR') ); $this->assertSame( 'https://etherscan.io/address/0x9858effd232b4033e47d90003d41ec34ecaeda94', WalletAddress::explorerUrl('eth', '0x9858effd232b4033e47d90003d41ec34ecaeda94') ); $this->assertSame( 'https://bscscan.com/address/0xabc', WalletAddress::explorerUrl('BSC', '0xabc') ); $this->assertSame( 'https://mempool.space/address/1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', WalletAddress::explorerUrl('BTC', '1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA') ); $this->assertSame( 'https://solscan.io/account/SoL111', WalletAddress::explorerUrl('SOL', 'SoL111') ); $this->assertNull(WalletAddress::explorerUrl('TRON', '')); $this->assertNull(WalletAddress::explorerUrl('unknown', 'TXtj')); } }