@ibgib/core-gib 0.1.45 → 0.1.48

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.
Files changed (99) hide show
  1. package/dist/common/other/ibgib-helper.d.mts +12 -0
  2. package/dist/common/other/ibgib-helper.d.mts.map +1 -1
  3. package/dist/common/other/ibgib-helper.mjs +39 -0
  4. package/dist/common/other/ibgib-helper.mjs.map +1 -1
  5. package/dist/keystone/kdf/kdf-helpers.mjs +2 -2
  6. package/dist/keystone/kdf/kdf-helpers.mjs.map +1 -1
  7. package/dist/keystone/keystone-config-builder.d.mts +2 -1
  8. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  9. package/dist/keystone/keystone-config-builder.mjs +8 -2
  10. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  11. package/dist/keystone/keystone-constants.d.mts +33 -3
  12. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  13. package/dist/keystone/keystone-constants.mjs +31 -1
  14. package/dist/keystone/keystone-constants.mjs.map +1 -1
  15. package/dist/keystone/keystone-helpers.d.mts +16 -1
  16. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  17. package/dist/keystone/keystone-helpers.mjs +227 -8
  18. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  19. package/dist/keystone/keystone-service-v1.d.mts +4 -1
  20. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  21. package/dist/keystone/keystone-service-v1.mjs +6 -1
  22. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  23. package/dist/keystone/keystone-service-v1.respec.mjs +26 -26
  24. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  25. package/dist/keystone/keystone-types.d.mts +26 -5
  26. package/dist/keystone/keystone-types.d.mts.map +1 -1
  27. package/dist/keystone/keystone-types.mjs.map +1 -1
  28. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +1 -1
  29. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
  30. package/dist/sync/sync-conflict-basic-divergence.respec.mjs +1 -1
  31. package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
  32. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +1 -1
  33. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
  34. package/dist/sync/sync-conflict-text-merge.respec.mjs +1 -1
  35. package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
  36. package/dist/sync/sync-constants.d.mts +47 -1
  37. package/dist/sync/sync-constants.d.mts.map +1 -1
  38. package/dist/sync/sync-constants.mjs +49 -1
  39. package/dist/sync/sync-constants.mjs.map +1 -1
  40. package/dist/sync/sync-innerspace-constants.respec.mjs +1 -1
  41. package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
  42. package/dist/sync/sync-innerspace-deep-updates.respec.mjs +1 -1
  43. package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
  44. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +33 -19
  45. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -1
  46. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +1 -1
  47. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
  48. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +1 -1
  49. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  50. package/dist/sync/sync-innerspace-partial-update.respec.mjs +1 -1
  51. package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
  52. package/dist/sync/sync-innerspace.respec.mjs +1 -1
  53. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  54. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  55. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +5 -0
  56. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  57. package/dist/sync/sync-peer/sync-peer-v1.d.mts +6 -1
  58. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  59. package/dist/sync/sync-peer/sync-peer-v1.mjs +56 -14
  60. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  61. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +7 -3
  62. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  63. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +32 -3
  64. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  65. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +16 -0
  66. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  67. package/dist/sync/sync-saga-coordinator.d.mts +18 -3
  68. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  69. package/dist/sync/sync-saga-coordinator.mjs +243 -56
  70. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  71. package/dist/sync/sync-types.d.mts +1 -1
  72. package/dist/sync/sync-types.d.mts.map +1 -1
  73. package/package.json +1 -1
  74. package/src/common/other/ibgib-helper.mts +39 -0
  75. package/src/keystone/kdf/kdf-helpers.mts +2 -2
  76. package/src/keystone/keystone-config-builder.mts +13 -2
  77. package/src/keystone/keystone-constants.mts +33 -2
  78. package/src/keystone/keystone-helpers.mts +237 -8
  79. package/src/keystone/keystone-service-v1.mts +5 -0
  80. package/src/keystone/keystone-service-v1.respec.mts +25 -25
  81. package/src/keystone/keystone-types.mts +31 -8
  82. package/src/sync/sync-conflict-adv-multitimelines.respec.mts +1 -1
  83. package/src/sync/sync-conflict-basic-divergence.respec.mts +1 -1
  84. package/src/sync/sync-conflict-basic-multitimelines.respec.mts +1 -1
  85. package/src/sync/sync-conflict-text-merge.respec.mts +1 -1
  86. package/src/sync/sync-constants.mts +51 -1
  87. package/src/sync/sync-innerspace-constants.respec.mts +1 -1
  88. package/src/sync/sync-innerspace-deep-updates.respec.mts +1 -1
  89. package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +36 -19
  90. package/src/sync/sync-innerspace-dest-ahead.respec.mts +1 -1
  91. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
  92. package/src/sync/sync-innerspace-partial-update.respec.mts +1 -1
  93. package/src/sync/sync-innerspace.respec.mts +1 -1
  94. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +5 -0
  95. package/src/sync/sync-peer/sync-peer-v1.mts +63 -15
  96. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +52 -4
  97. package/src/sync/sync-saga-context/sync-saga-context-types.mts +17 -0
  98. package/src/sync/sync-saga-coordinator.mts +298 -63
  99. package/src/sync/sync-types.mts +1 -1
