UserWallet: runCollectLoop options object, root null check, pairing/collect/bip32
**Motivations:**
- Passer runCollectLoop en objet d’options pour lisibilité et évolution
- Éviter non-null assertion sur root dans main.tsx
- Ajustements pairing, collect signatures, bip32
**Root causes:**
- N/A (évolutions + correctifs ciblés)
**Correctifs:**
- main.tsx: vérification root !== null avant createRoot, throw explicite si absent
**Evolutions:**
- LoginScreen: runCollectLoop({ relayEndpoints, hash, ourSigs, path, pairToMembers, pubkeyToPair, opts })
- pairingConfirm.ts, PairingDisplayScreen, PairingSetupBlock: modifications
- collectSignatures.ts, bip32.ts: ajustements
- SyncScreen: modifications mineures
**Pages affectées:**
- userwallet: LoginScreen, main.tsx, PairingDisplayScreen, PairingSetupBlock, SyncScreen, pairingConfirm.ts, bip32.ts, collectSignatures.ts
- data: sync-utxos.log
This commit is contained in:
parent
cb13ab6fbf
commit
9291eab9d5
@ -1,45 +1,3 @@
|
||||
⏳ Traitement: 200000/225826 UTXOs insérés...
|
||||
⏳ Traitement: 210000/225826 UTXOs insérés...
|
||||
⏳ Traitement: 220000/225826 UTXOs insérés...
|
||||
💾 Mise à jour des UTXOs dépensés...
|
||||
|
||||
📊 Résumé:
|
||||
- UTXOs vérifiés: 61609
|
||||
- UTXOs toujours disponibles: 61609
|
||||
- UTXOs dépensés détectés: 0
|
||||
|
||||
📈 Statistiques finales:
|
||||
- Total UTXOs: 68398
|
||||
- Dépensés: 6789
|
||||
- Non dépensés: 61609
|
||||
|
||||
✅ Synchronisation terminée
|
||||
🔍 Démarrage de la synchronisation des UTXOs dépensés...
|
||||
|
||||
📊 UTXOs à vérifier: 61609
|
||||
📡 Récupération des UTXOs depuis Bitcoin...
|
||||
📊 UTXOs disponibles dans Bitcoin: 225837
|
||||
💾 Création de la table temporaire...
|
||||
💾 Insertion des UTXOs disponibles par batch...
|
||||
⏳ Traitement: 10000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 20000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 30000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 40000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 50000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 60000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 70000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 80000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 90000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 100000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 110000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 120000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 130000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 140000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 150000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 160000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 170000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 180000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 190000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 200000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 210000/225837 UTXOs insérés...
|
||||
⏳ Traitement: 220000/225837 UTXOs insérés...
|
||||
@ -98,3 +56,45 @@
|
||||
- Non dépensés: 61609
|
||||
|
||||
✅ Synchronisation terminée
|
||||
🔍 Démarrage de la synchronisation des UTXOs dépensés...
|
||||
|
||||
📊 UTXOs à vérifier: 61598
|
||||
📡 Récupération des UTXOs depuis Bitcoin...
|
||||
📊 UTXOs disponibles dans Bitcoin: 225867
|
||||
💾 Création de la table temporaire...
|
||||
💾 Insertion des UTXOs disponibles par batch...
|
||||
⏳ Traitement: 10000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 20000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 30000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 40000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 50000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 60000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 70000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 80000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 90000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 100000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 110000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 120000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 130000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 140000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 150000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 160000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 170000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 180000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 190000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 200000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 210000/225867 UTXOs insérés...
|
||||
⏳ Traitement: 220000/225867 UTXOs insérés...
|
||||
💾 Mise à jour des UTXOs dépensés...
|
||||
|
||||
📊 Résumé:
|
||||
- UTXOs vérifiés: 61598
|
||||
- UTXOs toujours disponibles: 61598
|
||||
- UTXOs dépensés détectés: 0
|
||||
|
||||
📈 Statistiques finales:
|
||||
- Total UTXOs: 68398
|
||||
- Dépensés: 6800
|
||||
- Non dépensés: 61598
|
||||
|
||||
✅ Synchronisation terminée
|
||||
|
||||
@ -272,14 +272,14 @@ export function LoginScreen(): JSX.Element {
|
||||
);
|
||||
const endpoints = relays.map((r) => r.endpoint);
|
||||
// Boucle de collecte : fetch signatures par hash jusqu'à satisfaction ou timeout
|
||||
merged = await runCollectLoop(
|
||||
endpoints,
|
||||
proof.challenge.hash,
|
||||
proof.signatures,
|
||||
loginPath,
|
||||
merged = await runCollectLoop({
|
||||
relayEndpoints: endpoints,
|
||||
hash: proof.challenge.hash,
|
||||
ourSigs: proof.signatures,
|
||||
path: loginPath,
|
||||
pairToMembers,
|
||||
pubkeyToPair,
|
||||
{
|
||||
opts: {
|
||||
pollMs: COLLECT_POLL_MS,
|
||||
timeoutMs: COLLECT_TIMEOUT_MS,
|
||||
onProgress: (m) => {
|
||||
@ -290,7 +290,7 @@ export function LoginScreen(): JSX.Element {
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
} finally {
|
||||
setIsCollecting(false);
|
||||
setCollectProgressState(null);
|
||||
@ -884,14 +884,14 @@ export function LoginScreen(): JSX.Element {
|
||||
identity?.publicKey ?? '',
|
||||
loginPath.pairs_attendus,
|
||||
);
|
||||
const merged = await runCollectLoop(
|
||||
endpoints,
|
||||
proof.challenge.hash,
|
||||
proof.signatures,
|
||||
loginPath,
|
||||
const merged = await runCollectLoop({
|
||||
relayEndpoints: endpoints,
|
||||
hash: proof.challenge.hash,
|
||||
ourSigs: proof.signatures,
|
||||
path: loginPath,
|
||||
pairToMembers,
|
||||
pubkeyToPair,
|
||||
{
|
||||
opts: {
|
||||
pollMs: COLLECT_POLL_MS,
|
||||
timeoutMs: COLLECT_TIMEOUT_MS,
|
||||
onProgress: (m) => {
|
||||
@ -902,7 +902,7 @@ export function LoginScreen(): JSX.Element {
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
setCollectedMerged(merged);
|
||||
} finally {
|
||||
setIsCollecting(false);
|
||||
|
||||
@ -89,15 +89,15 @@ export function PairingDisplayScreen(): JSX.Element {
|
||||
}
|
||||
setIsConfirming(true);
|
||||
try {
|
||||
const ok = await runDevice2Confirmation(
|
||||
local.uuid,
|
||||
remote.uuid,
|
||||
const ok = await runDevice2Confirmation({
|
||||
pairLocal: local.uuid,
|
||||
pairRemote: remote.uuid,
|
||||
identity,
|
||||
relays,
|
||||
identity.t0_anniversaire,
|
||||
Date.now(),
|
||||
pubkeyHex,
|
||||
);
|
||||
start: identity.t0_anniversaire,
|
||||
end: Date.now(),
|
||||
remotePublicKey: pubkeyHex,
|
||||
});
|
||||
setJustConnected(ok);
|
||||
} catch (err) {
|
||||
console.error('Pairing confirmation (device 2):', err);
|
||||
|
||||
@ -94,13 +94,13 @@ export function PairingSetupBlock(): JSX.Element {
|
||||
}
|
||||
setIsConfirming(true);
|
||||
try {
|
||||
await runDevice1Confirmation(
|
||||
local.uuid,
|
||||
remote.uuid,
|
||||
await runDevice1Confirmation({
|
||||
pairLocal: local.uuid,
|
||||
pairRemote: remote.uuid,
|
||||
identity,
|
||||
relays,
|
||||
pubkeyHex,
|
||||
);
|
||||
remotePublicKey: pubkeyHex,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Pairing confirmation (device 1):', err);
|
||||
setRemoteError(
|
||||
|
||||
@ -57,15 +57,15 @@ export function SyncScreen(): JSX.Element {
|
||||
remote !== undefined &&
|
||||
identity.privateKey !== undefined
|
||||
) {
|
||||
void checkPairingConfirmationFromSync(
|
||||
void checkPairingConfirmationFromSync({
|
||||
relays,
|
||||
local.uuid,
|
||||
remote.uuid,
|
||||
pairLocal: local.uuid,
|
||||
pairRemote: remote.uuid,
|
||||
identity,
|
||||
start,
|
||||
end,
|
||||
remote.publicKey,
|
||||
).catch((err: unknown) => {
|
||||
remotePublicKey: remote.publicKey,
|
||||
}).catch((err: unknown) => {
|
||||
console.error('Pairing confirmation check during sync:', err);
|
||||
});
|
||||
}
|
||||
|
||||
@ -3,7 +3,11 @@ import ReactDOM from 'react-dom/client';
|
||||
import { App } from './App';
|
||||
import './index.css';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
const rootElement = document.getElementById('root');
|
||||
if (rootElement === null) {
|
||||
throw new Error('Root element not found');
|
||||
}
|
||||
ReactDOM.createRoot(rootElement).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
|
||||
@ -171,17 +171,22 @@ function buildMsgCle(
|
||||
};
|
||||
}
|
||||
|
||||
interface PublishPairingMessageParams {
|
||||
relays: RelayConfig[];
|
||||
message: MembreFinaliserMessage;
|
||||
hash: string;
|
||||
recipientPublicKey: string;
|
||||
senderIdentity: LocalIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a pairing message (MsgChiffre) to relays.
|
||||
* DH obligatoire: encrypt with ECDH and POST MsgCle. recipientPublicKey and senderIdentity required.
|
||||
*/
|
||||
async function publishPairingMessage(
|
||||
relays: RelayConfig[],
|
||||
message: MembreFinaliserMessage,
|
||||
hash: string,
|
||||
recipientPublicKey: string,
|
||||
senderIdentity: LocalIdentity,
|
||||
params: PublishPairingMessageParams,
|
||||
): Promise<void> {
|
||||
const { relays, message, hash, recipientPublicKey, senderIdentity } = params;
|
||||
if (recipientPublicKey === undefined || recipientPublicKey === '') {
|
||||
throw new Error(
|
||||
'Pairing DH obligatoire : clé publique du pair distant requise (exiger publicKey).',
|
||||
@ -212,25 +217,31 @@ async function publishPairingMessage(
|
||||
}
|
||||
}
|
||||
|
||||
interface PublishPairingMessageAndSignatureParams {
|
||||
relays: RelayConfig[];
|
||||
message: MembreFinaliserMessage;
|
||||
hash: string;
|
||||
sig: Signature;
|
||||
recipientPublicKey: string;
|
||||
senderIdentity: LocalIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish message and first signature to relays.
|
||||
* DH obligatoire: recipientPublicKey and senderIdentity required.
|
||||
*/
|
||||
export async function publishPairingMessageAndSignature(
|
||||
relays: RelayConfig[],
|
||||
message: MembreFinaliserMessage,
|
||||
hash: string,
|
||||
sig: Signature,
|
||||
recipientPublicKey: string,
|
||||
senderIdentity: LocalIdentity,
|
||||
params: PublishPairingMessageAndSignatureParams,
|
||||
): Promise<void> {
|
||||
await publishPairingMessage(
|
||||
const { relays, message, hash, sig, recipientPublicKey, senderIdentity } =
|
||||
params;
|
||||
await publishPairingMessage({
|
||||
relays,
|
||||
message,
|
||||
hash,
|
||||
recipientPublicKey,
|
||||
senderIdentity,
|
||||
);
|
||||
});
|
||||
const enabled = relays.filter((r) => r.enabled);
|
||||
const msgSig: MsgSignature = { signature: sig };
|
||||
for (const r of enabled) {
|
||||
@ -255,19 +266,32 @@ export async function publishPairingSignature(
|
||||
}
|
||||
}
|
||||
|
||||
interface FetchPairingMessageParams {
|
||||
relays: RelayConfig[];
|
||||
pairLocal: string;
|
||||
pairRemote: string;
|
||||
start: number;
|
||||
end: number;
|
||||
senderPublicKey?: string;
|
||||
ourIdentity?: LocalIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch messages in time window, find "membre finaliser" v1 for our pairs.
|
||||
* DH only: ECDH decryption when senderPublicKey and ourIdentity provided. No base64.
|
||||
*/
|
||||
export async function fetchPairingMessage(
|
||||
relays: RelayConfig[],
|
||||
pairLocal: string,
|
||||
pairRemote: string,
|
||||
start: number,
|
||||
end: number,
|
||||
senderPublicKey?: string,
|
||||
ourIdentity?: LocalIdentity,
|
||||
params: FetchPairingMessageParams,
|
||||
): Promise<{ message: MembreFinaliserMessage; hash: string } | null> {
|
||||
const {
|
||||
relays,
|
||||
pairLocal,
|
||||
pairRemote,
|
||||
start,
|
||||
end,
|
||||
senderPublicKey,
|
||||
ourIdentity,
|
||||
} = params;
|
||||
const enabled = relays.filter((r) => r.enabled);
|
||||
const key = sortedPairKey(pairLocal, pairRemote);
|
||||
const useEcdh =
|
||||
@ -401,13 +425,13 @@ async function buildAndPublishPairingVersion2(
|
||||
};
|
||||
const canonical = JSON.stringify(m2);
|
||||
const hash2 = await hashStringAsync(canonical, 'sha256');
|
||||
await publishPairingMessage(
|
||||
await publishPairingMessage({
|
||||
relays,
|
||||
m2,
|
||||
hash2,
|
||||
message: m2,
|
||||
hash: hash2,
|
||||
recipientPublicKey,
|
||||
senderIdentity,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -456,17 +480,22 @@ function delay(ms: number): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
interface RunDevice1ConfirmationParams {
|
||||
pairLocal: string;
|
||||
pairRemote: string;
|
||||
identity: LocalIdentity;
|
||||
relays: RelayConfig[];
|
||||
remotePublicKey: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run confirmation flow for device 1: create M, sign, publish, poll for remote sig, store.
|
||||
* remotePublicKey: identity public key of device 2, for ECDH encryption. Required (DH obligatoire).
|
||||
*/
|
||||
export async function runDevice1Confirmation(
|
||||
pairLocal: string,
|
||||
pairRemote: string,
|
||||
identity: LocalIdentity,
|
||||
relays: RelayConfig[],
|
||||
remotePublicKey: string,
|
||||
params: RunDevice1ConfirmationParams,
|
||||
): Promise<boolean> {
|
||||
const { pairLocal, pairRemote, identity, relays, remotePublicKey } = params;
|
||||
if (remotePublicKey === undefined || remotePublicKey === '') {
|
||||
throw new Error(
|
||||
'Pairing DH obligatoire : clé publique du pair distant requise (exiger publicKey).',
|
||||
@ -479,14 +508,14 @@ export async function runDevice1Confirmation(
|
||||
);
|
||||
const n = generateUuid();
|
||||
const sig = signMembreFinaliser(hash, identity, n);
|
||||
await publishPairingMessageAndSignature(
|
||||
await publishPairingMessageAndSignature({
|
||||
relays,
|
||||
message,
|
||||
hash,
|
||||
sig,
|
||||
remotePublicKey,
|
||||
identity,
|
||||
);
|
||||
recipientPublicKey: remotePublicKey,
|
||||
senderIdentity: identity,
|
||||
});
|
||||
for (let i = 0; i < POLL_ATTEMPTS; i++) {
|
||||
if (i > 0) {
|
||||
await delay(POLL_DELAY_MS);
|
||||
@ -508,28 +537,41 @@ export async function runDevice1Confirmation(
|
||||
return false;
|
||||
}
|
||||
|
||||
interface RunDevice2ConfirmationParams {
|
||||
pairLocal: string;
|
||||
pairRemote: string;
|
||||
identity: LocalIdentity;
|
||||
relays: RelayConfig[];
|
||||
start: number;
|
||||
end: number;
|
||||
remotePublicKey?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run confirmation flow for device 2: fetch M, verify sig1, sign, publish sig2, store.
|
||||
* remotePublicKey: identity public key of device 1 (sender), for ECDH decryption.
|
||||
*/
|
||||
export async function runDevice2Confirmation(
|
||||
pairLocal: string,
|
||||
pairRemote: string,
|
||||
identity: LocalIdentity,
|
||||
relays: RelayConfig[],
|
||||
start: number,
|
||||
end: number,
|
||||
remotePublicKey?: string,
|
||||
params: RunDevice2ConfirmationParams,
|
||||
): Promise<boolean> {
|
||||
const found = await fetchPairingMessage(
|
||||
const {
|
||||
pairLocal,
|
||||
pairRemote,
|
||||
identity,
|
||||
relays,
|
||||
start,
|
||||
end,
|
||||
remotePublicKey,
|
||||
} = params;
|
||||
const found = await fetchPairingMessage({
|
||||
relays,
|
||||
pairLocal,
|
||||
pairRemote,
|
||||
start,
|
||||
end,
|
||||
remotePublicKey,
|
||||
identity,
|
||||
);
|
||||
senderPublicKey: remotePublicKey,
|
||||
ourIdentity: identity,
|
||||
});
|
||||
if (found === null) {
|
||||
return false;
|
||||
}
|
||||
@ -547,33 +589,46 @@ export async function runDevice2Confirmation(
|
||||
return true;
|
||||
}
|
||||
|
||||
interface CheckPairingConfirmationFromSyncParams {
|
||||
relays: RelayConfig[];
|
||||
pairLocal: string;
|
||||
pairRemote: string;
|
||||
identity: LocalIdentity;
|
||||
start: number;
|
||||
end: number;
|
||||
remotePublicKey?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for pairing confirmation during Sync (device 1 timed out, user runs Sync later).
|
||||
* Fetches pairing message v1, signatures; if both signers present, stores confirmation.
|
||||
* remotePublicKey: identity public key of the other device (sender), for ECDH decryption.
|
||||
*/
|
||||
export async function checkPairingConfirmationFromSync(
|
||||
relays: RelayConfig[],
|
||||
pairLocal: string,
|
||||
pairRemote: string,
|
||||
identity: LocalIdentity,
|
||||
start: number,
|
||||
end: number,
|
||||
remotePublicKey?: string,
|
||||
params: CheckPairingConfirmationFromSyncParams,
|
||||
): Promise<boolean> {
|
||||
const {
|
||||
relays,
|
||||
pairLocal,
|
||||
pairRemote,
|
||||
identity,
|
||||
start,
|
||||
end,
|
||||
remotePublicKey,
|
||||
} = params;
|
||||
const already = await getPairingConfirmed(pairLocal, pairRemote);
|
||||
if (already) {
|
||||
return true;
|
||||
}
|
||||
const found = await fetchPairingMessage(
|
||||
const found = await fetchPairingMessage({
|
||||
relays,
|
||||
pairLocal,
|
||||
pairRemote,
|
||||
start,
|
||||
end,
|
||||
remotePublicKey,
|
||||
identity,
|
||||
);
|
||||
senderPublicKey: remotePublicKey,
|
||||
ourIdentity: identity,
|
||||
});
|
||||
if (found === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -273,8 +273,18 @@ export function uuidToBip32Words(uuid: string): string[] {
|
||||
const uuidBytes = hexToBytes(uuid.replace(/-/g, ''));
|
||||
const words: string[] = [];
|
||||
for (let i = 0; i < uuidBytes.length; i += 2) {
|
||||
const index = (uuidBytes[i]! << 8) | (uuidBytes[i + 1] ?? 0);
|
||||
words.push(BIP32_WORDLIST[index % BIP32_WORDLIST.length]!);
|
||||
const byte1 = uuidBytes[i];
|
||||
if (byte1 === undefined) {
|
||||
continue;
|
||||
}
|
||||
const byte2 = uuidBytes[i + 1] ?? 0;
|
||||
const index = (byte1 << 8) | byte2;
|
||||
const wordIndex = index % BIP32_WORDLIST.length;
|
||||
const word = BIP32_WORDLIST[wordIndex];
|
||||
if (word === undefined) {
|
||||
continue;
|
||||
}
|
||||
words.push(word);
|
||||
}
|
||||
return words;
|
||||
}
|
||||
@ -294,8 +304,12 @@ export function bip32WordsToUuid(words: string[]): string | null {
|
||||
}
|
||||
const bytes = new Uint8Array(indices.length * 2);
|
||||
for (let i = 0; i < indices.length; i++) {
|
||||
bytes[i * 2] = (indices[i]! >> 8) & 0xff;
|
||||
bytes[i * 2 + 1] = indices[i]! & 0xff;
|
||||
const index = indices[i];
|
||||
if (index === undefined) {
|
||||
continue;
|
||||
}
|
||||
bytes[i * 2] = (index >> 8) & 0xff;
|
||||
bytes[i * 2 + 1] = index & 0xff;
|
||||
}
|
||||
const hex = bytesToHex(bytes);
|
||||
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
||||
|
||||
@ -151,19 +151,32 @@ export interface CollectLoopOpts {
|
||||
onProgress?: (merged: ProofSignature[]) => void;
|
||||
}
|
||||
|
||||
interface RunCollectLoopParams {
|
||||
relayEndpoints: string[];
|
||||
hash: string;
|
||||
ourSigs: ProofSignature[];
|
||||
path: LoginPath;
|
||||
pairToMembers: Map<string, string[]>;
|
||||
pubkeyToPair: Map<string, string>;
|
||||
opts: CollectLoopOpts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect signatures from relays until we have enough per member, or timeout.
|
||||
* Optional onProgress called each poll for UI (e.g. X/Y signatures).
|
||||
*/
|
||||
export async function runCollectLoop(
|
||||
relayEndpoints: string[],
|
||||
hash: string,
|
||||
ourSigs: ProofSignature[],
|
||||
path: LoginPath,
|
||||
pairToMembers: Map<string, string[]>,
|
||||
pubkeyToPair: Map<string, string>,
|
||||
opts: CollectLoopOpts,
|
||||
params: RunCollectLoopParams,
|
||||
): Promise<ProofSignature[]> {
|
||||
const {
|
||||
relayEndpoints,
|
||||
hash,
|
||||
ourSigs,
|
||||
path,
|
||||
pairToMembers,
|
||||
pubkeyToPair,
|
||||
opts,
|
||||
} = params;
|
||||
const start = Date.now();
|
||||
let merged = ourSigs;
|
||||
for (;;) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user