import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs'; import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs'; import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs'; import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs"; import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs'; import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs'; import { debugState, devLog, lc, performPhaseSetup, performPhaseSync } from './common.mjs'; export function init3bSetupButton(): void { const btn = document.getElementById('btn-3b-setup') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', () => { performPhaseSetup({ phaseText: '3B', btnId: 'btn-3b-setup', nextBtnId: 'btn-3b-sync', masterSecret: 'test-sender-secret-phase3', syncSalt: 'senderidentitysyncsaltphase3', manageSalt: 'senderidentitymanagesaltphase3', ib: 'test data 3b', data: { hello: 'world3', random: Math.random() } }); }); } export function init3bSyncButton(): void { const btn = document.getElementById('btn-3b-sync') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', () => { performPhaseSync({ phaseText: '3B', btnId: 'btn-3b-sync', nextBtnId: 'btn-3b-check' }); }); } export function init3bCheckButton(): void { const lc_fn = `${lc}[init3bCheckButton]`; const btn = document.getElementById('btn-3b-check') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { devLog('3B Check: Asserting cryptographic and WebSocket state expectations...'); const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}); if (!space) { throw new Error("No default space."); } const domainI = debugState.domainI!; const targetX = debugState.targetX!; const xAddr = getIbGibAddr({ ibGib: targetX }); const domainAddr = getIbGibAddr({ ibGib: domainI }); // 1. Assert Target X exists locally (with evolved timeline) and get latest local graph const latestLocalXAddr = await metaspace.getLatestAddr({ addr: xAddr, space }); if (!latestLocalXAddr) { devLog('✗ Check: Evolved target X NOT found in local space!'); return; } devLog(`✓ Check: Evolved target X found locally at: ${latestLocalXAddr}`); const localXGraph = await metaspace.getDependencyGraph({ ibGibAddr: latestLocalXAddr, space }); if (!localXGraph || Object.keys(localXGraph).length === 0) { devLog('✗ Check: Failed to load target X dependency graph locally.'); return; } devLog(`✓ Check: Target X local graph loaded (${Object.keys(localXGraph).length} nodes).`); // 2. Fetch server's Target X graph via API bridge const apiBridge = new SpaceGibApiBridge(); const serverGetRes = await apiBridge.getIbGibGraph(domainAddr, xAddr, true); if (!serverGetRes.success || !serverGetRes.graph) { devLog(`✗ Check: Failed to fetch target X graph from server: ${serverGetRes.message}`); return; } const serverXGraph = serverGetRes.graph; devLog(`✓ Check: Target X server graph loaded (${Object.keys(serverXGraph).length} nodes).`); // 3. Verify graphs are equivalent using graphsAreEquivalent const equal = graphsAreEquivalent({ graphA: localXGraph, graphB: serverXGraph }); if (equal) { devLog('✓ Check: Target X dependency graphs are equivalent on client and server.'); } else { devLog('✗ Check: Target X dependency graphs mismatch between client and server!'); return; } // 4. Assert evolved sender identity I1 exists locally and on server const latestLocalIAddr = await metaspace.getLatestAddr({ addr: domainAddr, space }); if (!latestLocalIAddr) { devLog('✗ Check: Evolved domain keystone tip I1 NOT found in local space!'); return; } devLog(`✓ Check: Evolved Domain Keystone (I1) exists locally.`); const getRes = await metaspace.get({ addrs: [latestLocalIAddr], space }); const localI = getRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined; if (!localI) { devLog('✗ Check: Failed to load I1 from local space.'); return; } const syncProof = localI.data?.proofs?.find(p => p.claim?.verb === 'sync'); const sessionIdentityTjpAddr = syncProof?.claim?.target; if (!sessionIdentityTjpAddr) { devLog('✗ Check: I1 sync claim does not target a session keystone.'); return; } const serverIGetRes = await apiBridge.getIbGib(domainAddr, latestLocalIAddr); if (!serverIGetRes.success || !serverIGetRes.ibGib) { devLog(`✗ Check: Evolved Domain Keystone (I1) NOT found on server!`); return; } devLog(`✓ Check: Evolved Domain Keystone (I1) exists on server.`); // 5. Assert session identity S tip exists locally and on server const latestLocalSAddr = await metaspace.getLatestAddr({ addr: sessionIdentityTjpAddr, space }); if (!latestLocalSAddr) { devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.'); return; } devLog(`✓ Check: Found latest session keystone (S) locally: ${latestLocalSAddr}`); const localSRes = await metaspace.get({ addrs: [latestLocalSAddr], space }); const sessionS = localSRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined; if (!sessionS) { devLog('✗ Check: Failed to load latest Session Keystone (S) locally.'); return; } // Verify S evolved to correct n (n === 3 or 4) const n = sessionS.data?.n; devLog(`✓ Check: S tip evolved to n = ${n}.`); if (n !== 3 && n !== 4) { devLog(`⚠ Check: Expected S to evolve to n = 3 or 4, got n = ${n}. Continuing anyway...`); } const serverSGetRes = await apiBridge.getIbGib(domainAddr, latestLocalSAddr); if (!serverSGetRes.success || !serverSGetRes.ibGib) { devLog(`✗ Check: Latest Session Keystone (S) NOT found on server!`); return; } devLog(`✓ Check: Latest Session Keystone (S) exists on server.`); // 6. Assert S graph is identical on client and server const localSGraph = await metaspace.getDependencyGraph({ ibGibAddr: latestLocalSAddr, space }); const serverSGetGraphRes = await apiBridge.getIbGibGraph(domainAddr, sessionIdentityTjpAddr, true); if (!serverSGetGraphRes.success || !serverSGetGraphRes.graph) { devLog(`✗ Check: Failed to fetch session S graph from server: ${serverSGetGraphRes.message}`); return; } const serverSGraph = serverSGetGraphRes.graph; const sGraphsEqual = graphsAreEquivalent({ graphA: localSGraph, graphB: serverSGraph }); if (sGraphsEqual) { devLog('✓ Check: Session Keystone (S) dependency graphs are equivalent on client and server.'); } else { devLog('✗ Check: Session Keystone (S) dependency graphs mismatch between client and server!'); return; } devLog('🎉 ALL PHASE 3B TRANSACTION SYNC CHECKS PASSED FLAWLESSLY! ✓'); btn.textContent = '✓ 3B All Passed'; } catch (error) { devLog(`✗ 3B Check FAILED: ${extractErrorMsg(error)}`); console.error(`${lc_fn} 3B Check error:`, error); } }); }