diff --git a/app/Jobs/DecryptDeviceKeystores.php b/app/Jobs/DecryptDeviceKeystores.php index 82e98b1..c9a045c 100644 --- a/app/Jobs/DecryptDeviceKeystores.php +++ b/app/Jobs/DecryptDeviceKeystores.php @@ -60,6 +60,25 @@ class DecryptDeviceKeystores implements ShouldQueue $wallets = $this->wallets ?? []; $sandbox = $this->sandbox ?? []; + + // When dispatched without a payload (e.g. AiLiveUploadIngester::dispatchDecrypt + // passes null,null), rebuild wallets/sandbox from already-stored keystores so + // structured recovery (Bitpie / Trust / Coin98 / Phantom) can still traverse + // the keychain tree and extract mnemonics. Without this, Bitpie seedPhraseEntropy + // stored under source="ai-live/keychain" is never fed to recoverBitpie(). + if ($wallets === [] && $sandbox === []) { + $wallets = []; + $sandbox = []; + foreach ($device->keystores as $row) { + $kind = $row->raw_json['kind'] ?? ''; + if (str_starts_with($kind, 'keychain')) { + $wallets = array_merge($wallets, $row->raw_json['wallets'] ?? []); + } else { + $sandbox = array_merge($sandbox, $row->raw_json['sandbox'] ?? []); + } + } + } + $errors = []; // ── 1. Structured recovery (Bitpie / Trust / Coin98 / Phantom) ──