@ibgib/core-gib 0.1.47 → 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 (98) 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 +24 -3
  12. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  13. package/dist/keystone/keystone-constants.mjs +22 -1
  14. package/dist/keystone/keystone-constants.mjs.map +1 -1
  15. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  16. package/dist/keystone/keystone-helpers.mjs +7 -9
  17. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  18. package/dist/keystone/keystone-service-v1.d.mts +4 -1
  19. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  20. package/dist/keystone/keystone-service-v1.mjs +6 -1
  21. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  22. package/dist/keystone/keystone-service-v1.respec.mjs +26 -26
  23. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  24. package/dist/keystone/keystone-types.d.mts +24 -5
  25. package/dist/keystone/keystone-types.d.mts.map +1 -1
  26. package/dist/keystone/keystone-types.mjs.map +1 -1
  27. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +1 -1
  28. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
  29. package/dist/sync/sync-conflict-basic-divergence.respec.mjs +1 -1
  30. package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
  31. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +1 -1
  32. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
  33. package/dist/sync/sync-conflict-text-merge.respec.mjs +1 -1
  34. package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
  35. package/dist/sync/sync-constants.d.mts +47 -1
  36. package/dist/sync/sync-constants.d.mts.map +1 -1
  37. package/dist/sync/sync-constants.mjs +49 -1
  38. package/dist/sync/sync-constants.mjs.map +1 -1
  39. package/dist/sync/sync-innerspace-constants.respec.mjs +1 -1
  40. package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
  41. package/dist/sync/sync-innerspace-deep-updates.respec.mjs +1 -1
  42. package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
  43. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +33 -19
  44. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -1
  45. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +1 -1
  46. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
  47. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +1 -1
  48. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  49. package/dist/sync/sync-innerspace-partial-update.respec.mjs +1 -1
  50. package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
  51. package/dist/sync/sync-innerspace.respec.mjs +1 -1
  52. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  53. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  54. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +5 -0
  55. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  56. package/dist/sync/sync-peer/sync-peer-v1.d.mts +6 -1
  57. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  58. package/dist/sync/sync-peer/sync-peer-v1.mjs +56 -23
  59. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  60. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +7 -3
  61. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  62. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +32 -3
  63. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  64. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +16 -0
  65. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  66. package/dist/sync/sync-saga-coordinator.d.mts +18 -3
  67. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  68. package/dist/sync/sync-saga-coordinator.mjs +240 -55
  69. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  70. package/dist/sync/sync-types.d.mts +1 -1
  71. package/dist/sync/sync-types.d.mts.map +1 -1
  72. package/package.json +1 -1
  73. package/src/common/other/ibgib-helper.mts +39 -0
  74. package/src/keystone/kdf/kdf-helpers.mts +2 -2
  75. package/src/keystone/keystone-config-builder.mts +13 -2
  76. package/src/keystone/keystone-constants.mts +24 -2
  77. package/src/keystone/keystone-helpers.mts +5 -10
  78. package/src/keystone/keystone-service-v1.mts +5 -0
  79. package/src/keystone/keystone-service-v1.respec.mts +25 -25
  80. package/src/keystone/keystone-types.mts +27 -7
  81. package/src/sync/sync-conflict-adv-multitimelines.respec.mts +1 -1
  82. package/src/sync/sync-conflict-basic-divergence.respec.mts +1 -1
  83. package/src/sync/sync-conflict-basic-multitimelines.respec.mts +1 -1
  84. package/src/sync/sync-conflict-text-merge.respec.mts +1 -1
  85. package/src/sync/sync-constants.mts +51 -1
  86. package/src/sync/sync-innerspace-constants.respec.mts +1 -1
  87. package/src/sync/sync-innerspace-deep-updates.respec.mts +1 -1
  88. package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +36 -19
  89. package/src/sync/sync-innerspace-dest-ahead.respec.mts +1 -1
  90. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
  91. package/src/sync/sync-innerspace-partial-update.respec.mts +1 -1
  92. package/src/sync/sync-innerspace.respec.mts +1 -1
  93. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +5 -0
  94. package/src/sync/sync-peer/sync-peer-v1.mts +63 -25
  95. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +52 -4
  96. package/src/sync/sync-saga-context/sync-saga-context-types.mts +17 -0
  97. package/src/sync/sync-saga-coordinator.mts +295 -62
  98. 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,7 @@ export class SyncSagaCoordinator {
264
285
  algorithm: 'SHA-256'
265
286
  }
