@ibgib/space-gib 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/IMPLEMENTATION.md +9 -13
- package/dist/client/bootstrap.mjs +1 -1
- package/dist/client/bootstrap.mjs.map +1 -1
- package/dist/client/chunk-NCXKCVYS.mjs +42 -0
- package/dist/client/chunk-NCXKCVYS.mjs.map +7 -0
- package/dist/client/chunk-ZUEU37Z5.mjs +1920 -0
- package/dist/client/chunk-ZUEU37Z5.mjs.map +7 -0
- package/dist/client/index.html +103 -5
- package/dist/client/index.mjs +1 -1
- package/dist/client/script.mjs +1 -1
- package/dist/client/style.css +466 -61
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +294 -225
- package/dist/server/server.mjs.map +2 -2
- package/package.json +6 -6
- package/src/client/AUTO-GENERATED-version.mts +1 -1
- package/src/client/components/identity-header/IMPLEMENTATION.md +45 -0
- package/src/client/components/identity-header/identity-header.css +74 -0
- package/src/client/components/identity-header/identity-header.html +10 -0
- package/src/client/components/identity-header/identity-header.mts +361 -0
- package/src/client/components/identity-manager/IMPLEMENTATION.md +100 -0
- package/src/client/components/identity-manager/identity-manager.css +467 -0
- package/src/client/components/identity-manager/identity-manager.html +113 -0
- package/src/client/components/identity-manager/identity-manager.mts +767 -0
- package/src/client/components/keystone-creator/keystone-creator.css +2 -76
- package/src/client/components/keystone-creator/keystone-creator.html +41 -26
- package/src/client/components/keystone-creator/keystone-creator.mts +178 -41
- package/src/client/dev-tools/base-tools.mts +252 -0
- package/src/client/dev-tools/common.mts +217 -0
- package/src/client/dev-tools/phase-1.mts +156 -0
- package/src/client/dev-tools/phase-2.mts +143 -0
- package/src/client/dev-tools/phase-3.mts +189 -0
- package/src/client/dev-tools/phase-4-1.mts +197 -0
- package/src/client/dev-tools/phase-4-10.mts +884 -0
- package/src/client/dev-tools/phase-4-2.mts +388 -0
- package/src/client/dev-tools/phase-4-3.mts +391 -0
- package/src/client/dev-tools/phase-4-4.mts +374 -0
- package/src/client/dev-tools/phase-4-5.mts +376 -0
- package/src/client/dev-tools/phase-4-6.mts +273 -0
- package/src/client/dev-tools/phase-4-7.mts +399 -0
- package/src/client/dev-tools/phase-4-8.mts +430 -0
- package/src/client/dev-tools/phase-4-9.mts +398 -0
- package/src/client/dev-tools/phase-4.mts +1302 -0
- package/src/client/dev-tools.mts +52 -1194
- package/src/client/index.html +103 -5
- package/src/client/style.css +466 -61
- package/src/client/ui/shell/space-gib-shell-constants.mts +0 -2
- package/src/client/ui/shell/space-gib-shell-service.mts +82 -10
- package/src/common/common-constants.mts +0 -0
- package/src/common/keystone-policies.json +40 -43
- package/src/common/keystone-policies.mts +3 -5
- package/src/server/path-helper.respec.mts +99 -94
- package/src/server/serve-gib/README.md +9 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +1 -1
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +1 -1
- package/src/server/serve-gib/handlers/ws/sync-upgrade-handler-base.mts +31 -3
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +73 -45
- package/dist/client/chunk-2KJC5XKE.mjs +0 -31
- package/dist/client/chunk-2KJC5XKE.mjs.map +0 -7
- package/dist/client/chunk-QNIXTRFO.mjs +0 -235
- package/dist/client/chunk-QNIXTRFO.mjs.map +0 -7
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
3
|
+
import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
|
|
4
|
+
import { POOL_ID_CONNECT, POOL_ID_SYNC } from '@ibgib/core-gib/dist/keystone/keystone-constants.mjs';
|
|
5
|
+
import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
6
|
+
|
|
7
|
+
import { debugState, devLog, lc, performPhaseSetup, performPhaseSync } from './common.mjs';
|
|
8
|
+
|
|
9
|
+
export function init2bSetupButton(): void {
|
|
10
|
+
const btn = document.getElementById('btn-2b-setup') as HTMLButtonElement | null;
|
|
11
|
+
if (!btn) { return; }
|
|
12
|
+
btn.addEventListener('click', () => {
|
|
13
|
+
performPhaseSetup({
|
|
14
|
+
phaseText: '2B',
|
|
15
|
+
btnId: 'btn-2b-setup',
|
|
16
|
+
nextBtnId: 'btn-2b-sync',
|
|
17
|
+
masterSecret: 'test-sender-secret-phase2',
|
|
18
|
+
syncSalt: 'senderidentitysyncsaltphase2',
|
|
19
|
+
manageSalt: 'senderidentitymanagesaltphase2',
|
|
20
|
+
ib: 'test data',
|
|
21
|
+
data: { hello: 'world2', random: Math.random() }
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function init2bSyncButton(): void {
|
|
27
|
+
const btn = document.getElementById('btn-2b-sync') as HTMLButtonElement | null;
|
|
28
|
+
if (!btn) { return; }
|
|
29
|
+
btn.addEventListener('click', () => {
|
|
30
|
+
performPhaseSync({
|
|
31
|
+
phaseText: '2B',
|
|
32
|
+
btnId: 'btn-2b-sync',
|
|
33
|
+
nextBtnId: 'btn-2b-check',
|
|
34
|
+
expectSyncFailure: true,
|
|
35
|
+
failureMessageSuffix: 'connect phase successfully run; subsequent sync errors expected in 2B'
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function init2bCheckButton(): void {
|
|
41
|
+
const lc_fn = `${lc}[init2bCheckButton]`;
|
|
42
|
+
const btn = document.getElementById('btn-2b-check') as HTMLButtonElement | null;
|
|
43
|
+
if (!btn) { return; }
|
|
44
|
+
|
|
45
|
+
btn.addEventListener('click', async () => {
|
|
46
|
+
try {
|
|
47
|
+
devLog('2B Check: Asserting cryptographic and WebSocket state expectations...');
|
|
48
|
+
|
|
49
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
50
|
+
const space = await metaspace.getLocalUserSpace({});
|
|
51
|
+
if (!space) { throw new Error("No default space."); }
|
|
52
|
+
|
|
53
|
+
const domainI = debugState.domainI!;
|
|
54
|
+
|
|
55
|
+
// 1. Resolve evolved sender identity I1 locally
|
|
56
|
+
const domainAddr = getIbGibAddr({ ibGib: domainI });
|
|
57
|
+
const newSenderIdentityAddr = await metaspace.getLatestAddr({
|
|
58
|
+
addr: domainAddr,
|
|
59
|
+
space
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (!newSenderIdentityAddr) {
|
|
63
|
+
devLog('✗ Check: Evolved domain keystone tip I1 NOT found in local space!');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
devLog(`✓ Check: Evolved Domain Keystone (I1) created and stored locally.`);
|
|
67
|
+
|
|
68
|
+
const getRes = await metaspace.get({ addrs: [newSenderIdentityAddr], space });
|
|
69
|
+
const newSenderIdentity = getRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
70
|
+
|
|
71
|
+
if (!newSenderIdentity) {
|
|
72
|
+
devLog('✗ Check: Failed to load I1 from local space.');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const syncProof = newSenderIdentity.data?.proofs?.find(p => p.claim?.verb === 'sync');
|
|
77
|
+
const sessionIdentityTjpAddr = syncProof?.claim?.target;
|
|
78
|
+
if (!sessionIdentityTjpAddr) {
|
|
79
|
+
devLog('✗ Check: I1 sync claim does not target a session keystone.');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
devLog(`✓ Check: Sync claim targets session keystone: ${sessionIdentityTjpAddr}`);
|
|
83
|
+
|
|
84
|
+
// 2. Load Session Keystone (S) locally and get latest tip
|
|
85
|
+
const latestSessionSAddr = await metaspace.getLatestAddr({
|
|
86
|
+
addr: sessionIdentityTjpAddr,
|
|
87
|
+
space
|
|
88
|
+
});
|
|
89
|
+
if (!latestSessionSAddr) {
|
|
90
|
+
devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
devLog(`✓ Check: Found latest session keystone (S) locally.`);
|
|
94
|
+
|
|
95
|
+
const sRes = await metaspace.get({ addrs: [latestSessionSAddr], space });
|
|
96
|
+
const sessionIdentity = sRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
97
|
+
|
|
98
|
+
if (!sessionIdentity) {
|
|
99
|
+
devLog('✗ Check: Failed to load latest Session Keystone (S).');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Verify S contains connect and sync pools
|
|
104
|
+
const sPools = sessionIdentity.data?.challengePools ?? [];
|
|
105
|
+
const connectPool = sPools.find(p => p.id === POOL_ID_CONNECT);
|
|
106
|
+
const syncPool = sPools.find(p => p.id === POOL_ID_SYNC);
|
|
107
|
+
|
|
108
|
+
if (connectPool && syncPool) {
|
|
109
|
+
devLog('✓ Check: S contains both connect and sync challenge pools.');
|
|
110
|
+
} else {
|
|
111
|
+
devLog(`✗ Check: S is missing challenge pools! (connect: ${!!connectPool}, sync: ${!!syncPool})`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Verify S was successfully evolved (depleted connect pool)
|
|
116
|
+
const remainingChallenges = Object.keys(connectPool.challenges).length;
|
|
117
|
+
if (remainingChallenges === 0) {
|
|
118
|
+
devLog('✓ Check: S connect pool successfully depleted (0 challenges remaining).');
|
|
119
|
+
} else {
|
|
120
|
+
devLog(`✗ Check: S connect pool not depleted! (${remainingChallenges} challenges remaining)`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 3. Verify WebSocket Connection is open and active
|
|
125
|
+
if (debugState.senderPeer && debugState.senderPeer.isSocketOpen) {
|
|
126
|
+
devLog('✓ Check: WebSocket connection is active and OPEN.');
|
|
127
|
+
} else {
|
|
128
|
+
devLog('✗ Check: WebSocket connection is NOT open or peer is missing!');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
devLog('🎉 ALL PHASE 2B CONNECT CHECKS PASSED FLAWLESSLY! ✓');
|
|
133
|
+
btn.textContent = '✓ 2B All Passed';
|
|
134
|
+
|
|
135
|
+
const p3SetupBtn = document.getElementById('btn-3b-setup') as HTMLButtonElement | null;
|
|
136
|
+
if (p3SetupBtn) { p3SetupBtn.disabled = false; }
|
|
137
|
+
|
|
138
|
+
} catch (error) {
|
|
139
|
+
devLog(`✗ 2B Check FAILED: ${extractErrorMsg(error)}`);
|
|
140
|
+
console.error(`${lc_fn} 2B Check error:`, error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
3
|
+
import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
|
|
4
|
+
import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
5
|
+
import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
|
|
6
|
+
import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs';
|
|
7
|
+
|
|
8
|
+
import { debugState, devLog, lc, performPhaseSetup, performPhaseSync } from './common.mjs';
|
|
9
|
+
|
|
10
|
+
export function init3bSetupButton(): void {
|
|
11
|
+
const btn = document.getElementById('btn-3b-setup') as HTMLButtonElement | null;
|
|
12
|
+
if (!btn) { return; }
|
|
13
|
+
btn.addEventListener('click', () => {
|
|
14
|
+
performPhaseSetup({
|
|
15
|
+
phaseText: '3B',
|
|
16
|
+
btnId: 'btn-3b-setup',
|
|
17
|
+
nextBtnId: 'btn-3b-sync',
|
|
18
|
+
masterSecret: 'test-sender-secret-phase3',
|
|
19
|
+
syncSalt: 'senderidentitysyncsaltphase3',
|
|
20
|
+
manageSalt: 'senderidentitymanagesaltphase3',
|
|
21
|
+
ib: 'test data 3b',
|
|
22
|
+
data: { hello: 'world3', random: Math.random() }
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function init3bSyncButton(): void {
|
|
28
|
+
const btn = document.getElementById('btn-3b-sync') as HTMLButtonElement | null;
|
|
29
|
+
if (!btn) { return; }
|
|
30
|
+
btn.addEventListener('click', () => {
|
|
31
|
+
performPhaseSync({
|
|
32
|
+
phaseText: '3B',
|
|
33
|
+
btnId: 'btn-3b-sync',
|
|
34
|
+
nextBtnId: 'btn-3b-check'
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function init3bCheckButton(): void {
|
|
40
|
+
const lc_fn = `${lc}[init3bCheckButton]`;
|
|
41
|
+
const btn = document.getElementById('btn-3b-check') as HTMLButtonElement | null;
|
|
42
|
+
if (!btn) { return; }
|
|
43
|
+
|
|
44
|
+
btn.addEventListener('click', async () => {
|
|
45
|
+
try {
|
|
46
|
+
devLog('3B Check: Asserting cryptographic and WebSocket state expectations...');
|
|
47
|
+
|
|
48
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
49
|
+
const space = await metaspace.getLocalUserSpace({});
|
|
50
|
+
if (!space) { throw new Error("No default space."); }
|
|
51
|
+
|
|
52
|
+
const domainI = debugState.domainI!;
|
|
53
|
+
const targetX = debugState.targetX!;
|
|
54
|
+
const xAddr = getIbGibAddr({ ibGib: targetX });
|
|
55
|
+
const domainAddr = getIbGibAddr({ ibGib: domainI });
|
|
56
|
+
|
|
57
|
+
// 1. Assert Target X exists locally (with evolved timeline) and get latest local graph
|
|
58
|
+
const latestLocalXAddr = await metaspace.getLatestAddr({
|
|
59
|
+
addr: xAddr,
|
|
60
|
+
space
|
|
61
|
+
});
|
|
62
|
+
if (!latestLocalXAddr) {
|
|
63
|
+
devLog('✗ Check: Evolved target X NOT found in local space!');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
devLog(`✓ Check: Evolved target X found locally at: ${latestLocalXAddr}`);
|
|
67
|
+
|
|
68
|
+
const localXGraph = await metaspace.getDependencyGraph({
|
|
69
|
+
ibGibAddr: latestLocalXAddr,
|
|
70
|
+
space
|
|
71
|
+
});
|
|
72
|
+
if (!localXGraph || Object.keys(localXGraph).length === 0) {
|
|
73
|
+
devLog('✗ Check: Failed to load target X dependency graph locally.');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
devLog(`✓ Check: Target X local graph loaded (${Object.keys(localXGraph).length} nodes).`);
|
|
77
|
+
|
|
78
|
+
// 2. Fetch server's Target X graph via API bridge
|
|
79
|
+
const apiBridge = new SpaceGibApiBridge();
|
|
80
|
+
const serverGetRes = await apiBridge.getIbGibGraph(domainAddr, xAddr, true);
|
|
81
|
+
if (!serverGetRes.success || !serverGetRes.graph) {
|
|
82
|
+
devLog(`✗ Check: Failed to fetch target X graph from server: ${serverGetRes.message}`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const serverXGraph = serverGetRes.graph;
|
|
86
|
+
devLog(`✓ Check: Target X server graph loaded (${Object.keys(serverXGraph).length} nodes).`);
|
|
87
|
+
|
|
88
|
+
// 3. Verify graphs are equivalent using graphsAreEquivalent
|
|
89
|
+
const equal = graphsAreEquivalent({ graphA: localXGraph, graphB: serverXGraph });
|
|
90
|
+
if (equal) {
|
|
91
|
+
devLog('✓ Check: Target X dependency graphs are equivalent on client and server.');
|
|
92
|
+
} else {
|
|
93
|
+
devLog('✗ Check: Target X dependency graphs mismatch between client and server!');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 4. Assert evolved sender identity I1 exists locally and on server
|
|
98
|
+
const latestLocalIAddr = await metaspace.getLatestAddr({
|
|
99
|
+
addr: domainAddr,
|
|
100
|
+
space
|
|
101
|
+
});
|
|
102
|
+
if (!latestLocalIAddr) {
|
|
103
|
+
devLog('✗ Check: Evolved domain keystone tip I1 NOT found in local space!');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
devLog(`✓ Check: Evolved Domain Keystone (I1) exists locally.`);
|
|
107
|
+
|
|
108
|
+
const getRes = await metaspace.get({ addrs: [latestLocalIAddr], space });
|
|
109
|
+
const localI = getRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
110
|
+
if (!localI) {
|
|
111
|
+
devLog('✗ Check: Failed to load I1 from local space.');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const syncProof = localI.data?.proofs?.find(p => p.claim?.verb === 'sync');
|
|
116
|
+
const sessionIdentityTjpAddr = syncProof?.claim?.target;
|
|
117
|
+
if (!sessionIdentityTjpAddr) {
|
|
118
|
+
devLog('✗ Check: I1 sync claim does not target a session keystone.');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const serverIGetRes = await apiBridge.getIbGib(domainAddr, latestLocalIAddr);
|
|
123
|
+
if (!serverIGetRes.success || !serverIGetRes.ibGib) {
|
|
124
|
+
devLog(`✗ Check: Evolved Domain Keystone (I1) NOT found on server!`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
devLog(`✓ Check: Evolved Domain Keystone (I1) exists on server.`);
|
|
128
|
+
|
|
129
|
+
// 5. Assert session identity S tip exists locally and on server
|
|
130
|
+
const latestLocalSAddr = await metaspace.getLatestAddr({
|
|
131
|
+
addr: sessionIdentityTjpAddr,
|
|
132
|
+
space
|
|
133
|
+
});
|
|
134
|
+
if (!latestLocalSAddr) {
|
|
135
|
+
devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
devLog(`✓ Check: Found latest session keystone (S) locally: ${latestLocalSAddr}`);
|
|
139
|
+
|
|
140
|
+
const localSRes = await metaspace.get({ addrs: [latestLocalSAddr], space });
|
|
141
|
+
const sessionS = localSRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
142
|
+
if (!sessionS) {
|
|
143
|
+
devLog('✗ Check: Failed to load latest Session Keystone (S) locally.');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Verify S evolved to correct n (n === 3 or 4)
|
|
148
|
+
const n = sessionS.data?.n;
|
|
149
|
+
devLog(`✓ Check: S tip evolved to n = ${n}.`);
|
|
150
|
+
if (n !== 3 && n !== 4) {
|
|
151
|
+
devLog(`⚠ Check: Expected S to evolve to n = 3 or 4, got n = ${n}. Continuing anyway...`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const serverSGetRes = await apiBridge.getIbGib(domainAddr, latestLocalSAddr);
|
|
155
|
+
if (!serverSGetRes.success || !serverSGetRes.ibGib) {
|
|
156
|
+
devLog(`✗ Check: Latest Session Keystone (S) NOT found on server!`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
devLog(`✓ Check: Latest Session Keystone (S) exists on server.`);
|
|
160
|
+
|
|
161
|
+
// 6. Assert S graph is identical on client and server
|
|
162
|
+
const localSGraph = await metaspace.getDependencyGraph({
|
|
163
|
+
ibGibAddr: latestLocalSAddr,
|
|
164
|
+
space
|
|
165
|
+
});
|
|
166
|
+
const serverSGetGraphRes = await apiBridge.getIbGibGraph(domainAddr, sessionIdentityTjpAddr, true);
|
|
167
|
+
if (!serverSGetGraphRes.success || !serverSGetGraphRes.graph) {
|
|
168
|
+
devLog(`✗ Check: Failed to fetch session S graph from server: ${serverSGetGraphRes.message}`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const serverSGraph = serverSGetGraphRes.graph;
|
|
172
|
+
|
|
173
|
+
const sGraphsEqual = graphsAreEquivalent({ graphA: localSGraph, graphB: serverSGraph });
|
|
174
|
+
if (sGraphsEqual) {
|
|
175
|
+
devLog('✓ Check: Session Keystone (S) dependency graphs are equivalent on client and server.');
|
|
176
|
+
} else {
|
|
177
|
+
devLog('✗ Check: Session Keystone (S) dependency graphs mismatch between client and server!');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
devLog('🎉 ALL PHASE 3B TRANSACTION SYNC CHECKS PASSED FLAWLESSLY! ✓');
|
|
182
|
+
btn.textContent = '✓ 3B All Passed';
|
|
183
|
+
|
|
184
|
+
} catch (error) {
|
|
185
|
+
devLog(`✗ 3B Check FAILED: ${extractErrorMsg(error)}`);
|
|
186
|
+
console.error(`${lc_fn} 3B Check error:`, error);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { extractErrorMsg, getUUID, getTimestamp } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
|
+
import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';
|
|
3
|
+
import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
|
|
4
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
5
|
+
import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
|
|
6
|
+
import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
|
|
7
|
+
import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
8
|
+
import { mut8Timeline } from '@ibgib/core-gib/dist/timeline/timeline-api.mjs';
|
|
9
|
+
import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
|
|
10
|
+
import { SyncPeerWebSocketSender_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs';
|
|
11
|
+
import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs';
|
|
12
|
+
import { SyncConflictStrategy } from '@ibgib/core-gib/dist/sync/sync-constants.mjs';
|
|
13
|
+
import { SESSION_KEYSTONE_POLICY, getSpaceGibPoolConfig } from "../../common/keystone-policies.mjs";
|
|
14
|
+
import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs';
|
|
15
|
+
|
|
16
|
+
import { debugState, devLog, lc, performPhaseSetup, performPhaseSync } from './common.mjs';
|
|
17
|
+
|
|
18
|
+
export function init4_1bSetupButton(): void {
|
|
19
|
+
const btn = document.getElementById('btn-4-1b-setup') as HTMLButtonElement | null;
|
|
20
|
+
if (!btn) { return; }
|
|
21
|
+
btn.addEventListener('click', () => {
|
|
22
|
+
performPhaseSetup({
|
|
23
|
+
phaseText: '4.1B',
|
|
24
|
+
btnId: 'btn-4-1b-setup',
|
|
25
|
+
nextBtnId: 'btn-4-1b-sync',
|
|
26
|
+
masterSecret: 'test-sender-secret-phase4-1',
|
|
27
|
+
syncSalt: 'senderidentitysyncsaltphase4-1',
|
|
28
|
+
manageSalt: 'senderidentitymanagesaltphase4-1',
|
|
29
|
+
ib: 'test data 4.1b',
|
|
30
|
+
data: { hello: 'world4_1', random: Math.random() }
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function init4_1bSyncButton(): void {
|
|
36
|
+
const btn = document.getElementById('btn-4-1b-sync') as HTMLButtonElement | null;
|
|
37
|
+
if (!btn) { return; }
|
|
38
|
+
btn.addEventListener('click', () => {
|
|
39
|
+
performPhaseSync({
|
|
40
|
+
phaseText: '4.1B',
|
|
41
|
+
btnId: 'btn-4-1b-sync',
|
|
42
|
+
nextBtnId: 'btn-4-1b-check'
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function init4_1bCheckButton(): void {
|
|
48
|
+
const lc_fn = `${lc}[init4_1bCheckButton]`;
|
|
49
|
+
const btn = document.getElementById('btn-4-1b-check') as HTMLButtonElement | null;
|
|
50
|
+
if (!btn) { return; }
|
|
51
|
+
|
|
52
|
+
btn.addEventListener('click', async () => {
|
|
53
|
+
try {
|
|
54
|
+
devLog('4.1B Check: Asserting cryptographic and WebSocket state expectations...');
|
|
55
|
+
|
|
56
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
57
|
+
const space = await metaspace.getLocalUserSpace({});
|
|
58
|
+
if (!space) { throw new Error("No default space."); }
|
|
59
|
+
|
|
60
|
+
const domainI = debugState.domainI!;
|
|
61
|
+
const targetX = debugState.targetX!;
|
|
62
|
+
const xAddr = getIbGibAddr({ ibGib: targetX });
|
|
63
|
+
const domainAddr = getIbGibAddr({ ibGib: domainI });
|
|
64
|
+
|
|
65
|
+
// 1. Assert Target X exists locally (with evolved timeline) and get latest local graph
|
|
66
|
+
const latestLocalXAddr = await metaspace.getLatestAddr({
|
|
67
|
+
addr: xAddr,
|
|
68
|
+
space
|
|
69
|
+
});
|
|
70
|
+
if (!latestLocalXAddr) {
|
|
71
|
+
devLog('✗ Check: Evolved target X NOT found in local space!');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
devLog(`✓ Check: Evolved target X found locally at: ${latestLocalXAddr}`);
|
|
75
|
+
|
|
76
|
+
const localXGraph = await metaspace.getDependencyGraph({
|
|
77
|
+
ibGibAddr: latestLocalXAddr,
|
|
78
|
+
space
|
|
79
|
+
});
|
|
80
|
+
if (!localXGraph || Object.keys(localXGraph).length === 0) {
|
|
81
|
+
devLog('✗ Check: Failed to load target X dependency graph locally.');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
devLog(`✓ Check: Target X local graph loaded (${Object.keys(localXGraph).length} nodes).`);
|
|
85
|
+
|
|
86
|
+
// 2. Fetch server's Target X graph via API bridge
|
|
87
|
+
const apiBridge = new SpaceGibApiBridge();
|
|
88
|
+
const serverGetRes = await apiBridge.getIbGibGraph(domainAddr, xAddr, true);
|
|
89
|
+
if (!serverGetRes.success || !serverGetRes.graph) {
|
|
90
|
+
devLog(`✗ Check: Failed to fetch target X graph from server: ${serverGetRes.message}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const serverXGraph = serverGetRes.graph;
|
|
94
|
+
devLog(`✓ Check: Target X server graph loaded (${Object.keys(serverXGraph).length} nodes).`);
|
|
95
|
+
|
|
96
|
+
// 3. Verify graphs are equivalent using graphsAreEquivalent
|
|
97
|
+
const equal = graphsAreEquivalent({ graphA: localXGraph, graphB: serverXGraph });
|
|
98
|
+
if (equal) {
|
|
99
|
+
devLog('✓ Check: Target X dependency graphs are equivalent on client and server.');
|
|
100
|
+
} else {
|
|
101
|
+
devLog('✗ Check: Target X dependency graphs mismatch between client and server!');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 4. Assert evolved sender identity I1 exists locally and on server
|
|
106
|
+
const latestLocalIAddr = await metaspace.getLatestAddr({
|
|
107
|
+
addr: domainAddr,
|
|
108
|
+
space
|
|
109
|
+
});
|
|
110
|
+
if (!latestLocalIAddr) {
|
|
111
|
+
devLog('✗ Check: Evolved domain keystone tip I1 NOT found in local space!');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
devLog(`✓ Check: Evolved Domain Keystone (I1) exists locally.`);
|
|
115
|
+
|
|
116
|
+
const getRes = await metaspace.get({ addrs: [latestLocalIAddr], space });
|
|
117
|
+
const localI = getRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
118
|
+
if (!localI) {
|
|
119
|
+
devLog('✗ Check: Failed to load I1 from local space.');
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const syncProof = localI.data?.proofs?.find(p => p.claim?.verb === 'sync');
|
|
124
|
+
const sessionIdentityTjpAddr = syncProof?.claim?.target;
|
|
125
|
+
if (!sessionIdentityTjpAddr) {
|
|
126
|
+
devLog('✗ Check: I1 sync claim does not target a session keystone.');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const serverIGetRes = await apiBridge.getIbGib(domainAddr, latestLocalIAddr);
|
|
131
|
+
if (!serverIGetRes.success || !serverIGetRes.ibGib) {
|
|
132
|
+
devLog(`✗ Check: Evolved Domain Keystone (I1) NOT found on server!`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
devLog(`✓ Check: Evolved Domain Keystone (I1) exists on server.`);
|
|
136
|
+
|
|
137
|
+
// 5. Assert session identity S tip exists locally and on server
|
|
138
|
+
const latestLocalSAddr = await metaspace.getLatestAddr({
|
|
139
|
+
addr: sessionIdentityTjpAddr,
|
|
140
|
+
space
|
|
141
|
+
});
|
|
142
|
+
if (!latestLocalSAddr) {
|
|
143
|
+
devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
devLog(`✓ Check: Found latest session keystone (S) locally: ${latestLocalSAddr}`);
|
|
147
|
+
|
|
148
|
+
const localSRes = await metaspace.get({ addrs: [latestLocalSAddr], space });
|
|
149
|
+
const sessionS = localSRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
|
|
150
|
+
if (!sessionS) {
|
|
151
|
+
devLog('✗ Check: Failed to load latest Session Keystone (S) locally.');
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Verify S evolved to correct n (n === 3 or 4)
|
|
156
|
+
const n = sessionS.data?.n;
|
|
157
|
+
devLog(`✓ Check: S tip evolved to n = ${n}.`);
|
|
158
|
+
if (n !== 3 && n !== 4) {
|
|
159
|
+
devLog(`⚠ Check: Expected S to evolve to n = 3 or 4, got n = ${n}. Continuing anyway...`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const serverSGetRes = await apiBridge.getIbGib(domainAddr, latestLocalSAddr);
|
|
163
|
+
if (!serverSGetRes.success || !serverSGetRes.ibGib) {
|
|
164
|
+
devLog(`✗ Check: Latest Session Keystone (S) NOT found on server!`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
devLog(`✓ Check: Latest Session Keystone (S) exists on server.`);
|
|
168
|
+
|
|
169
|
+
// 6. Assert S graph is identical on client and server
|
|
170
|
+
const localSGraph = await metaspace.getDependencyGraph({
|
|
171
|
+
ibGibAddr: latestLocalSAddr,
|
|
172
|
+
space
|
|
173
|
+
});
|
|
174
|
+
const serverSGetGraphRes = await apiBridge.getIbGibGraph(domainAddr, sessionIdentityTjpAddr, true);
|
|
175
|
+
if (!serverSGetGraphRes.success || !serverSGetGraphRes.graph) {
|
|
176
|
+
devLog(`✗ Check: Failed to fetch session S graph from server: ${serverSGetGraphRes.message}`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const serverSGraph = serverSGetGraphRes.graph;
|
|
180
|
+
|
|
181
|
+
const sGraphsEqual = graphsAreEquivalent({ graphA: localSGraph, graphB: serverSGraph });
|
|
182
|
+
if (sGraphsEqual) {
|
|
183
|
+
devLog('✓ Check: Session Keystone (S) dependency graphs are equivalent on client and server.');
|
|
184
|
+
} else {
|
|
185
|
+
devLog('✗ Check: Session Keystone (S) dependency graphs mismatch between client and server!');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
devLog('🎉 ALL PHASE 4.1B TRANSACTION SYNC CHECKS PASSED FLAWLESSLY! ✓');
|
|
190
|
+
btn.textContent = '✓ 4.1B All Passed';
|
|
191
|
+
|
|
192
|
+
} catch (error) {
|
|
193
|
+
devLog(`✗ 4.1B Check FAILED: ${extractErrorMsg(error)}`);
|
|
194
|
+
console.error(`${lc_fn} 4.1B Check error:`, error);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|