@@ -5,9 +5,10 @@ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
5
5
  import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
6
6
  import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
7
7
  import { putInSpace, getLatestAddrs, getFromSpace, registerNewIbGib } from "../witness/space/space-helper.mjs";
8
+ import { KeystoneChallengeType } from "../keystone/keystone-types.mjs";
8
9
  import { deriveKey } from "../keystone/kdf/kdf-helpers.mjs";
9
10
  import { KdfStrategy } from "../keystone/kdf/kdf-constants.mjs";
10
- import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN, SyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES, DEFAULT_SESSION_IDENTITY_INITIAL_DELEGATE_SECRET, } from "./sync-constants.mjs";
11
+ import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN, SyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES, SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO, SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS, SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM, SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY, SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL, SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING, SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID, SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_DELEGATE, SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID, SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID, } from "./sync-constants.mjs";
11
12
  import { appendToTimeline, createTimeline, getHistory, getHistoryAddrs } from "../timeline/timeline-api.mjs";
12
13
  import { SyncMode, } from "./sync-types.mjs";
13
14
  import { getSyncSagaFrameOrigin, getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory, getAllOrphanedAddresses, getFinalConflictsInfo } from "./sync-helpers.mjs";
@@ -22,9 +23,11 @@ import { fnObs } from "../common/pubsub/observer/observer-helper.mjs";
22
23
  import { graftTimelines, } from "./graft-info/graft-info-helpers.mjs";
23
24
  import { GRAFT_INFO_REL8N_NAME } from "./graft-info/graft-info-constants.mjs";
24
25
  import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
25
- import { KEYSTONE_VERB_MANAGE } from "../keystone/keystone-constants.mjs";
26
- import { validateKeystoneGraph } from "../keystone/keystone-helpers.mjs";
26
+ import { KEYSTONE_VERB_MANAGE, KEYSTONE_VERB_SIGN } from "../keystone/keystone-constants.mjs";
27
+ import { addToBindingMap, generateOpaqueChallengeId, validateGenesisKeystone, validateKeystoneGraph } from "../keystone/keystone-helpers.mjs";
27
28
  import { SYNC_SAGA_CONTEXT_ATOM } from "./sync-saga-context/sync-saga-context-constants.mjs";
29
+ import { createStandardPoolConfig } from "../keystone/keystone-config-builder.mjs";
30
+ import { KeystoneStrategyFactory } from "../keystone/strategy/keystone-strategy-factory.mjs";
28
31
  const logalot = GLOBAL_LOG_A_LOT;
29
32
  const logalotControlDomain = false;
30
33
  const lcControlDomain = '[ControlDomain]';
@@ -107,7 +110,20 @@ export class SyncSagaCoordinator {
107
110
  // creates the initial session identity (keystone). the flow
108
111
  // (i think) will go: evolve saga frame, then sign keystone,
109
112
  // then create/send context.
110
- sessionIdentity = await this.getSessionIdentity({ sagaId, identitySecret, metaspace, localSpace });
113
+ const resCreateSessionIdentity = await this.createSessionIdentity({
114
+ sagaId,
115
+ primaryIdentity: identity,
116
+ nonSessionSecret: identitySecret,
117
+ metaspace,
118
+ localSpace
119
+ });
120
+ sessionIdentity = resCreateSessionIdentity.sessionIdentity;
121
+ if (identity) {
122
+ if (!resCreateSessionIdentity.newPrimaryIdentity) {
123
+ throw new Error(`(UNEXPECTED) identity truthy but resCreateSessionIdentity.newPrimaryIdentity falsy? (E: 4f82e88a3cc5bd7e58a40f8d77bda826)`);
124
+ }
125
+ identity = resCreateSessionIdentity.newPrimaryIdentity;
126
+ }
111
127
  }
