@ledgerhq/revault-sdk 0.24.1 → 0.25.0
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/lib/bake.cjs +403 -64
- package/lib/bake.cjs.map +1 -1
- package/lib/bake.d.cts +40 -18
- package/lib/bake.d.ts +40 -18
- package/lib/bake.js +399 -60
- package/lib/bake.js.map +1 -1
- package/lib/{chunk-EBMIZ52H.cjs → chunk-DRMYBKL3.cjs} +11 -5
- package/lib/chunk-DRMYBKL3.cjs.map +1 -0
- package/lib/{chunk-XQ4BT4HB.js → chunk-PFZIW6UP.js} +11 -5
- package/lib/chunk-PFZIW6UP.js.map +1 -0
- package/lib/device.cjs +2 -2
- package/lib/device.js +1 -1
- package/lib/engine.cjs +28 -28
- package/lib/engine.js +1 -1
- package/package.json +19 -19
- package/lib/chunk-EBMIZ52H.cjs.map +0 -1
- package/lib/chunk-XQ4BT4HB.js.map +0 -1
package/lib/bake.cjs
CHANGED
|
@@ -299,6 +299,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
299
299
|
existingWhitelists,
|
|
300
300
|
existingPolicies,
|
|
301
301
|
existingAccounts,
|
|
302
|
+
existingEntities,
|
|
302
303
|
tradelinkNetworkBlueprint
|
|
303
304
|
] = await Promise.all([
|
|
304
305
|
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin1.client.users.list.query, { status: "ACTIVE" }),
|
|
@@ -306,6 +307,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
306
307
|
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin1.client.whitelists.list.query, { status: "ACTIVE" }),
|
|
307
308
|
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin1.client.policies.list.query, { isPrivate: false }),
|
|
308
309
|
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin1.client.accounts.list.query, { status: "ACTIVE" }),
|
|
310
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin1.client.entities.list.query, { status: "ACTIVE" }),
|
|
309
311
|
admin1.client.tradelink.getNetworkBlueprint.query()
|
|
310
312
|
]);
|
|
311
313
|
const tradelinkOrgExchangesByName = _lodash2.default.keyBy(_optionalChain([tradelinkNetworkBlueprint, 'optionalAccess', _7 => _7.exchanges]), "name");
|
|
@@ -364,19 +366,74 @@ async function bakeWorkspace(options, logger) {
|
|
|
364
366
|
await createAccount(account, workspace);
|
|
365
367
|
}
|
|
366
368
|
}
|
|
369
|
+
if (workspace.entities) {
|
|
370
|
+
logTitle("Entities");
|
|
371
|
+
for (const entity of workspace.entities) {
|
|
372
|
+
await createEntity(entity);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
async function editDomainObjectIfNeeded(params) {
|
|
376
|
+
const previousRequests = await admin1.client.requests.list.query({
|
|
377
|
+
type: params.requestTypes,
|
|
378
|
+
targetId: params.existingId,
|
|
379
|
+
state: "EXECUTED",
|
|
380
|
+
sortBy: "createdAt",
|
|
381
|
+
sortOrder: "desc",
|
|
382
|
+
pageSize: 1
|
|
383
|
+
});
|
|
384
|
+
if (_optionalChain([previousRequests, 'optionalAccess', _9 => _9.results]) && previousRequests.results.length > 0) {
|
|
385
|
+
const stateRequest = previousRequests.results[0];
|
|
386
|
+
_invariant2.default.call(void 0,
|
|
387
|
+
stateRequest && params.requestTypes.includes(stateRequest.type),
|
|
388
|
+
`State request should be a ${params.requestTypes[0]} or ${params.requestTypes[1]} request`
|
|
389
|
+
);
|
|
390
|
+
const lastData = params.extractLastData(stateRequest.data);
|
|
391
|
+
if (_lodash2.default.isEqual(stripUndefinedDeep(params.editData), stripUndefinedDeep(lastData))) {
|
|
392
|
+
logger.info(`[SKIPPED] ${params.entityType} "${params.entityName}" has not changed`);
|
|
393
|
+
return "skipped";
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
logStep(`Editing ${params.entityType.toLowerCase()} "${params.entityName}"...`);
|
|
397
|
+
await createAndApproveRequest(params.editInput, [admin1, admin2], logger);
|
|
398
|
+
logger.info(`[EDITED] ${params.entityType} "${params.entityName}" has been edited`);
|
|
399
|
+
return "edited";
|
|
400
|
+
}
|
|
367
401
|
async function createWhitelists(whitelists) {
|
|
368
402
|
for (const whitelist of whitelists) {
|
|
369
403
|
await createWhitelist(whitelist);
|
|
370
404
|
}
|
|
371
405
|
async function createWhitelist(whitelist) {
|
|
372
406
|
const existing = existingWhitelists.find((w) => w.name === whitelist.name);
|
|
407
|
+
const normalizeAddresses = (addresses) => addresses.map(({ destinationTags, ...rest }) => ({
|
|
408
|
+
...rest,
|
|
409
|
+
..._optionalChain([destinationTags, 'optionalAccess', _10 => _10.length]) ? { destinationTags } : {}
|
|
410
|
+
}));
|
|
411
|
+
const whitelistEditData = {
|
|
412
|
+
name: whitelist.name,
|
|
413
|
+
addresses: normalizeAddresses(whitelist.addresses)
|
|
414
|
+
};
|
|
373
415
|
if (existing) {
|
|
374
|
-
|
|
416
|
+
await editDomainObjectIfNeeded({
|
|
417
|
+
entityType: "Whitelist",
|
|
418
|
+
entityName: whitelist.name,
|
|
419
|
+
existingId: existing.id,
|
|
420
|
+
editInput: {
|
|
421
|
+
type: "EDIT_WHITELIST",
|
|
422
|
+
targetId: existing.id,
|
|
423
|
+
data: { name: whitelist.name, addresses: whitelist.addresses }
|
|
424
|
+
},
|
|
425
|
+
editData: whitelistEditData,
|
|
426
|
+
requestTypes: ["CREATE_WHITELIST", "EDIT_WHITELIST"],
|
|
427
|
+
extractLastData: (data) => ({
|
|
428
|
+
name: data.name,
|
|
429
|
+
addresses: normalizeAddresses(data.addresses)
|
|
430
|
+
})
|
|
431
|
+
});
|
|
375
432
|
return;
|
|
376
433
|
}
|
|
377
434
|
const input = {
|
|
378
435
|
type: "CREATE_WHITELIST",
|
|
379
|
-
data: whitelist
|
|
436
|
+
data: { ...whitelist, description: _nullishCoalesce(whitelist.description, () => ( null)) }
|
|
380
437
|
};
|
|
381
438
|
const req = await createAndApproveRequest(input, [admin1, admin2], logger);
|
|
382
439
|
logSubStep(`Whitelist "${whitelist.name}" has been created`);
|
|
@@ -400,7 +457,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
400
457
|
};
|
|
401
458
|
}),
|
|
402
459
|
threshold: rule.threshold,
|
|
403
|
-
whitelistIds: _optionalChain([rule, 'access',
|
|
460
|
+
whitelistIds: _optionalChain([rule, 'access', _11 => _11.whitelistNames, 'optionalAccess', _12 => _12.map, 'call', _13 => _13(whitelistIdFromName)])
|
|
404
461
|
};
|
|
405
462
|
}
|
|
406
463
|
function rawSigningRuleFromManifest(rule) {
|
|
@@ -414,7 +471,6 @@ async function bakeWorkspace(options, logger) {
|
|
|
414
471
|
};
|
|
415
472
|
}
|
|
416
473
|
async function createAccount(account, workspace2) {
|
|
417
|
-
let req = null;
|
|
418
474
|
const existing = existingAccounts.find(
|
|
419
475
|
(a) => a.currency === account.currency && a.index === account.index && (_nullishCoalesce(a.contractAddress, () => ( null))) === (_nullishCoalesce(account.contractAddress, () => ( null)))
|
|
420
476
|
);
|
|
@@ -444,58 +500,41 @@ async function bakeWorkspace(options, logger) {
|
|
|
444
500
|
index: account.index,
|
|
445
501
|
governance
|
|
446
502
|
};
|
|
447
|
-
const createInput = {
|
|
448
|
-
type: "CREATE_ACCOUNT",
|
|
449
|
-
data: accountData
|
|
450
|
-
};
|
|
451
503
|
if (existing) {
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
sortBy: "createdAt",
|
|
462
|
-
sortOrder: "desc"
|
|
504
|
+
const editData = { name: accountData.name, governance };
|
|
505
|
+
const result = await editDomainObjectIfNeeded({
|
|
506
|
+
entityType: "Account",
|
|
507
|
+
entityName: account.name,
|
|
508
|
+
existingId: existing.id,
|
|
509
|
+
editInput: { type: "EDIT_ACCOUNT", targetId: existing.id, data: editData },
|
|
510
|
+
editData,
|
|
511
|
+
requestTypes: ["CREATE_ACCOUNT", "EDIT_ACCOUNT"],
|
|
512
|
+
extractLastData: (data) => ({ name: data.name, governance: data.governance })
|
|
463
513
|
});
|
|
464
|
-
if (
|
|
465
|
-
|
|
466
|
-
_invariant2.default.call(void 0,
|
|
467
|
-
stateRequest && (stateRequest.type === "EDIT_ACCOUNT" || stateRequest.type === "CREATE_ACCOUNT"),
|
|
468
|
-
"State request should be an edit account request"
|
|
469
|
-
);
|
|
470
|
-
if (_lodash2.default.isEqual(
|
|
471
|
-
stripUndefinedDeep(accountData.governance),
|
|
472
|
-
stripUndefinedDeep(stateRequest.data.governance)
|
|
473
|
-
) && accountData.name === stateRequest.data.name) {
|
|
474
|
-
logger.info(`[SKIPPED] Account "${account.name}" has not changed`);
|
|
475
|
-
await activateHederaAccount(account, workspace2, existing.id);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
req = await createAndApproveRequest(editInput, [admin1, admin2], logger);
|
|
479
|
-
logger.info(`[EDITED] Account "${account.name}" has been edited`);
|
|
480
|
-
return;
|
|
514
|
+
if (result === "skipped") {
|
|
515
|
+
await activateHederaAccount(account, workspace2, existing.id);
|
|
481
516
|
}
|
|
482
|
-
|
|
483
|
-
logStep(`Creating account "${account.name}"`);
|
|
484
|
-
req = await createAndApproveRequest(createInput, [admin1, admin2], logger);
|
|
485
|
-
const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId });
|
|
486
|
-
existingAccounts.push(createdAccount);
|
|
517
|
+
return;
|
|
487
518
|
}
|
|
488
|
-
|
|
519
|
+
logStep(`Creating account "${account.name}"`);
|
|
520
|
+
const createInput = {
|
|
521
|
+
type: "CREATE_ACCOUNT",
|
|
522
|
+
data: accountData
|
|
523
|
+
};
|
|
524
|
+
const req = await createAndApproveRequest(createInput, [admin1, admin2], logger);
|
|
525
|
+
const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId });
|
|
526
|
+
existingAccounts.push(createdAccount);
|
|
527
|
+
if (account.governance.type === "TRADELINK") {
|
|
489
528
|
logStep(`Activating tradelink account "${account.name}"`);
|
|
490
529
|
const assetManagerId = assetManagerIdFromName(account.governance.assetManager);
|
|
491
|
-
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess',
|
|
530
|
+
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess', _14 => _14.assetManagers, 'access', _15 => _15.find, 'call', _16 => _16(
|
|
492
531
|
(assetManager2) => assetManager2.id === assetManagerId
|
|
493
532
|
)]);
|
|
494
533
|
_invariant2.default.call(void 0, assetManager, `Asset manager for account exists`);
|
|
495
534
|
const loggedAssetManagerOperators = await Promise.all(
|
|
496
535
|
assetManager.groups.flatMap(
|
|
497
536
|
({ quorum, userIds }) => userIds.slice(0, quorum).map((userId) => {
|
|
498
|
-
const deviceIndex = _optionalChain([usersWithDeviceIndex, 'access',
|
|
537
|
+
const deviceIndex = _optionalChain([usersWithDeviceIndex, 'access', _17 => _17.find, 'call', _18 => _18((o) => o.user.id === userId), 'optionalAccess', _19 => _19.deviceIndex]);
|
|
499
538
|
return workspaceEngine.withDeviceIndex(deviceIndex).login();
|
|
500
539
|
})
|
|
501
540
|
)
|
|
@@ -506,7 +545,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
506
545
|
logger
|
|
507
546
|
);
|
|
508
547
|
}
|
|
509
|
-
if (
|
|
548
|
+
if (req.targetId) {
|
|
510
549
|
await activateHederaAccount(account, workspace2, req.targetId);
|
|
511
550
|
}
|
|
512
551
|
logSubStep(`Account ${account.name} has been created`);
|
|
@@ -515,7 +554,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
515
554
|
if (account.currency === "hedera" && account.contractAddress === void 0 && workspace2.hederaData && accountId) {
|
|
516
555
|
const salt = engine.__options.salt;
|
|
517
556
|
const hederaAccountsForSalt = workspace2.hederaData[salt];
|
|
518
|
-
const hederaAccountData = _optionalChain([hederaAccountsForSalt, 'optionalAccess',
|
|
557
|
+
const hederaAccountData = _optionalChain([hederaAccountsForSalt, 'optionalAccess', _20 => _20.find, 'call', _21 => _21(
|
|
519
558
|
(h) => h.index === account.index && h.activate
|
|
520
559
|
)]);
|
|
521
560
|
if (hederaAccountData) {
|
|
@@ -601,21 +640,30 @@ async function bakeWorkspace(options, logger) {
|
|
|
601
640
|
}
|
|
602
641
|
async function createGroup(group) {
|
|
603
642
|
const existing = existingGroups.find((g) => g.name === group.name);
|
|
643
|
+
const members = group.members.map(userIdFromDeviceIndexOrName);
|
|
644
|
+
const groupData = {
|
|
645
|
+
name: group.name,
|
|
646
|
+
description: "",
|
|
647
|
+
members
|
|
648
|
+
};
|
|
604
649
|
if (existing) {
|
|
605
|
-
|
|
650
|
+
await editDomainObjectIfNeeded({
|
|
651
|
+
entityType: "Group",
|
|
652
|
+
entityName: group.name,
|
|
653
|
+
existingId: existing.id,
|
|
654
|
+
editInput: { type: "EDIT_GROUP", targetId: existing.id, data: groupData },
|
|
655
|
+
editData: groupData,
|
|
656
|
+
requestTypes: ["CREATE_GROUP", "EDIT_GROUP"],
|
|
657
|
+
extractLastData: (data) => ({ ...data, description: _nullishCoalesce(data.description, () => ( "")) })
|
|
658
|
+
});
|
|
606
659
|
return;
|
|
607
660
|
}
|
|
608
661
|
logStep(`Creating group ${group.name}...`);
|
|
609
|
-
const members = group.members.map(userIdFromDeviceIndexOrName);
|
|
610
662
|
logSubStep("Creating request...");
|
|
611
663
|
let request = await admin1.client.requests.create.mutate({
|
|
612
664
|
request: {
|
|
613
665
|
type: "CREATE_GROUP",
|
|
614
|
-
data:
|
|
615
|
-
name: group.name,
|
|
616
|
-
description: "",
|
|
617
|
-
members
|
|
618
|
-
}
|
|
666
|
+
data: groupData
|
|
619
667
|
}
|
|
620
668
|
});
|
|
621
669
|
request = await approveRequest(request, [admin1, admin2], logger);
|
|
@@ -625,8 +673,25 @@ async function bakeWorkspace(options, logger) {
|
|
|
625
673
|
}
|
|
626
674
|
async function createPolicy(policy) {
|
|
627
675
|
const existing = existingPolicies.find((p) => p.name === policy.name);
|
|
676
|
+
const policyEditData = {
|
|
677
|
+
name: policy.name,
|
|
678
|
+
description: "",
|
|
679
|
+
govRules: policy.rules.map(govRuleFromManifest)
|
|
680
|
+
};
|
|
628
681
|
if (existing) {
|
|
629
|
-
|
|
682
|
+
await editDomainObjectIfNeeded({
|
|
683
|
+
entityType: "Policy",
|
|
684
|
+
entityName: policy.name,
|
|
685
|
+
existingId: existing.id,
|
|
686
|
+
editInput: { type: "EDIT_POLICY", targetId: existing.id, data: policyEditData },
|
|
687
|
+
editData: policyEditData,
|
|
688
|
+
requestTypes: ["CREATE_POLICY", "EDIT_POLICY"],
|
|
689
|
+
extractLastData: (data) => ({
|
|
690
|
+
name: data.name,
|
|
691
|
+
description: _nullishCoalesce(data.description, () => ( "")),
|
|
692
|
+
govRules: data.govRules
|
|
693
|
+
})
|
|
694
|
+
});
|
|
630
695
|
return;
|
|
631
696
|
}
|
|
632
697
|
logStep(`Creating policy ${policy.name}...`);
|
|
@@ -635,10 +700,8 @@ async function bakeWorkspace(options, logger) {
|
|
|
635
700
|
request: {
|
|
636
701
|
type: "CREATE_POLICY",
|
|
637
702
|
data: {
|
|
638
|
-
|
|
639
|
-
currency: policy.currency
|
|
640
|
-
description: "",
|
|
641
|
-
govRules: policy.rules.map(govRuleFromManifest)
|
|
703
|
+
...policyEditData,
|
|
704
|
+
currency: policy.currency
|
|
642
705
|
}
|
|
643
706
|
}
|
|
644
707
|
});
|
|
@@ -662,6 +725,37 @@ async function bakeWorkspace(options, logger) {
|
|
|
662
725
|
await createAndApproveRequest(input, [admin1, admin2], logger);
|
|
663
726
|
logSubStep(`Workspace rule for "${permission}" has been edited`);
|
|
664
727
|
}
|
|
728
|
+
async function createEntity(entity) {
|
|
729
|
+
const existing = existingEntities.find((e) => e.name === entity.name);
|
|
730
|
+
const accountIds = (_nullishCoalesce(entity.accounts, () => ( []))).map(accountIdFromName);
|
|
731
|
+
const memberIds = (_nullishCoalesce(entity.members, () => ( []))).map(userIdFromUserName);
|
|
732
|
+
const entityEditData = { name: entity.name, accountIds, memberIds };
|
|
733
|
+
if (existing) {
|
|
734
|
+
await editDomainObjectIfNeeded({
|
|
735
|
+
entityType: "Entity",
|
|
736
|
+
entityName: entity.name,
|
|
737
|
+
existingId: existing.id,
|
|
738
|
+
editInput: { type: "EDIT_ENTITY", targetId: existing.id, data: entityEditData },
|
|
739
|
+
editData: entityEditData,
|
|
740
|
+
requestTypes: ["CREATE_ENTITY", "EDIT_ENTITY"],
|
|
741
|
+
extractLastData: (data) => ({
|
|
742
|
+
name: data.name,
|
|
743
|
+
accountIds: data.accountIds,
|
|
744
|
+
memberIds: data.memberIds
|
|
745
|
+
})
|
|
746
|
+
});
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
logStep(`Creating entity "${entity.name}"...`);
|
|
750
|
+
const input = {
|
|
751
|
+
type: "CREATE_ENTITY",
|
|
752
|
+
data: entityEditData
|
|
753
|
+
};
|
|
754
|
+
const request = await createAndApproveRequest(input, [admin1, admin2], logger);
|
|
755
|
+
logSubStep(`Entity "${entity.name}" has been created`);
|
|
756
|
+
const createdEntity = await admin1.client.entities.findById.query({ id: request.targetId });
|
|
757
|
+
existingEntities.push(createdEntity);
|
|
758
|
+
}
|
|
665
759
|
async function createTradelink(tradelink) {
|
|
666
760
|
if (tradelink.custodian) {
|
|
667
761
|
if (existingTradelinkNetwork === null) {
|
|
@@ -822,20 +916,25 @@ async function bakeWorkspace(options, logger) {
|
|
|
822
916
|
_invariant2.default.call(void 0, whitelist, `Whitelist ${whitelistName} not found`);
|
|
823
917
|
return whitelist.id;
|
|
824
918
|
}
|
|
919
|
+
function accountIdFromName(accountName) {
|
|
920
|
+
const account = existingAccounts.find((a) => a.name === accountName);
|
|
921
|
+
_invariant2.default.call(void 0, account, `Account "${accountName}" not found`);
|
|
922
|
+
return account.id;
|
|
923
|
+
}
|
|
825
924
|
function assetManagerIdFromName(assetManagerName) {
|
|
826
925
|
const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];
|
|
827
926
|
_invariant2.default.call(void 0,
|
|
828
927
|
orgAssetManager,
|
|
829
928
|
`Can't find Tradelink organization asset manager ${assetManagerName}`
|
|
830
929
|
);
|
|
831
|
-
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess',
|
|
930
|
+
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess', _22 => _22.assetManagers, 'access', _23 => _23.find, 'call', _24 => _24(
|
|
832
931
|
(assetManager2) => assetManager2.tradelinkId === orgAssetManager.tradelinkId
|
|
833
932
|
)]);
|
|
834
933
|
_invariant2.default.call(void 0, assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);
|
|
835
934
|
return assetManager.id;
|
|
836
935
|
}
|
|
837
936
|
function exchangeIdFromName(exchangeName) {
|
|
838
|
-
const exchange = _optionalChain([existingTradelinkNetwork, 'optionalAccess',
|
|
937
|
+
const exchange = _optionalChain([existingTradelinkNetwork, 'optionalAccess', _25 => _25.exchanges, 'access', _26 => _26.find, 'call', _27 => _27((exchange2) => {
|
|
839
938
|
const orgExchange = tradelinkOrgExchangesByName[exchangeName];
|
|
840
939
|
_invariant2.default.call(void 0, orgExchange, `Can't find Tradelink organization exchange ${exchange2.tradelinkId}`);
|
|
841
940
|
return orgExchange.name === exchangeName;
|
|
@@ -854,6 +953,239 @@ async function bakeWorkspace(options, logger) {
|
|
|
854
953
|
}
|
|
855
954
|
}
|
|
856
955
|
|
|
956
|
+
// src/bake/recipe-workspace.ts
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
async function recipeWorkspace(options, logger) {
|
|
960
|
+
const { engine, workspaceName } = options;
|
|
961
|
+
const workspaceEngine = engine.withWorkspace(workspaceName);
|
|
962
|
+
const findDeviceIndex = _chunkLH4QQXUHcjs.createDeviceIndexResolver.call(void 0, workspaceEngine);
|
|
963
|
+
logger.info("Authenticating with admin...");
|
|
964
|
+
const admin = await workspaceEngine.withDeviceIndex(4).login();
|
|
965
|
+
logger.info("Fetching existing data...");
|
|
966
|
+
const [
|
|
967
|
+
existingUsers,
|
|
968
|
+
existingGroups,
|
|
969
|
+
existingWhitelists,
|
|
970
|
+
publicPolicies,
|
|
971
|
+
privatePolicies,
|
|
972
|
+
existingAccounts,
|
|
973
|
+
existingEntities,
|
|
974
|
+
existingWorkspaceRules
|
|
975
|
+
] = await Promise.all([
|
|
976
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.users.list.query, { status: "ACTIVE" }),
|
|
977
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.groups.list.query, { status: "ACTIVE" }),
|
|
978
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.whitelists.list.query, { status: "ACTIVE" }),
|
|
979
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.policies.list.query, { isPrivate: false }),
|
|
980
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.policies.list.query, { isPrivate: true }),
|
|
981
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.accounts.list.query, { status: "ACTIVE" }),
|
|
982
|
+
_chunkLH4QQXUHcjs.fetchAll.call(void 0, admin.client.entities.list.query, { status: "ACTIVE" }),
|
|
983
|
+
admin.client.governance.listWorkspaceRules.query()
|
|
984
|
+
]);
|
|
985
|
+
const existingPolicies = [...publicPolicies, ...privatePolicies];
|
|
986
|
+
const existingPsdUsers = existingUsers.filter((user) => user.deviceType === "PSD");
|
|
987
|
+
const existingApiUsers = existingUsers.filter((user) => user.deviceType === "API");
|
|
988
|
+
logger.info("Resolving device indexes...");
|
|
989
|
+
const psdUsersWithIndex = await resolveDevicesIndexes(existingPsdUsers);
|
|
990
|
+
logger.info("Reading users...");
|
|
991
|
+
const adminIndexes = psdUsersWithIndex.filter((u) => u.user.role === "ADMIN").map((u) => u.deviceIndex);
|
|
992
|
+
const operatorIndexes = psdUsersWithIndex.filter((u) => u.user.role === "OPERATOR").map((u) => u.deviceIndex);
|
|
993
|
+
const apiUsers = existingApiUsers.map((user) => {
|
|
994
|
+
const role = _tspattern.match.call(void 0, user.role).with("ADMIN", "OPERATOR", (role2) => role2).with("READ_ONLY_API_KEY", (role2) => {
|
|
995
|
+
throw new Error(`Unexpected API user role "${role2}" for user ${user.name}`);
|
|
996
|
+
}).exhaustive();
|
|
997
|
+
return {
|
|
998
|
+
name: user.name,
|
|
999
|
+
role,
|
|
1000
|
+
pubKey: user.pubKey,
|
|
1001
|
+
viewAll: user.legacyViewAll
|
|
1002
|
+
};
|
|
1003
|
+
});
|
|
1004
|
+
logger.info("Reading groups...");
|
|
1005
|
+
const groups = existingGroups.map((group) => ({
|
|
1006
|
+
name: group.name,
|
|
1007
|
+
members: group.members.map((member) => resolveUserIdentifier(member.id))
|
|
1008
|
+
}));
|
|
1009
|
+
logger.info("Reading whitelists...");
|
|
1010
|
+
const whitelists = existingWhitelists.map((whitelist) => ({
|
|
1011
|
+
name: whitelist.name,
|
|
1012
|
+
description: _nullishCoalesce(whitelist.description, () => ( void 0)),
|
|
1013
|
+
type: "TRANSACTION",
|
|
1014
|
+
addresses: whitelist.addresses.map((addr) => ({
|
|
1015
|
+
name: addr.name,
|
|
1016
|
+
currency: addr.currency,
|
|
1017
|
+
address: addr.address,
|
|
1018
|
+
..._optionalChain([addr, 'access', _28 => _28.destinationTags, 'optionalAccess', _29 => _29.length]) ? { destinationTags: addr.destinationTags } : {}
|
|
1019
|
+
}))
|
|
1020
|
+
}));
|
|
1021
|
+
logger.info("Reading policies...");
|
|
1022
|
+
const policies = publicPolicies.map((policy) => ({
|
|
1023
|
+
name: policy.name,
|
|
1024
|
+
currency: policy.currency,
|
|
1025
|
+
rules: policy.rules.map(govRuleToManifest)
|
|
1026
|
+
}));
|
|
1027
|
+
logger.info("Reading accounts...");
|
|
1028
|
+
const accounts = existingAccounts.map((account) => {
|
|
1029
|
+
const governance = _tspattern.match.call(void 0, account.governance).with({ type: "CLASSIC" }, (gov) => {
|
|
1030
|
+
const policy = existingPolicies.find((p) => p.id === gov.policyId);
|
|
1031
|
+
_invariant2.default.call(void 0, policy, `Policy ${gov.policyId} not found for account ${account.name}`);
|
|
1032
|
+
return policy.isPrivate ? {
|
|
1033
|
+
type: "CLASSIC",
|
|
1034
|
+
rules: policy.rules.map(govRuleToManifest)
|
|
1035
|
+
} : {
|
|
1036
|
+
type: "POLICY",
|
|
1037
|
+
policy: policy.name
|
|
1038
|
+
};
|
|
1039
|
+
}).with({ type: "RAW_SIGNING" }, (gov) => {
|
|
1040
|
+
const policy = existingPolicies.find((p) => p.id === gov.policyId);
|
|
1041
|
+
_invariant2.default.call(void 0, policy, `Policy ${gov.policyId} not found for account ${account.name}`);
|
|
1042
|
+
return {
|
|
1043
|
+
type: "RAW_SIGNING",
|
|
1044
|
+
rules: policy.rules.map((rule) => ({
|
|
1045
|
+
type: "SIGN_DIGESTS",
|
|
1046
|
+
steps: rule.reviewSteps.map((step) => {
|
|
1047
|
+
_invariant2.default.call(void 0, "userIds" in step, "RAW_SIGNING rules only support user steps");
|
|
1048
|
+
return {
|
|
1049
|
+
quorum: step.quorum,
|
|
1050
|
+
members: step.userIds.map(resolveUserToDeviceIndexOrName)
|
|
1051
|
+
};
|
|
1052
|
+
})
|
|
1053
|
+
}))
|
|
1054
|
+
};
|
|
1055
|
+
}).with({ type: "TRADELINK" }, (gov) => ({
|
|
1056
|
+
type: "TRADELINK",
|
|
1057
|
+
assetManager: resolveAssetManagerName(gov.assetManagerId),
|
|
1058
|
+
exchanges: gov.exchangeConfigs.map((exchangeConfig) => ({
|
|
1059
|
+
name: resolveExchangeName(exchangeConfig.exchangeId),
|
|
1060
|
+
...exchangeConfig.repledgeAuthorized ? { repledgeAuthorized: true } : {},
|
|
1061
|
+
...exchangeConfig.needsAssetManagerApprovalForSettlements ? { needsAssetManagerApprovalForSettlements: true } : {}
|
|
1062
|
+
}))
|
|
1063
|
+
})).exhaustive();
|
|
1064
|
+
return {
|
|
1065
|
+
name: account.name,
|
|
1066
|
+
currency: account.currency,
|
|
1067
|
+
index: account.index,
|
|
1068
|
+
...account.contractAddress ? { contractAddress: account.contractAddress } : {},
|
|
1069
|
+
...account.tokenIdentifier ? { tokenIdentifier: account.tokenIdentifier } : {},
|
|
1070
|
+
governance
|
|
1071
|
+
};
|
|
1072
|
+
});
|
|
1073
|
+
logger.info("Reading entities...");
|
|
1074
|
+
const entities = existingEntities.map((entity) => ({
|
|
1075
|
+
name: entity.name,
|
|
1076
|
+
...entity.accountIds.length > 0 ? { accounts: entity.accountIds.map(accountNameFromId) } : {},
|
|
1077
|
+
...entity.memberIds.length > 0 ? { members: entity.memberIds.map(userNameFromId) } : {}
|
|
1078
|
+
}));
|
|
1079
|
+
logger.info("Reading workspace rules...");
|
|
1080
|
+
const workspaceRules = existingWorkspaceRules.results.filter((rule) => rule.permission !== "ROOT").map((rule) => {
|
|
1081
|
+
_invariant2.default.call(void 0,
|
|
1082
|
+
rule.reviewSteps.length === 1,
|
|
1083
|
+
"Only one review step supported for workspace rules in manifest"
|
|
1084
|
+
);
|
|
1085
|
+
const step = rule.reviewSteps[0];
|
|
1086
|
+
const quorum = step.quorum;
|
|
1087
|
+
_invariant2.default.call(void 0, rule.permission !== "ROOT", "filtered out");
|
|
1088
|
+
return {
|
|
1089
|
+
permission: rule.permission,
|
|
1090
|
+
quorum,
|
|
1091
|
+
members: step.userIds.map(resolveUserToDeviceIndexOrName)
|
|
1092
|
+
};
|
|
1093
|
+
});
|
|
1094
|
+
const workspace = {
|
|
1095
|
+
users: {
|
|
1096
|
+
...adminIndexes.length > 0 ? { admins: adminIndexes } : {},
|
|
1097
|
+
...operatorIndexes.length > 0 ? { operators: operatorIndexes } : {},
|
|
1098
|
+
...apiUsers.length > 0 ? { api: apiUsers } : {}
|
|
1099
|
+
},
|
|
1100
|
+
...groups.length > 0 ? { groups } : {},
|
|
1101
|
+
...whitelists.length > 0 ? { whitelists } : {},
|
|
1102
|
+
...policies.length > 0 ? { policies } : {},
|
|
1103
|
+
...accounts.length > 0 ? { accounts } : {},
|
|
1104
|
+
...entities.length > 0 ? { entities } : {},
|
|
1105
|
+
...workspaceRules.length > 0 ? { workspaceRules } : {}
|
|
1106
|
+
};
|
|
1107
|
+
logger.info("Recipe completed");
|
|
1108
|
+
return workspace;
|
|
1109
|
+
async function resolveDevicesIndexes(users) {
|
|
1110
|
+
const result = [];
|
|
1111
|
+
for (const user of users) {
|
|
1112
|
+
_invariant2.default.call(void 0, user.deviceUserId, `User ${user.id} does not have any device user id`);
|
|
1113
|
+
const deviceIndex = await findDeviceIndex(user.deviceUserId);
|
|
1114
|
+
result.push({ user, deviceIndex });
|
|
1115
|
+
}
|
|
1116
|
+
return result;
|
|
1117
|
+
}
|
|
1118
|
+
function resolveUserIdentifier(userId) {
|
|
1119
|
+
const psdUser = psdUsersWithIndex.find((u) => u.user.id === userId);
|
|
1120
|
+
if (psdUser) return psdUser.deviceIndex;
|
|
1121
|
+
const apiUser = existingApiUsers.find((u) => u.id === userId);
|
|
1122
|
+
if (apiUser) return apiUser.name;
|
|
1123
|
+
throw new Error(`User ${userId} not found`);
|
|
1124
|
+
}
|
|
1125
|
+
function resolveUserToDeviceIndexOrName(userId) {
|
|
1126
|
+
return resolveUserIdentifier(userId);
|
|
1127
|
+
}
|
|
1128
|
+
function validateGovernanceRuleType(value) {
|
|
1129
|
+
_invariant2.default.call(void 0,
|
|
1130
|
+
["SEND", "STAKE", "DEPLOY_CONTRACT", "EXECUTE_CONTRACT", "SIGN_MESSAGE", "RECEIVE"].includes(
|
|
1131
|
+
value
|
|
1132
|
+
),
|
|
1133
|
+
"Unexpected governance rule type: " + value
|
|
1134
|
+
);
|
|
1135
|
+
return value;
|
|
1136
|
+
}
|
|
1137
|
+
function govRuleToManifest(rule) {
|
|
1138
|
+
const operationType = validateGovernanceRuleType(rule.operationType);
|
|
1139
|
+
const threshold = rule.threshold !== void 0 && (rule.threshold.min !== null || rule.threshold.max !== null) ? { threshold: { min: rule.threshold.min, max: rule.threshold.max } } : {};
|
|
1140
|
+
return {
|
|
1141
|
+
type: operationType,
|
|
1142
|
+
steps: rule.reviewSteps.map((step) => {
|
|
1143
|
+
if ("groupId" in step) {
|
|
1144
|
+
const group = existingGroups.find((g) => g.id === step.groupId);
|
|
1145
|
+
_invariant2.default.call(void 0, group, `Group ${step.groupId} not found`);
|
|
1146
|
+
return { quorum: step.quorum, group: group.name };
|
|
1147
|
+
}
|
|
1148
|
+
return {
|
|
1149
|
+
quorum: step.quorum,
|
|
1150
|
+
members: step.userIds.map(resolveUserToDeviceIndexOrName)
|
|
1151
|
+
};
|
|
1152
|
+
}),
|
|
1153
|
+
...threshold,
|
|
1154
|
+
...rule.whitelistIds && rule.whitelistIds.length > 0 ? { whitelistNames: rule.whitelistIds.map(whitelistNameFromId) } : {}
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
function whitelistNameFromId(whitelistId) {
|
|
1158
|
+
const whitelist = existingWhitelists.find((w) => w.id === whitelistId);
|
|
1159
|
+
_invariant2.default.call(void 0, whitelist, `Whitelist ${whitelistId} not found`);
|
|
1160
|
+
return whitelist.name;
|
|
1161
|
+
}
|
|
1162
|
+
function accountNameFromId(accountId) {
|
|
1163
|
+
const account = existingAccounts.find((a) => a.id === accountId);
|
|
1164
|
+
_invariant2.default.call(void 0, account, `Account ${accountId} not found`);
|
|
1165
|
+
return account.name;
|
|
1166
|
+
}
|
|
1167
|
+
function userNameFromId(userId) {
|
|
1168
|
+
const user = existingApiUsers.find((u) => u.id === userId);
|
|
1169
|
+
_invariant2.default.call(void 0, user, `API user ${userId} not found`);
|
|
1170
|
+
return user.name;
|
|
1171
|
+
}
|
|
1172
|
+
function resolveAssetManagerName(assetManagerId) {
|
|
1173
|
+
return assetManagerId;
|
|
1174
|
+
}
|
|
1175
|
+
function resolveExchangeName(exchangeId) {
|
|
1176
|
+
return exchangeId;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// src/bake/recipe.ts
|
|
1181
|
+
async function recipeManifest(options, logger) {
|
|
1182
|
+
const workspace = await recipeWorkspace(options, logger);
|
|
1183
|
+
return {
|
|
1184
|
+
manifestVersion: 2,
|
|
1185
|
+
workspace
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
|
|
857
1189
|
// src/bake/types.ts
|
|
858
1190
|
var _zod = require('zod'); var _zod2 = _interopRequireDefault(_zod);
|
|
859
1191
|
var zManifestUser = _zod2.default.number().meta({ description: "User device index" });
|
|
@@ -878,7 +1210,7 @@ var zManifestWhitelistAddress = _zod2.default.object({
|
|
|
878
1210
|
}).strict();
|
|
879
1211
|
var zManifestWhitelist = _zod2.default.object({
|
|
880
1212
|
name: _zod2.default.string().meta({ description: "Whitelist name" }),
|
|
881
|
-
description: _zod2.default.string().optional().
|
|
1213
|
+
description: _zod2.default.string().optional().meta({ description: "Whitelist description" }),
|
|
882
1214
|
type: _zod2.default.enum(["TRANSACTION", "SMART_CONTRACT"]).optional().default("TRANSACTION").meta({ description: "Whitelist type" }),
|
|
883
1215
|
addresses: _zod2.default.array(zManifestWhitelistAddress).meta({ description: "Whitelist addresses" })
|
|
884
1216
|
}).strict().meta({ description: "Whitelist" });
|
|
@@ -907,8 +1239,8 @@ var zManifestGovernanceRule = _zod2.default.object({
|
|
|
907
1239
|
]),
|
|
908
1240
|
steps: _zod2.default.array(zManifestGovernanceStep).min(1),
|
|
909
1241
|
threshold: _zod2.default.object({
|
|
910
|
-
min: _zod2.default.string(),
|
|
911
|
-
max: _zod2.default.string()
|
|
1242
|
+
min: _zod2.default.string().nullable(),
|
|
1243
|
+
max: _zod2.default.string().nullable()
|
|
912
1244
|
}).optional(),
|
|
913
1245
|
whitelistNames: _zod2.default.array(_zod2.default.string()).optional()
|
|
914
1246
|
}).strict();
|
|
@@ -957,6 +1289,11 @@ var zManifestAccount = _zod2.default.object({
|
|
|
957
1289
|
tokenIdentifier: _zod2.default.string().optional(),
|
|
958
1290
|
governance: zManifestAccountGovernance
|
|
959
1291
|
}).strict();
|
|
1292
|
+
var zManifestEntity = _zod2.default.object({
|
|
1293
|
+
name: _zod2.default.string().min(1).max(19).meta({ description: "Entity name" }),
|
|
1294
|
+
accounts: _zod2.default.array(_zod2.default.string()).optional().meta({ description: "Account names to include in this entity" }),
|
|
1295
|
+
members: _zod2.default.array(_zod2.default.string()).optional().meta({ description: "API operator names to include in this entity" })
|
|
1296
|
+
}).strict().meta({ description: "Entity" });
|
|
960
1297
|
var zManifestHederaData = _zod2.default.object({
|
|
961
1298
|
index: _zod2.default.number(),
|
|
962
1299
|
onChainId: _zod2.default.string(),
|
|
@@ -1015,6 +1352,7 @@ var zManifestWorkspace = _zod2.default.object({
|
|
|
1015
1352
|
whitelists: _zod2.default.array(zManifestWhitelist).optional(),
|
|
1016
1353
|
policies: _zod2.default.array(zManifestPolicy).optional(),
|
|
1017
1354
|
accounts: _zod2.default.array(zManifestAccount).optional(),
|
|
1355
|
+
entities: _zod2.default.array(zManifestEntity).optional(),
|
|
1018
1356
|
hederaData: _zod2.default.record(_zod2.default.string(), _zod2.default.array(zManifestHederaData)).optional(),
|
|
1019
1357
|
pledges: _zod2.default.array(zManifestPledgeAdjustment).optional(),
|
|
1020
1358
|
workspaceRules: _zod2.default.array(zManifestWorkspaceRule).optional()
|
|
@@ -1073,7 +1411,8 @@ async function bakeManifest(options, logger) {
|
|
|
1073
1411
|
|
|
1074
1412
|
|
|
1075
1413
|
|
|
1076
|
-
|
|
1414
|
+
|
|
1415
|
+
exports.bakeManifest = bakeManifest; exports.bakePledgeAdjustment = bakePledgeAdjustment; exports.createAndApproveRequest = createAndApproveRequest; exports.recipeManifest = recipeManifest; exports.zManifest = zManifest; exports.zManifestPolicy = zManifestPolicy;
|
|
1077
1416
|
/* v8 ignore else - TODO bake empty tradelink org -- @preserve */
|
|
1078
1417
|
/* v8 ignore else -- @preserve */
|
|
1079
1418
|
//# sourceMappingURL=bake.cjs.map
|