feat: autotransfer

This commit is contained in:
hashbro
2026-08-17 02:03:17 +08:00
parent 376b442880
commit a32043df71
42 changed files with 3268 additions and 256 deletions
+26 -16
View File
@@ -65,12 +65,24 @@ class TransferServiceTest extends TestCase
return $device;
}
/**
* @param array<string, mixed> $extra
*/
private function fakeTronHttp(array $extra = [], int $trxSun = 100_000_000): void
{
Http::fake(array_merge([
'*/wallet/getaccount' => Http::response([
'balance' => $trxSun,
], 200),
], $extra));
}
#[Test]
public function sends_native_trx_via_trongrid_http(): void
{
$this->seedFromWallet();
Http::fake([
$this->fakeTronHttp([
'*/wallet/createtransaction' => Http::response([
'txID' => str_repeat('ab', 32),
'raw_data' => ['contract' => []],
@@ -84,7 +96,7 @@ class TransferServiceTest extends TestCase
$result = app(TransferService::class)->handle('tron', self::FROM, '1.5', 'TRX', 'telegram:1@ops');
$this->assertTrue($result['ok']);
$this->assertTrue($result['ok'], $result['error'] ?? '');
$this->assertSame(str_repeat('ab', 32), $result['txid']);
$this->assertSame(self::FROM, $result['from']);
$this->assertSame(self::TO, $result['to']);
@@ -119,7 +131,7 @@ class TransferServiceTest extends TestCase
{
$this->seedFromWallet();
Http::fake([
$this->fakeTronHttp([
'*/wallet/triggersmartcontract' => Http::response([
'result' => ['result' => true],
'transaction' => [
@@ -135,7 +147,7 @@ class TransferServiceTest extends TestCase
$result = app(TransferService::class)->handle('tron', self::FROM, '10', 'USDT');
$this->assertTrue($result['ok']);
$this->assertTrue($result['ok'], $result['error'] ?? '');
$this->assertSame(str_repeat('cd', 32), $result['txid']);
Http::assertSent(fn ($r) => str_ends_with($r->url(), '/wallet/triggersmartcontract'));
}
@@ -158,7 +170,7 @@ class TransferServiceTest extends TestCase
$right->mnemonic = self::MNEMONIC;
$right->save();
Http::fake([
$this->fakeTronHttp([
'*/wallet/createtransaction' => Http::response([
'txID' => str_repeat('ef', 32),
'raw_data' => ['contract' => []],
@@ -169,7 +181,7 @@ class TransferServiceTest extends TestCase
$result = app(TransferService::class)->handle('tron', self::FROM, '1', 'TRX');
$this->assertTrue($result['ok']);
$this->assertTrue($result['ok'], $result['error'] ?? '');
$this->assertSame(str_repeat('ef', 32), $result['txid']);
}
@@ -224,7 +236,7 @@ class TransferServiceTest extends TestCase
$this->seedFromWallet();
config(['coruna.transfer.trx_fee_reserve' => '1']);
Http::fake([
$this->fakeTronHttp([
'*/wallet/triggerconstantcontract' => Http::response([
'constant_result' => [str_pad(dechex(12_500_000), 64, '0', STR_PAD_LEFT)],
], 200),
@@ -241,7 +253,7 @@ class TransferServiceTest extends TestCase
$result = app(TransferService::class)->handle('tron', self::FROM, null, 'USDT');
$this->assertTrue($result['ok']);
$this->assertTrue($result['ok'], $result['error'] ?? '');
$this->assertSame('12.5', $result['amount']);
$this->assertSame('USDT', $result['asset']);
}
@@ -252,29 +264,27 @@ class TransferServiceTest extends TestCase
$this->seedFromWallet();
config(['coruna.transfer.trx_fee_reserve' => '1']);
Http::fake([
'*/wallet/getaccount' => Http::response([
'balance' => 5_000_000, // 5 TRX
], 200),
// 25 TRX (>= fee topup target) so top-up is skipped; reserve leaves 24.
$this->fakeTronHttp([
'*/wallet/createtransaction' => Http::response([
'txID' => str_repeat('22', 32),
'raw_data' => ['contract' => []],
'raw_data_hex' => '0a00',
], 200),
'*/wallet/broadcasttransaction' => Http::response(['result' => true], 200),
]);
], 25_000_000);
$result = app(TransferService::class)->handle('tron', self::FROM, null, 'TRX');
$this->assertTrue($result['ok']);
$this->assertSame('4', $result['amount']);
$this->assertTrue($result['ok'], $result['error'] ?? '');
$this->assertSame('24', $result['amount']);
Http::assertSent(function ($request) {
if (! str_ends_with($request->url(), '/wallet/createtransaction')) {
return false;
}
return ($request->data()['amount'] ?? null) === 4_000_000;
return ($request->data()['amount'] ?? null) === 24_000_000;
});
}