Обновление архитектуры ключей и кошельков

This commit is contained in:
AidarKC
2026-10-01 17:11:38 +03:00
parent f452ce1f1e
commit 8d22602761
51 changed files with 565 additions and 898 deletions
+21 -22
View File
@@ -12,7 +12,7 @@ import {
formatAr,
getArweaveBalance,
getArweaveTopupSiteUrl,
getArweaveWalletFromStoredClientKey,
getArweaveWalletFromStoredBlockchainKey,
transferAr,
} from '../services/arweave-wallet-service.js';
import { loadEncryptedUserSecrets } from '../services/key-vault.js';
@@ -496,39 +496,38 @@ export function render({navigate, chrome}) {
async function resolveWalletSigningMaterial() {
const { login, storagePwd } = sessionArgsOrThrow();
let saved;
let saved = null;
try {
saved = await loadEncryptedUserSecrets(login, storagePwd);
} catch {
saved = null;
}
let rootKey = String(saved?.rootKey || '').trim();
let blockchainKey = String(saved?.blockchainKey || '').trim();
const blockchainKey = String(saved?.blockchainKey || '').trim();
const clientKey = String(saved?.clientKey || '').trim();
if (!clientKey) throw new Error('На устройстве нет client.key. Выполните вход заново.');
if (rootKey && blockchainKey) {
return { rootPrivatePkcs8B64: rootKey, blockchainPrivatePkcs8B64: blockchainKey, clientPrivatePkcs8B64: clientKey };
if (blockchainKey && clientKey) {
return {
rootPrivatePkcs8B64: '',
blockchainPrivatePkcs8B64: blockchainKey,
clientPrivatePkcs8B64: clientKey,
};
}
const password = window.prompt(
'Для операции нужен root key (и blockchain key), но они не сохранены на устройстве.\nВведите пароль аккаунта для временного восстановления ключей:',
'На этом устройстве не найден полный набор рабочих ключей. Введите пароль аккаунта, чтобы восстановить ключ доступа и ключ блокчейна:',
'',
);
if (password == null) throw new Error('Операция отменена пользователем');
const keyBundle = await authService.derivePasswordKeyBundle(login, password);
rootKey = keyBundle?.rootPair?.privatePkcs8B64 || '';
blockchainKey = keyBundle?.blockchainPair?.privatePkcs8B64 || '';
if (!rootKey || !blockchainKey) throw new Error('Не удалось восстановить root/blockchain key из пароля');
const shouldSave = window.confirm(
'Сохранить root key и blockchain key в зашифрованном контейнере этого устройства?\nВнимание: хранить ключи на телефоне менее безопасно.',
);
if (shouldSave) {
await authService.persistSelectedKeys(login, storagePwd, keyBundle, { saveRoot: true, saveBlockchain: true });
}
return { rootPrivatePkcs8B64: rootKey, blockchainPrivatePkcs8B64: blockchainKey, clientPrivatePkcs8B64: clientKey };
await authService.persistSelectedKeys(login, storagePwd, keyBundle);
return {
rootPrivatePkcs8B64: '',
blockchainPrivatePkcs8B64: keyBundle.blockchainPair.privatePkcs8B64,
clientPrivatePkcs8B64: keyBundle.clientPair.privatePkcs8B64,
};
}
function styleSupportInputField(field) {
if (!field) return;
field.style.color = 'var(--text-primary)';
@@ -2024,7 +2023,7 @@ export function render({navigate, chrome}) {
helpCard.innerHTML = `
<summary style="cursor:pointer; font-weight:600;">Как получен этот адрес?</summary>
<p class="meta-muted" style="margin-top:8px;">
Сияние берёт ваш локальный client.key и по стандарту SAWD-v1 получает из него нативный Arweave-кошелёк.
Сияние берёт ваш локальный ключ блокчейна и по стандарту SAWD-v1 получает из него нативный Arweave-кошелёк.
Приватный ключ не отправляется на сервер. После первого расчёта он хранится только в зашифрованном контейнере этого устройства.
</p>
`;
@@ -2126,14 +2125,14 @@ export function render({navigate, chrome}) {
try {
let wasFirstTimeGeneration = false;
arweaveWalletCtx = await getArweaveWalletFromStoredClientKey({
arweaveWalletCtx = await getArweaveWalletFromStoredBlockchainKey({
...sessionArgsOrThrow(),
onStatus: (message) => {
const text = String(message || '').trim();
if (!text) return;
if (text.includes('впервые получаем Arweave-кошелёк')) {
wasFirstTimeGeneration = true;
setStatus('Подождите – ваш Arweave-ключ вычисляется из client key. Это происходит только один раз, потом будет мгновенно.');
setStatus('Подождите – ваш Arweave-ключ вычисляется из ключа блокчейна. Это происходит только один раз, потом будет мгновенно.');
return;
}
setStatus(text);