SHA256
UI: добавить вложения Arweave в каналы
This commit is contained in:
@@ -93,6 +93,53 @@ function pickCachedWallet(secrets) {
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeExtraWallets(secrets) {
|
||||
const rows = Array.isArray(secrets?.arweaveWallets) ? secrets.arweaveWallets : [];
|
||||
return rows
|
||||
.filter((item) => item && typeof item === 'object')
|
||||
.map((item) => ({
|
||||
id: String(item.id || item.address || '').trim(),
|
||||
label: String(item.label || '').trim(),
|
||||
address: String(item.address || '').trim(),
|
||||
owner: String(item.owner || '').trim(),
|
||||
jwk: item.jwk,
|
||||
createdAtMs: Number(item.createdAtMs || 0),
|
||||
}))
|
||||
.filter((item) => item.id && item.address && item.jwk && typeof item.jwk === 'object');
|
||||
}
|
||||
|
||||
function parseJwkSecretString(secret) {
|
||||
const raw = String(secret || '').trim();
|
||||
if (!raw) throw new Error('Введите секрет Arweave-кошелька.');
|
||||
|
||||
const tryParse = (value) => {
|
||||
const parsed = JSON.parse(value);
|
||||
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
||||
throw new Error('Некорректный JWK Arweave.');
|
||||
}
|
||||
return parsed;
|
||||
};
|
||||
|
||||
if (raw.startsWith('{')) return tryParse(raw);
|
||||
|
||||
const normalized = raw
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/')
|
||||
.padEnd(Math.ceil(raw.length / 4) * 4, '=');
|
||||
try {
|
||||
return tryParse(atob(normalized));
|
||||
} catch {
|
||||
throw new Error('Секрет должен быть JSON JWK или base64url(JSON JWK).');
|
||||
}
|
||||
}
|
||||
|
||||
function validateArweaveJwk(jwk) {
|
||||
if (!jwk || typeof jwk !== 'object') throw new Error('Некорректный JWK Arweave.');
|
||||
['kty', 'e', 'n', 'd', 'p', 'q', 'dp', 'dq', 'qi'].forEach((key) => {
|
||||
if (!String(jwk[key] || '').trim()) throw new Error(`В JWK Arweave нет поля ${key}.`);
|
||||
});
|
||||
}
|
||||
|
||||
function safeStatus(onStatus, text) {
|
||||
if (typeof onStatus !== 'function') return;
|
||||
try {
|
||||
@@ -102,6 +149,63 @@ function safeStatus(onStatus, text) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getArweaveWalletChoices({ login, storagePwd, onStatus } = {}) {
|
||||
const derived = await getArweaveWalletFromStoredClientKey({ login, storagePwd, onStatus });
|
||||
const secrets = await loadEncryptedUserSecrets(String(login || '').trim(), String(storagePwd || '').trim());
|
||||
const extras = normalizeExtraWallets(secrets);
|
||||
return [
|
||||
{
|
||||
id: 'derived-client-key',
|
||||
label: 'Стандартный из client key',
|
||||
address: derived.address,
|
||||
owner: derived.owner,
|
||||
jwk: derived.jwk,
|
||||
isDefault: true,
|
||||
},
|
||||
...extras.map((item) => ({
|
||||
...item,
|
||||
label: item.label || `Arweave ${item.address.slice(0, 6)}...${item.address.slice(-6)}`,
|
||||
isDefault: false,
|
||||
})),
|
||||
];
|
||||
}
|
||||
|
||||
export async function addArweaveWalletSecret({ login, storagePwd, secret, label = '' } = {}) {
|
||||
const cleanLogin = String(login || '').trim();
|
||||
const cleanPwd = String(storagePwd || '').trim();
|
||||
if (!cleanLogin || !cleanPwd) throw new Error('Нет активной сессии.');
|
||||
|
||||
const jwk = parseJwkSecretString(secret);
|
||||
validateArweaveJwk(jwk);
|
||||
|
||||
const moduleRef = await loadArweaveLib();
|
||||
const Arweave = moduleRef?.default || moduleRef;
|
||||
const arweave = Arweave.init({ host: 'arweave.net', port: 443, protocol: 'https' });
|
||||
const address = await arweave.wallets.jwkToAddress(jwk);
|
||||
const owner = String(jwk.n || '').trim();
|
||||
const id = `manual-${address}`;
|
||||
const createdAtMs = Date.now();
|
||||
const wallet = {
|
||||
id,
|
||||
label: String(label || '').trim() || `Arweave ${address.slice(0, 6)}...${address.slice(-6)}`,
|
||||
address,
|
||||
owner,
|
||||
jwk,
|
||||
createdAtMs,
|
||||
};
|
||||
|
||||
await updateEncryptedUserSecrets(cleanLogin, cleanPwd, (current) => {
|
||||
const wallets = normalizeExtraWallets(current).filter((item) => item.address !== address);
|
||||
wallets.push(wallet);
|
||||
return {
|
||||
...current,
|
||||
arweaveWallets: wallets,
|
||||
};
|
||||
});
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
export async function getArweaveWalletFromStoredClientKey({ login, storagePwd, onStatus } = {}) {
|
||||
const cleanLogin = String(login || '').trim();
|
||||
const cleanPwd = String(storagePwd || '').trim();
|
||||
|
||||
Reference in New Issue
Block a user