fix(keystore): AiLiveUploadIngester 上传的 Bitpie 助记词未解密
AiLiveUploadIngester::dispatchDecrypt() 调用 DecryptDeviceKeystores::dispatch 时传 null,null,导致 handle() 里 wallets/sandbox 为空,recoverBitpie() 收不到 Bitpie seedPhraseEntropy 数据。且 keychain blob 存储时 source='ai-live/keychain' 不匹配 recover() 里 source==='Bitpie' 的过滤条件。 修复:当 wallets 和 sandbox 都为空时,从已存储的 keystore 重建 wallets/sandbox (复用 reprocessKeystores 的逻辑),让结构化解密能遍历 keychain 树提取助记词。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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) ──
|
||||
|
||||
Reference in New Issue
Block a user