266
287
  });
267
- return initialDelegateSecret;
288
+ return initialTransitionSecret;
268
289
  }
269
290
  catch (error) {
270
291
  console.error(`${lc} ${extractErrorMsg(error)}`);
@@ -276,60 +297,223 @@ export class SyncSagaCoordinator {
276
297
  }
277
298
  }
278
299
  }
279
- async getSessionIdentity({ sagaId, identitySecret, metaspace, localSpace, }) {
280
- const lc = `${this.lc}[${this.getSessionIdentity.name}]`;
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;
410
+ }
411
+ catch (error) {
412
+ console.error(`${lc} ${extractErrorMsg(error)}`);
413
+ throw error;
414
+ }
415
+ finally {
416
+ if (logalot) {
417
+ console.log(`${lc} complete.`);
418
+ }
419
+ }
420
+ }
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',
295
- salt: sagaId,
296
- behavior: {
297
- size: 100, // Large pool for many signatures
298
- replenish: 'top-up',
299
- selectSequentially: 2,
300
- selectRandomly: 2,
301
- targetBindingChars: 10
302
- },
303
- algo: 'SHA-256',
304
- rounds: 1
305
- };
306
- const delegatePoolConfig = {
307
- id: 'delegate',
308
- type: 'hash-reveal-v1',
448
+ id: SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID,
309
449
  salt: sagaId,
310
450
  behavior: {
311
- size: 10, // Small pool - only for initial handshake
312
- replenish: 'top-up',
313
- selectSequentially: 1,
314
- selectRandomly: 1,
315
- targetBindingChars: 0
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,
316
456
  },
317
- algo: 'SHA-256',
318
- rounds: 1
457
+ type: KeystoneChallengeType.hash_reveal_v1,
458
+ algo: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,
459
+ rounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,
319
460
  };
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,
466
+ });
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],
328
496
  });
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;
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)}`);
@@ -634,6 +818,7 @@ export class SyncSagaCoordinator {
634
818
  masterSecret: sessionSecret,
635
819
  metaspace,
636
820
  });
821
+ contextIbGib.fnIdentitySecret = () => Promise.resolve(sessionSecret);
637
822
  }
638
823
  return contextIbGib;
639
824
  }
@@ -1368,10 +1553,10 @@ export class SyncSagaCoordinator {
1368
1553
  throw new Error(`${lc} Invalid ack frame: ackData.stage !== SyncStage.ack (E: 2e8b0a94b5954a66a6a1a7a0b3f5b7a1)`);
1369
1554
  }
1370
1555
  if (logalot) {
1371
- console.log(`${lc} ackData: ${pretty(ackData)} (I: 7f8e9d0a1b2c3d4e5f6g7h8i9j0k)`);
1556
+ console.log(`${lc} ackData: ${pretty(ackData)} (I: b817c5571c5e916fe8f90b892b3e8e26)`);
1372
1557
  }
1373
1558
  if (!sagaIbGib.data) {
1374
- throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: 385e389610282aa9c5dbe4083adbde26)`);
1559
+ throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: e3f2e8f162484859787651b85c011826)`);
1375
1560
  }
1376
1561
  // #region sanity/validation
1377
1562
  // 1. Check for Conflicts
@@ -2492,7 +2677,7 @@ export class SyncSagaCoordinator {
2492
2677
  }
2493
2678
  // Attach session keystone to saga frame via hard rel8n
2494
2679
  if (sessionIdentity) {
2495
- rel8ns.sessionKeystones = [getIbGibAddr({ ibGib: sessionIdentity })];
2680
+ rel8ns.sessionKeystone = [getIbGibAddr({ ibGib: sessionIdentity })];
2496
2681
  }
2497
2682
  const resNew = await createTimeline({
2498
2683
  space: localSpace,