112
128
  // if (logalot) { console.log(`${lc} sessionIdentity: ${sessionIdentity ? pretty(sessionIdentity) : 'undefined'} (I: abc01872800b3a66b819a05898bba826)`); }
113
129
  // CREATE INITIAL FRAME (Stage.init)
@@ -220,15 +236,20 @@ export class SyncSagaCoordinator {
220
236
  }
221
237
  }
222
238
  }
223
- async getSessionSecret({ sagaId, identitySecret, }) {
224
- const lc = `${this.lc}[${this.getSessionSecret.name}]`;
239
+ /**
240
+ * helper that KDFs the given identitySecret, using {@link sagaId} to do so.
241
+ *
242
+ * @returns deterministically derived session secret
243
+ */
244
+ async deriveSessionSecret({ sagaId, nonSessionSecret, }) {
245
+ const lc = `${this.lc}[${this.deriveSessionSecret.name}]`;
225
246
  try {
226
247
  if (logalot) {
227
248
  console.log(`${lc} starting... (I: 0de03f8dcd3e32f1fca244e8f2a8a826)`);
228
249
  }
229
250
  // Derive session-specific secret using KDF
230
251
  const sessionSecret = await deriveKey({
231
- masterSecret: identitySecret,
252
+ masterSecret: nonSessionSecret,
232
253
  kdfOpts: {
233
254
  strategy: KdfStrategy.recursive_salt_wrap,
234
255
  salt: sagaId,
@@ -248,15 +269,15 @@ export class SyncSagaCoordinator {
248
269
  }
249
270
  }
250
271
  }
251
- async getInitialWeakDelegateSessionSecret({ sagaId, }) {
252
- const lc = `${this.lc}[${this.getInitialWeakDelegateSessionSecret.name}]`;
272
+ async getInitialWeakTransitionSessionSecret({ sagaId, }) {
273
+ const lc = `${this.lc}[${this.getInitialWeakTransitionSessionSecret.name}]`;
253
274
  try {
254
275
  if (logalot) {
255
276
  console.log(`${lc} starting... (I: 872ab81a78827b9f2822b78459203226)`);
256
277
  }
257
278
  // Create delegate pool bootstrap secret (publicly derivable)
258
- const initialDelegateSecret = await deriveKey({
259
- masterSecret: DEFAULT_SESSION_IDENTITY_INITIAL_DELEGATE_SECRET, // Weak, publicly derivable secret
279
+ const initialTransitionSecret = await deriveKey({
280
+ masterSecret: SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL, // Weak, publicly derivable secret
260
281
  kdfOpts: {
261
282
  strategy: KdfStrategy.recursive_salt_wrap,
262
283
  salt: sagaId,
@@ -264,7 +285,128 @@ export class SyncSagaCoordinator {
264
285
  algorithm: 'SHA-256'
265
286
  }
266
287
  });
267
- return initialDelegateSecret;
288
+ return initialTransitionSecret;
289
+ }
290
+ catch (error) {
291
+ console.error(`${lc} ${extractErrorMsg(error)}`);
292
+ throw error;
293
+ }
294
+ finally {
295
+ if (logalot) {
296
+ console.log(`${lc} complete.`);
297
+ }
298
+ }
299
+ }
300
+ async getTransitionKeystonePool({ sagaId, }) {
301
+ const lc = `${this.lc}[${this.getTransitionKeystonePool.name}]`;
302
+ try {
303
+ if (logalot) {
304
+ console.log(`${lc} starting... (I: 1ec1c8db7438938b08b96559fcee0826)`);
305
+ }
306
+ const config = createStandardPoolConfig({
307
+ salt: sagaId,
308
+ id: SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID,
309
+ type: KeystoneChallengeType.hash_reveal_v1,
310
+ size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE_TRANSITIONPOOL,
311
+ replenishStrategy: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY_TRANSITIONPOOL,
312
+ random: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM_TRANSITIONPOOL,
313
+ sequential: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL_TRANSITIONPOOL,
314
+ targetBinding: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING_TRANSITIONPOOL,
315
+ hashAlgorithm: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO_TRANSITIONPOOL,
316
+ hashRounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS_TRANSITIONPOOL,
317
+ verbs: SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_TRANSITIONPOOL,
318
+ });
319
+ const strategy = KeystoneStrategyFactory.create({ config });
320
+ const poolSecret = await strategy.derivePoolSecret({
321
+ masterSecret: await this.getInitialWeakTransitionSessionSecret({ sagaId }),
322
+ });
323
+ const challenges = {};
324
+ const bindingMap = {};
325
+ const targetSize = config.behavior.size;
326
+ const timestamp = Date.now().toString();
327
+ for (let i = 0; i < targetSize; i++) {
328
+ const challengeId = await generateOpaqueChallengeId({
329
+ salt: config.salt, timestamp, index: i
330
+ });
331
+ const solution = await strategy.generateSolution({
332
+ poolSecret, poolId: config.salt, challengeId,
333
+ });
334
+ const challenge = await strategy.generateChallenge({ solution });
335
+ challenges[challengeId] = challenge;
336
+ // Populate Binding Map
337
+ addToBindingMap(bindingMap, challengeId);
338
+ }
339
+ const transitionPool = {
340
+ id: SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID,
341
+ config,
342
+ challenges,
343
+ bindingMap,
344
+ isForeign: true,
345
+ // metadata: { origin: 'receiver', role: 'delegate' } // don't need metadata since we have the pool id being 'delegate' (i think)
346
+ };
347
+ return transitionPool;
348
+ }
349
+ catch (error) {
350
+ console.error(`${lc} ${extractErrorMsg(error)}`);
351
+ throw error;
352
+ }
353
+ finally {
354
+ if (logalot) {
355
+ console.log(`${lc} complete.`);
356
+ }
357
+ }
358
+ }
359
+ async getDelegateKeystonePool({ sagaId, }) {
360
+ const lc = `${this.lc}[${this.getDelegateKeystonePool.name}]`;
361
+ try {
362
+ if (logalot) {
363
+ console.log(`${lc} starting... (I: 6b1d338f8e988e68f8d77e72ed00d526)`);
364
+ }
365
+ // todo: change this to a helper function that does the delegated
366
+ // functionality better. also the f***ing binding map needs better
367
+ // implementation. f***ng glazed over by AI.
368
+ const config = createStandardPoolConfig({
369
+ salt: sagaId,
370
+ id: SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID,
371
+ type: KeystoneChallengeType.hash_reveal_v1,
372
+ size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE,
373
+ replenishStrategy: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,
374
+ random: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,
375
+ sequential: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,
376
+ targetBinding: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,
377
+ hashAlgorithm: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,
378
+ hashRounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,
379
+ verbs: SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_DELEGATE,
380
+ });
381
+ const strategy = KeystoneStrategyFactory.create({ config });
382
+ const poolSecret = await strategy.derivePoolSecret({
383
+ masterSecret: SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL
384
+ });
385
+ const challenges = {};
386
+ const bindingMap = {};
387
+ const targetSize = config.behavior.size;
388
+ const timestamp = Date.now().toString();
389
+ for (let i = 0; i < targetSize; i++) {
390
+ const challengeId = await generateOpaqueChallengeId({
391
+ salt: config.salt, timestamp, index: i
392
+ });
393
+ const solution = await strategy.generateSolution({
394
+ poolSecret, poolId: config.salt, challengeId,
395
+ });
396
+ const challenge = await strategy.generateChallenge({ solution });
397
+ challenges[challengeId] = challenge;
398
+ // Populate Binding Map
399
+ addToBindingMap(bindingMap, challengeId);
400
+ }
401
+ const delegatePool = {
402
+ id: SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID,
403
+ config,
404
+ challenges,
405
+ bindingMap,
406
+ isForeign: true,
407
+ // metadata: { origin: 'receiver', role: 'delegate' } // don't need metadata since we have the pool id being 'delegate' (i think)
408
+ };
409
+ return delegatePool;
268
410
  }
269
411
  catch (error) {
270
412
  console.error(`${lc} ${extractErrorMsg(error)}`);
@@ -276,60 +418,102 @@ export class SyncSagaCoordinator {
276
418
  }
277
419
  }
278
420
  }
279
- async getSessionIdentity({ sagaId, identitySecret, metaspace, localSpace, }) {
280
- const lc = `${this.lc}[${this.getSessionIdentity.name}]`;
421
+ /**
422
+ * creates a session identity keystone based off of the given args.
423
+ *
424
+ * Then, if the {@link primaryIdentity} keystone is provided, this also
425
+ * **signs** this keystone pointing to the address of the sess
426
+ * @param param0
427
+ * @returns
428
+ */
429
+ async createSessionIdentity({ sagaId, primaryIdentity, nonSessionSecret, metaspace, localSpace, }) {
430
+ const lc = `${this.lc}[${this.createSessionIdentity.name}]`;
281
431
  try {
282
432
  if (logalot) {
283
433
  console.log(`${lc} starting... (I: 428392a4ee636b7bd8f7d5d89a87e826)`);
284
434
  }
285
- if (!identitySecret) {
286
- throw new Error(`(UNEXPECTED) identitySecret falsy? This is expected to be truthy by this point. (E: 8ce053fe59825a6678713128953b9d26)`);
435
+ if (!nonSessionSecret) {
436
+ throw new Error(`(UNEXPECTED) nonSessionSecret falsy? This is expected to be truthy by this point. (E: 8ce053fe59825a6678713128953b9d26)`);
287
437
  }
288
- const sessionSecret = await this.getSessionSecret({ sagaId, identitySecret });
289
- const init = await this.getInitialWeakDelegateSessionSecret({ sagaId });
290
- // Create TWO pool configs: Primary (strong) + Delegate (weak bootstrap)
438
+ const primarySessionSecret = await this.deriveSessionSecret({
439
+ sagaId, nonSessionSecret
440
+ });
441
+ // Generate keystone with two initial pools in two steps.
442
+ // 1. Create primary pool with genesis method to correspond to the
443
+ // sender/sender's secret/identity.
444
+ // 2. Create a separate pool and add separately because a
445
+ // different pw + config is used for the transition pool.
291
446
  const primaryPoolConfig = {
292
447
  allowedVerbs: [KEYSTONE_VERB_MANAGE],
293
- id: 'primary',
294
- type: 'hash-reveal-v1',
448
+ id: SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID,
295
449
  salt: sagaId,
296
450
  behavior: {
297
- size: 100, // Large pool for many signatures
298
- replenish: 'top-up',
299
- selectSequentially: 2,
300
- selectRandomly: 2,
301
- targetBindingChars: 10
451
+ size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, // Large pool for many signatures
452
+ replenish: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,
453
+ selectSequentially: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,
454
+ selectRandomly: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,
455
+ targetBindingChars: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,
302
456
  },
303
- algo: 'SHA-256',
304
- rounds: 1
457
+ type: KeystoneChallengeType.hash_reveal_v1,
458
+ algo: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,
459
+ rounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,
305
460
  };
306
- const delegatePoolConfig = {
307
- id: 'delegate',
308
- type: 'hash-reveal-v1',
309
- salt: sagaId,
310
- behavior: {
311
- size: 10, // Small pool - only for initial handshake
312
- replenish: 'top-up',
313
- selectSequentially: 1,
314
- selectRandomly: 1,
315
- targetBindingChars: 0
316
- },
317
- algo: 'SHA-256',
318
- rounds: 1
319
- };
320
- // Generate keystone with DUAL pools. We have to first genesis with
321
- // one and then add the other, because we have two distinct
322
- // secrets.
323
- const sessionIdentity = await this.keystoneSvc.genesis({
324
- masterSecret: sessionSecret,
461
+ const sessionIdentity_genesis = await this.keystoneSvc.genesis({
462
+ masterSecret: primarySessionSecret,
325
463
  configs: [primaryPoolConfig],
326
464
  metaspace,
327
- space: localSpace
465
+ space: localSpace,
328
466
  });
329
- // TODO: Store delegate pool separate challenges derived from bootstrap secret
330
- // This allows receiver to verify/evolve the delegate pool
331
- // For now, the keystone genesis with multiple configs handles this
332
- return sessionIdentity;
467
+ // #region sanity validation of genesis keystone
468
+ /**
469
+ * not necessary but since it's a new design, I'm putting in this
470
+ * immediate validation just to put it through its paces. (worth the
471
+ * slight perf hit).
472
+ */
473
+ const validationErrors = await validateGenesisKeystone({
474
+ keystoneIbGib: sessionIdentity_genesis
475
+ });
476
+ if (validationErrors) {
477
+ throw new Error(`(UNEXPECTED) the sessionIdentity_genesis that we just created already has validation errors just after creation? (E: e9ca08cf0f8858bb1ace8b9fa89f8726)`);
478
+ }
479
+ // #endregion sanity validation of genesis keystone
480
+ const transitionPool = await this.getTransitionKeystonePool({ sagaId });
481
+ /**
482
+ * Note this actually **signs** the initial {@link sessionIdentity_genesis}
483
+ * and requires the use of a pool with management priveleges.
484
+ */
485
+ const sessionIdentity_withTransitionPool = await this.keystoneSvc.addPools({
486
+ latestKeystone: sessionIdentity_genesis,
487
+ /**
488
+ * this secret does not do the delegate pool challenges,
489
+ * rather, this is the sessionSecret itself to evolve the
490
+ * keystone **to add** the delegate pool in the first place.
491
+ */
492
+ masterSecret: primarySessionSecret,
493
+ metaspace,
494
+ space: localSpace,
495
+ newPools: [transitionPool],
496
+ });
497
+ let newPrimaryIdentity = undefined;
498
+ if (primaryIdentity) {
499
+ newPrimaryIdentity = await this.keystoneSvc.sign({
500
+ latestKeystone: primaryIdentity,
501
+ poolId: primaryPoolConfig.id,
502
+ claim: {
503
+ verb: KEYSTONE_VERB_SIGN,
504
+ target: getIbGibAddr({ ibGib: sessionIdentity_withTransitionPool }),
505
+ },
506
+ masterSecret: nonSessionSecret,
507
+ metaspace,
508
+ space: localSpace,
509
+ // frameDetails: undefined, // anything to put here?
510
+ // requiredChallengeIds: undefined, // not relevant I think
511
+ });
512
+ }
513
+ return {
514
+ sessionIdentity: sessionIdentity_withTransitionPool,
515
+ newPrimaryIdentity,
516
+ };
333
517
  }
334
518
  catch (error) {
335
519
  console.error(`${lc} ${extractErrorMsg(error)}`);
@@ -589,7 +773,9 @@ export class SyncSagaCoordinator {
589
773
  if (sessionKeystone) {
590
774
  const keystoneErrors = await validateKeystoneGraph({
591
775
  keystoneIbGib: sessionKeystone,
592
- space: localSpace
776
+ space: localSpace,
777
+ getLatest: true,
778
+ invalidIfMoreRecentKeystoneFoundInSpace: true,
593
779
  });
594
780
  if (keystoneErrors.length > 0) {
595
781
  throw new Error(`invalid sessionKeystone. errors: ${keystoneErrors} (E: 3881b8caf2d803767a331e1141e84826)`);
@@ -632,6 +818,7 @@ export class SyncSagaCoordinator {
632
818
  masterSecret: sessionSecret,
633
819
  metaspace,
634
820
  });
821
+ contextIbGib.fnIdentitySecret = () => Promise.resolve(sessionSecret);
635
822
  }
636
823
  return contextIbGib;
637
824
  }
@@ -1366,10 +1553,10 @@ export class SyncSagaCoordinator {
1366
1553
  throw new Error(`${lc} Invalid ack frame: ackData.stage !== SyncStage.ack (E: 2e8b0a94b5954a66a6a1a7a0b3f5b7a1)`);
1367
1554
  }
1368
1555
  if (logalot) {
1369
- console.log(`${lc} ackData: ${pretty(ackData)} (I: 7f8e9d0a1b2c3d4e5f6g7h8i9j0k)`);
1556
+ console.log(`${lc} ackData: ${pretty(ackData)} (I: b817c5571c5e916fe8f90b892b3e8e26)`);
1370
1557
  }
1371
1558
  if (!sagaIbGib.data) {
1372
- throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: 385e389610282aa9c5dbe4083adbde26)`);
1559
+ throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: e3f2e8f162484859787651b85c011826)`);
1373
1560
  }
1374
1561
  // #region sanity/validation
1375
1562
  // 1. Check for Conflicts
@@ -2490,7 +2677,7 @@ export class SyncSagaCoordinator {
2490
2677
  }
2491
2678
  // Attach session keystone to saga frame via hard rel8n
2492
2679
  if (sessionIdentity) {
2493
- rel8ns.sessionKeystones = [getIbGibAddr({ ibGib: sessionIdentity })];
2680
+ rel8ns.sessionKeystone = [getIbGibAddr({ ibGib: sessionIdentity })];
2494
2681
  }
2495
2682
  const resNew = await createTimeline({
2496
2683
  space: localSpace,