@ledgerhq/revault-sdk 0.21.11 → 0.22.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 +25 -36
- package/lib/bake.cjs.map +1 -1
- package/lib/bake.d.cts +3 -0
- package/lib/bake.d.ts +3 -0
- package/lib/bake.js +22 -33
- package/lib/bake.js.map +1 -1
- package/package.json +11 -10
package/lib/bake.cjs
CHANGED
|
@@ -284,13 +284,9 @@ async function bakeWorkspace(options, logger) {
|
|
|
284
284
|
if (workspace.accounts) {
|
|
285
285
|
logTitle("Accounts");
|
|
286
286
|
for (const account of workspace.accounts) {
|
|
287
|
-
await createAccount(account);
|
|
287
|
+
await createAccount(account, workspace);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
|
-
if (workspace.hederaData) {
|
|
291
|
-
logTitle("Activate Hedera Accounts");
|
|
292
|
-
await activateHederaAccount(workspace.hederaData);
|
|
293
|
-
}
|
|
294
290
|
async function createWhitelists(whitelists) {
|
|
295
291
|
for (const whitelist of whitelists) {
|
|
296
292
|
await createWhitelist(whitelist);
|
|
@@ -330,7 +326,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
330
326
|
whitelistIds: _optionalChain([rule, 'access', _5 => _5.whitelistNames, 'optionalAccess', _6 => _6.map, 'call', _7 => _7(whitelistIdFromName)])
|
|
331
327
|
};
|
|
332
328
|
}
|
|
333
|
-
async function createAccount(account) {
|
|
329
|
+
async function createAccount(account, workspace2) {
|
|
334
330
|
let req = null;
|
|
335
331
|
const existing = existingAccounts.find(
|
|
336
332
|
(a) => a.currency === account.currency && a.index === account.index && (_nullishCoalesce(a.contractAddress, () => ( null))) === (_nullishCoalesce(account.contractAddress, () => ( null)))
|
|
@@ -341,7 +337,8 @@ async function bakeWorkspace(options, logger) {
|
|
|
341
337
|
// general fields
|
|
342
338
|
name: account.name,
|
|
343
339
|
currency: account.currency,
|
|
344
|
-
contractAddress: account.contractAddress,
|
|
340
|
+
contractAddress: _nullishCoalesce(account.contractAddress, () => ( null)),
|
|
341
|
+
tokenIdentifier: _nullishCoalesce(account.tokenIdentifier, () => ( null)),
|
|
345
342
|
index: account.index,
|
|
346
343
|
// governance fields
|
|
347
344
|
governance: account.governance.type === "TRADELINK" ? {
|
|
@@ -415,33 +412,25 @@ async function bakeWorkspace(options, logger) {
|
|
|
415
412
|
logger
|
|
416
413
|
);
|
|
417
414
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
try {
|
|
436
|
-
await admin1.client.accounts.hedera.activateAccount.mutate({
|
|
437
|
-
id: account.id,
|
|
438
|
-
onchainId: hederaAccount.onChainId
|
|
439
|
-
});
|
|
440
|
-
logger.info(`[ACTIVATED] Hedera account "${account.name}" has been activated`);
|
|
441
|
-
} catch (error) {
|
|
442
|
-
logger.warning(`Activation for "${account.name}" failed: ${error} (likely expected)`);
|
|
415
|
+
if (account.currency === "hedera" && account.contractAddress === void 0 && workspace2.hederaData && req) {
|
|
416
|
+
const salt = engine.__options.salt;
|
|
417
|
+
const hederaAccountsForSalt = workspace2.hederaData[salt];
|
|
418
|
+
const hederaAccountData = _optionalChain([hederaAccountsForSalt, 'optionalAccess', _17 => _17.find, 'call', _18 => _18(
|
|
419
|
+
(h) => h.index === account.index && h.activate
|
|
420
|
+
)]);
|
|
421
|
+
if (hederaAccountData) {
|
|
422
|
+
try {
|
|
423
|
+
await admin1.client.accounts.hedera.activateAccount.mutate({
|
|
424
|
+
id: req.targetId,
|
|
425
|
+
onchainId: hederaAccountData.onChainId
|
|
426
|
+
});
|
|
427
|
+
logSubStep(`Hedera account "${account.name}" has been activated`);
|
|
428
|
+
} catch (error) {
|
|
429
|
+
logger.warning(`Activation for "${account.name}" failed: ${error} (likely expected)`);
|
|
430
|
+
}
|
|
443
431
|
}
|
|
444
432
|
}
|
|
433
|
+
logSubStep(`Account ${account.name} has been created`);
|
|
445
434
|
}
|
|
446
435
|
async function createUser(role, deviceIndex) {
|
|
447
436
|
const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);
|
|
@@ -720,14 +709,14 @@ async function bakeWorkspace(options, logger) {
|
|
|
720
709
|
orgAssetManager,
|
|
721
710
|
`Can't find Tradelink organization asset manager ${assetManagerName}`
|
|
722
711
|
);
|
|
723
|
-
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess',
|
|
712
|
+
const assetManager = _optionalChain([existingTradelinkNetwork, 'optionalAccess', _19 => _19.assetManagers, 'access', _20 => _20.find, 'call', _21 => _21(
|
|
724
713
|
(assetManager2) => assetManager2.tradelinkId === orgAssetManager.tradelinkId
|
|
725
714
|
)]);
|
|
726
715
|
_invariant2.default.call(void 0, assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);
|
|
727
716
|
return assetManager.id;
|
|
728
717
|
}
|
|
729
718
|
function exchangeIdFromName(exchangeName) {
|
|
730
|
-
const exchange = _optionalChain([existingTradelinkNetwork, 'optionalAccess',
|
|
719
|
+
const exchange = _optionalChain([existingTradelinkNetwork, 'optionalAccess', _22 => _22.exchanges, 'access', _23 => _23.find, 'call', _24 => _24((exchange2) => {
|
|
731
720
|
const orgExchange = tradelinkOrgExchangesByName[exchangeName];
|
|
732
721
|
_invariant2.default.call(void 0, orgExchange, `Can't find Tradelink organization exchange ${exchange2.tradelinkId}`);
|
|
733
722
|
return orgExchange.name === exchangeName;
|
|
@@ -832,6 +821,7 @@ var zManifestAccount = _zod2.default.object({
|
|
|
832
821
|
currency: _zod2.default.string(),
|
|
833
822
|
index: _zod2.default.number().nonnegative(),
|
|
834
823
|
contractAddress: _zod2.default.string().optional(),
|
|
824
|
+
tokenIdentifier: _zod2.default.string().optional(),
|
|
835
825
|
governance: zManifestAccountGovernance
|
|
836
826
|
}).strict();
|
|
837
827
|
var zManifestHederaData = _zod2.default.object({
|
|
@@ -921,7 +911,7 @@ async function bakeManifest(options, logger) {
|
|
|
921
911
|
engine,
|
|
922
912
|
tradelink,
|
|
923
913
|
rootAuthToken,
|
|
924
|
-
..._optionalChain([workspace, 'optionalAccess',
|
|
914
|
+
..._optionalChain([workspace, 'optionalAccess', _25 => _25.tradelink, 'optionalAccess', _26 => _26.networkBlueprint]) && workspaceName ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } } : {}
|
|
925
915
|
},
|
|
926
916
|
logger
|
|
927
917
|
);
|
|
@@ -947,5 +937,4 @@ async function bakeManifest(options, logger) {
|
|
|
947
937
|
exports.bakeManifest = bakeManifest; exports.bakePledgeAdjustment = bakePledgeAdjustment; exports.createAndApproveRequest = createAndApproveRequest; exports.zManifest = zManifest; exports.zManifestPolicy = zManifestPolicy;
|
|
948
938
|
/* v8 ignore else - TODO bake empty tradelink org -- @preserve */
|
|
949
939
|
/* v8 ignore else -- @preserve */
|
|
950
|
-
/* v8 ignore next -- @preserve */
|
|
951
940
|
//# sourceMappingURL=bake.cjs.map
|
package/lib/bake.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/_work/revault/revault/packages/sdk/lib/bake.cjs","../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"names":["blueprintExchange","invariant","assetManager","usersWithDeviceIndex","acc"],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACRA,4FAAsB;ADUtB;AACA;AEXA;AFaA;AACA;AGbA;AAcO,SAAS,oBAAA,CAAqB,MAAA,EAA4B;AAC/D,EAAA,OAAO;AAAA,IACL,QAAA,CAAS,KAAA,EAAqB;AAC5B,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,GAAA,EAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAAA,IAC9B,CAAA;AAAA,IACA,OAAA,CAAQ,GAAA,EAAmB;AACzB,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,GAAA,EAAM,GAAG,CAAA,CAAA;AACvB,IAAA;AAC8B,IAAA;AACP,MAAA;AACvB,IAAA;AACF,EAAA;AACF;AAOsB;AAKG,EAAA;AACH,EAAA;AACP,IAAA;AACM,IAAA;AACD,IAAA;AAClB,EAAA;AACO,EAAA;AACT;AAEsB;AAKG,EAAA;AACG,EAAA;AACP,EAAA;AACR,EAAA;AACW,EAAA;AACA,EAAA;AACxB;AAEsC;AACZ,EAAA;AACP,IAAA;AACjB,EAAA;AAE0B,EAAA;AACV,IAAA;AAET,MAAA;AAEL,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AHlB4B;AACA;AE5CF;AACQ,EAAA;AACN,IAAA;AACjB,IAAA;AACJ,EAAA;AACP;AAEsB;AACM,EAAA;AAEH,EAAA;AAEX,EAAA;AACQ,EAAA;AAER,EAAA;AACa,EAAA;AACD,IAAA;AACC,IAAA;AACA,IAAA;AACxB,EAAA;AAEe,EAAA;AACG,EAAA;AAEE,EAAA;AACF,EAAA;AAEM,EAAA;AACjB,IAAA;AACHA,MAAAA;AACH,IAAA;AACU,IAAA;AACH,IAAA;AACR,EAAA;AACmB,EAAA;AAED,EAAA;AACE,EAAA;AACA,EAAA;AACG,EAAA;AAElB,EAAA;AACoB,IAAA;AAC1B,EAAA;AACAC,EAAAA;AACE,IAAA;AACuB,IAAA;AACzB,EAAA;AAEoB,EAAA;AACE,IAAA;AACA,IAAA;AACtB,EAAA;AAEwB,EAAA;AACV,IAAA;AACG,MAAA;AAIf,IAAA;AACF,EAAA;AAEM,EAAA;AACJ,IAAA;AACQ,MAAA;AACA,MAAA;AACe,QAAA;AACP,QAAA;AACJ,QAAA;AACV,MAAA;AACF,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AAEO,EAAA;AACL,IAAA;AACF,EAAA;AACF;AF8B4B;AACA;AIlHN;AACD,EAAA;AAEC,EAAA;AAEM,EAAA;AAED,EAAA;AACf,IAAA;AACF,IAAA;AACK,IAAA;AACH,MAAA;AACF,MAAA;AACK,QAAA;AACL,UAAA;AACF,QAAA;AACK,MAAA;AACY,QAAA;AACG,UAAA;AACA,UAAA;AACT,UAAA;AACV,QAAA;AACW,QAAA;AACd,MAAA;AACF,IAAA;AACF,EAAA;AAGc,EAAA;AACJ,IAAA;AACF,IAAA;AACK,IAAA;AACH,MAAA;AACc,QAAA;AACpB,MAAA;AACI,MAAA;AACK,QAAA;AACL,UAAA;AACF,QAAA;AACK,MAAA;AACY,QAAA;AACT,UAAA;AACA,UAAA;AACG,UAAA;AACV,QAAA;AACM,QAAA;AACL,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAG0B,EAAA;AAChB,IAAA;AACF,IAAA;AACK,IAAA;AACH,MAAA;AACF,MAAA;AACK,QAAA;AACL,UAAA;AACF,QAAA;AACK,MAAA;AACY,QAAA;AACT,UAAA;AACA,UAAA;AACG,UAAA;AACV,QAAA;AACW,QAAA;AACd,MAAA;AACF,IAAA;AACF,EAAA;AAGsB,EAAA;AACZ,IAAA;AACe,IAAA;AACjB,IAAA;AACA,IAAA;AACiB,IAAA;AACT,MAAA;AACP,IAAA;AACY,MAAA;AACf,QAAA;AACmB,QAAA;AACR,QAAA;AACI,QAAA;AAChB,MAAA;AACW,MAAA;AACd,IAAA;AACF,EAAA;AACF;AJ2G4B;AACA;AK5MN;AACR;AAoCQ;AACD,EAAA;AAEK,EAAA;AACN,EAAA;AAGM,EAAA;AAIZ,EAAA;AACa,EAAA;AACP,IAAA;AACA,IAAA;AACjB,EAAA;AAGW,EAAA;AACN,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACoB,EAAA;AACG,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACC,IAAA;AACzB,EAAA;AAEK,EAAA;AACA,EAAA;AAEF,EAAA;AAIqB,EAAA;AACA,EAAA;AAEnB,EAAA;AAKe,EAAA;AACH,IAAA;AACI,IAAA;AACP,MAAA;AACQ,QAAA;AACnB,MAAA;AACF,IAAA;AAGoB,IAAA;AACP,MAAA;AACQ,QAAA;AACnB,MAAA;AACF,IAAA;AACoB,IAAA;AACI,MAAA;AACA,QAAA;AACtB,MAAA;AACF,IAAA;AACF,EAAA;AAKsB,EAAA;AACH,IAAA;AACG,IAAA;AACA,MAAA;AACpB,IAAA;AACF,EAAA;AAK0B,EAAA;AACH,IAAA;AACE,IAAA;AACzB,EAAA;AAIwB,EAAA;AACH,IAAA;AACE,IAAA;AACA,MAAA;AACrB,IAAA;AACF,EAAA;AAKyB,EAAA;AACH,IAAA;AACE,IAAA;AACxB,EAAA;AAKwB,EAAA;AACH,IAAA;AACG,IAAA;AACA,MAAA;AACtB,IAAA;AACF,EAAA;AAE0B,EAAA;AACf,IAAA;AACH,IAAA;AACR,EAAA;AAEe,EAAA;AACW,IAAA;AACA,MAAA;AACxB,IAAA;AAEe,IAAA;AACI,MAAA;AAGH,MAAA;AACA,QAAA;AACZ,QAAA;AACF,MAAA;AAEkC,MAAA;AAC1B,QAAA;AACA,QAAA;AACR,MAAA;AAEkB,MAAA;AACP,MAAA;AAEL,MAAA;AACa,MAAA;AACrB,IAAA;AACF,EAAA;AAES,EAAA;AACA,IAAA;AACe,MAAA;AACF,MAAA;AACD,QAAA;AACN,UAAA;AACQ,YAAA;AACJ,YAAA;AACX,UAAA;AACF,QAAA;AACO,QAAA;AACQ,UAAA;AACC,UAAA;AAChB,QAAA;AACD,MAAA;AACe,MAAA;AACG,MAAA;AACrB,IAAA;AACF,EAAA;AAEe,EAAA;AAC0B,IAAA;AACtB,IAAA;AAEE,MAAA;AAGnB,IAAA;AACwC,IAAA;AAChC,MAAA;AACA,MAAA;AAAA;AAEU,QAAA;AACI,QAAA;AACD,QAAA;AACF,QAAA;AAAA;AAIL,QAAA;AAEI,UAAA;AACU,UAAA;AACC,UAAA;AACH,YAAA;AACZ,YAAA;AACA,YAAA;AAEA,UAAA;AAEJ,QAAA;AACQ,UAAA;AACW,UAAA;AACnB,QAAA;AACR,MAAA;AACF,IAAA;AAEc,IAAA;AAC0B,MAAA;AACjC,QAAA;AACG,QAAA;AACa,QAAA;AACrB,MAAA;AAEM,MAAA;AACG,QAAA;AACY,QAAA;AACZ,QAAA;AACC,QAAA;AACG,QAAA;AACZ,MAAA;AAKG,MAAA;AACI,QAAA;AACNA,QAAAA;AAEK,UAAA;AACH,UAAA;AACF,QAAA;AAII,QAAA;AACA,UAAA;AACA,UAAA;AAEU,QAAA;AAEA,UAAA;AACZ,UAAA;AACF,QAAA;AAGY,QAAA;AACA,QAAA;AACZ,QAAA;AACF,MAAA;AACK,IAAA;AACG,MAAA;AACI,MAAA;AAEN,MAAA;AACgB,MAAA;AACxB,IAAA;AAEuB,IAAA;AACb,MAAA;AAEF,MAAA;AACe,MAAA;AACDC,QAAAA;AACpB,MAAA;AACU,MAAA;AACJ,MAAA;AACgB,QAAA;AAAmB,UAAA;AAE7B,YAAA;AACC,YAAA;AACR,UAAA;AACH,QAAA;AACF,MAAA;AACM,MAAA;AACI,QAAA;AACR,QAAA;AACA,QAAA;AACF,MAAA;AACF,IAAA;AAEsB,IAAA;AACxB,EAAA;AAMe,EAAA;AAGO,IAAA;AACG,IAAA;AACF,IAAA;AACP,MAAA;AACZ,MAAA;AACF,IAAA;AACW,IAAA;AACO,MAAA;AACF,MAAA;AACL,QAAA;AACL,UAAA;AACF,QAAA;AACA,QAAA;AACF,MAAA;AACI,MAAA;AACkB,QAAA;AACN,UAAA;AACD,UAAA;AACZ,QAAA;AACW,QAAA;AACE,MAAA;AAEC,QAAA;AACjB,MAAA;AACF,IAAA;AACF,EAAA;AAE0B,EAAA;AACL,IAAA;AACI,IAAA;AAGN,IAAA;AACH,IAAA;AACA,MAAA;AACZ,MAAA;AACF,IAAA;AAEgB,IAAA;AACQ,IAAA;AAEb,IAAA;AACQ,IAAA;AACjB,MAAA;AACA,MAAA;AACc,MAAA;AACJ,MAAA;AACX,IAAA;AAEU,IAAA;AACU,IAAA;AAEV,IAAA;AACY,IAAA;AACZ,MAAA;AACD,QAAA;AACE,QAAA;AACV,MAAA;AACD,IAAA;AAEW,IAAA;AACM,IAAA;AAEE,IAAA;AAGD,IAAA;AACE,IAAA;AACvB,EAAA;AAEe,EAAA;AACU,IAAA;AACN,IAAA;AACA,MAAA;AACjB,IAAA;AACc,IAAA;AACL,MAAA;AACL,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAEQ,IAAA;AAEG,IAAA;AACY,IAAA;AACZ,MAAA;AACD,QAAA;AACA,QAAA;AACU,UAAA;AACA,UAAA;AACd,UAAA;AACiB,UAAA;AACnB,QAAA;AACF,MAAA;AACD,IAAA;AACW,IAAA;AACY,IAAA;AAEb,IAAA;AACS,IAAA;AACV,MAAA;AACT,IAAA;AACD,IAAA;AACuB,MAAA;AACvB,IAAA;AACoB,IAAA;AAEE,IAAA;AACxB,EAAA;AAEe,EAAA;AACI,IAAA;AACH,IAAA;AACA,MAAA;AACZ,MAAA;AACF,IAAA;AAEQ,IAAA;AAEc,IAAA;AAEX,IAAA;AACS,IAAA;AACT,MAAA;AACD,QAAA;AACA,QAAA;AACQ,UAAA;AACC,UAAA;AACb,UAAA;AACF,QAAA;AACF,MAAA;AACD,IAAA;AAEe,IAAA;AACQ,IAAA;AAEH,IAAA;AACD,IAAA;AACtB,EAAA;AAEe,EAAA;AACI,IAAA;AACH,IAAA;AACA,MAAA;AACZ,MAAA;AACF,IAAA;AAEQ,IAAA;AAEG,IAAA;AACS,IAAA;AACT,MAAA;AACD,QAAA;AACA,QAAA;AACS,UAAA;AACI,UAAA;AACJ,UAAA;AACI,UAAA;AACnB,QAAA;AACF,MAAA;AACD,IAAA;AAEe,IAAA;AACK,IAAA;AAEC,IAAA;AACA,IAAA;AACxB,EAAA;AAEe,EAAA;AAEC,IAAA;AACR,MAAA;AACM,QAAA;AACY,QAAA;AACP,QAAA;AACC,UAAA;AACF,UAAA;AACG,UAAA;AACf,QAAA;AAEW,QAAA;AACK,QAAA;AACL,UAAA;AACD,YAAA;AACN,YAAA;AACF,UAAA;AACD,QAAA;AAEK,QAAA;AACK,QAAA;AAEX,QAAA;AACK,MAAA;AACO,QAAA;AACd,MAAA;AAEM,MAAA;AACF,MAAA;AAEY,QAAA;AACN,UAAA;AACR,QAAA;AAGc,QAAA;AACN,UAAA;AACR,QAAA;AACK,MAAA;AACE,QAAA;AACL,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAEe,EAAA;AAIH,IAAA;AACJ,IAAA;AACiB,IAAA;AAEf,MAAA;AACND,MAAAA;AACE,QAAA;AACY,QAAA;AACd,MAAA;AACmB,MAAA;AACX,MAAA;AAEN,MAAA;AAGY,QAAA;AACZ,QAAA;AACF,MAAA;AAEW,MAAA;AACW,MAAA;AACX,QAAA;AACD,UAAA;AACA,UAAA;AACS,YAAA;AACL,YAAA;AACG,YAAA;AACb,UAAA;AACF,QAAA;AACD,MAAA;AAEK,MAAA;AACY,QAAA;AAAmB,UAAA;AAInC,QAAA;AACF,MAAA;AAEqB,MAAA;AAGrB,MAAA;AACU,MAAA;AACZ,IAAA;AACF,EAAA;AAEe,EAAA;AAIH,IAAA;AACJ,IAAA;AACK,IAAA;AAEH,MAAA;AACU,QAAA;AAChB,MAAA;AACAA,MAAAA;AACE,QAAA;AACgB,QAAA;AAClB,MAAA;AACM,MAAA;AACE,MAAA;AAEN,MAAA;AACiB,QAAA;AAEjB,MAAA;AACY,QAAA;AACZ,QAAA;AACF,MAAA;AAEW,MAAA;AACW,MAAA;AACX,QAAA;AACD,UAAA;AACA,UAAA;AACS,YAAA;AACL,YAAA;AACG,YAAA;AACb,UAAA;AACF,QAAA;AACD,MAAA;AAEK,MAAA;AACgB,QAAA;AAAmB,UAAA;AAIvC,QAAA;AACF,MAAA;AAEqB,MAAA;AAGrB,MAAA;AACU,MAAA;AACZ,IAAA;AACF,EAAA;AAKe,EAAA;AAGPE,IAAAA;AAIE,MAAA;AACa,QAAA;AACRC,QAAAA;AACR,MAAA;AACe,MAAA;AACpB,IAAA;AACOD,IAAAA;AACT,EAAA;AAEe,EAAA;AAGE,IAAA;AACK,IAAA;AACL,IAAA;AACjB,EAAA;AAES,EAAA;AACe,IAAA;AACZ,IAAA;AACW,IAAA;AACvB,EAAA;AAES,EAAA;AACM,IAAA;AACG,IAAA;AACJ,IAAA;AACd,EAAA;AAES,EAAA;AACI,IAAA;AACF,MAAA;AACT,IAAA;AACO,IAAA;AACT,EAAA;AAEyB,EAAA;AACT,IAAA;AACG,IAAA;AACJ,IAAA;AACf,EAAA;AAES,EAAA;AACW,IAAA;AACG,IAAA;AACJ,IAAA;AACnB,EAAA;AAES,EAAA;AACiB,IAAA;AACxBF,IAAAA;AACE,MAAA;AACA,MAAA;AACF,IAAA;AACqB,IAAA;AACDC,MAAAA;AACpB,IAAA;AACU,IAAA;AACU,IAAA;AACtB,EAAA;AAES,EAAA;AACU,IAAA;AACK,MAAA;AACV,MAAA;AACS,MAAA;AACpB,IAAA;AACmB,IAAA;AACJ,IAAA;AAClB,EAAA;AAES,EAAA;AACP,IAAA;AACA,IAAA;AAC8C,EAAA;AACvC,IAAA;AACgB,MAAA;AACrB,MAAA;AACF,IAAA;AACF,EAAA;AACF;ALG4B;AACA;AM5uBd;AAiBU;AACI;AACD;AACD,EAAA;AACD,EAAA;AAGf,EAAA;AAEF,IAAA;AAEM,EAAA;AACc,EAAA;AAC3B;AASE;AACyB,EAAA;AAEN,EAAA;AAIZ;AAQJ;AAEsB,EAAA;AACE,EAAA;AACD,EAAA;AAEhB,EAAA;AAIH;AAGP;AACyB,EAAA;AACA,EAAA;AAEf,EAAA;AAIU,EAAA;AAGb;AAQJ;AAEe,EAAA;AACS,EAAA;AAEpB;AAEJ;AAEe,EAAA;AACD,EAAA;AAEV;AAEJ;AACJ,EAAA;AACA,EAAA;AACD;AAEK;AACI;AAAA;AAGO,EAAA;AACX,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACD,EAAA;AACc,EAAA;AAEL,EAAA;AACQ,IAAA;AACA,IAAA;AAEN,EAAA;AACc,EAAA;AAEpB;AAKP;AACgB,EAAA;AACM,EAAA;AACN,EAAA;AAET;AAQJ;AAEuB,EAAA;AACV,EAAA;AAET;AAEJ;AAEsB,EAAA;AAErB,EAAA;AAGH,EAAA;AAKM;AAEJ;AAEc,EAAA;AACS,EAAA;AACN,EAAA;AAEb;AAEJ;AACJ,EAAA;AACA,EAAA;AACD;AAGE;AACgB,EAAA;AACI,EAAA;AACD,EAAA;AACQ,EAAA;AACd,EAAA;AAEN;AASP;AACiB,EAAA;AACI,EAAA;AACE,EAAA;AAEhB;AAQJ;AAEgB,EAAA;AACC,EAAA;AACF,EAAA;AAEX;AAQJ;AAEe,EAAA;AACA,EAAA;AAGX;AAIJ;AAEA;AAEoB,EAAA;AACI,EAAA;AACD,EAAA;AAGnB;AAEJ;AAIA;AAEa,EAAA;AACP,EAAA;AACG,EAAA;AAEL;AAIJ;AAEU,EAAA;AACF,EAAA;AACG,EAAA;AAEP;AAEJ;AAEkB,EAAA;AACC,EAAA;AACI,EAAA;AAEnB;AAIJ;AAEgB,EAAA;AACP,EAAA;AACQ,EAAA;AACI,EAAA;AAGjB;AASP;AACY,EAAA;AAED,EAAA;AACU,IAAA;AACG,IAAA;AACN,IAAA;AAEL,EAAA;AACI,EAAA;AACI,EAAA;AACF,EAAA;AACA,EAAA;AACK,EAAA;AACN,EAAA;AAGX;AAQJ;AAEa,EAAA;AACA,EAAA;AACA,EAAA;AAGT;AAEoB;AAEP,EAAA;AACI,EAAA;AACH,EAAA;AAGd;AASA;AACa,EAAA;AACR,EAAA;AACA,EAAA;AAEL;ANgjBkB;AACA;AC/3BO;AAC3B,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACuB,IAAA;AACrB,EAAA;AAEW,EAAA;AACH,IAAA;AACJ,IAAA;AACJ,MAAA;AACE,QAAA;AACA,QAAA;AACA,QAAA;AACe,QAAA;AAGjB,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEe,EAAA;AACH,IAAA;AACY,IAAA;AAEC,IAAA;AACf,MAAA;AACK,MAAA;AACH,QAAA;AACR,MAAA;AACF,IAAA;AACF,EAAA;AAEY,EAAA;AACd;AD23B4B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/_work/revault/revault/packages/sdk/lib/bake.cjs","sourcesContent":[null,"import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\nexport * from \"./types\";\nexport { type CreateRequestInput, createAndApproveRequest } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n /* v8 ignore else - TODO bake empty tradelink org -- @preserve */\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestHederaData,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n approveRequest,\n type CreateRequestInput,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account);\n }\n }\n\n if (workspace.hederaData) {\n logTitle(\"Activate Hedera Accounts\");\n await activateHederaAccount(workspace.hederaData);\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(account: ManifestAccount): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n /* v8 ignore else -- @preserve */\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n /**\n * Look for existing Hedera accounts for {salt;index}\n * getAccount() does not return lesWalletId, so try to activate them anyway and catch error\n */\n async function activateHederaAccount(\n hederaData: Record<string, ManifestHederaData[]>,\n ): Promise<void> {\n const salt = engine.__options.salt;\n const hederaAccounts = hederaData[salt];\n if (!hederaAccounts) {\n logger.info(`[SKIPPED] No Hedera accounts to activate for salt: \"${salt}\"`);\n return;\n }\n for (const hederaAccount of hederaAccounts.filter((h) => h.activate)) {\n const account = existingAccounts.find((a) => a.index === hederaAccount.index);\n if (!account) {\n logger.info(\n `[SKIPPED] Cannot ActivateHedera Account with index ${hederaAccount.index}, it has not been created`,\n );\n continue;\n }\n try {\n await admin1.client.accounts.hedera.activateAccount.mutate({\n id: account.id,\n onchainId: hederaAccount.onChainId,\n });\n logger.info(`[ACTIVATED] Hedera account \"${account.name}\" has been activated`);\n } catch (error) {\n /* v8 ignore next -- @preserve */\n logger.warning(`Activation for \"${account.name}\" failed: ${error} (likely expected)`);\n }\n }\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n /* v8 ignore else -- @preserve */\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n /* v8 ignore else -- @preserve */\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\n \"SEND\",\n \"STAKE\",\n \"DEPLOY_CONTRACT\",\n \"EXECUTE_CONTRACT\",\n \"SIGN_MESSAGE\",\n \"RECEIVE\",\n ]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Hedera data ------------------------------------------------------------------\n\nconst zManifestHederaData = z\n .object({\n index: z.number(),\n onChainId: z.string(),\n activate: z.boolean().default(true),\n })\n .strict();\n\nexport type ManifestHederaData = z.infer<typeof zManifestHederaData>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n hederaData: z.record(z.string(), z.array(zManifestHederaData)).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/_work/revault/revault/packages/sdk/lib/bake.cjs","../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"names":["blueprintExchange","invariant","assetManager","usersWithDeviceIndex","acc"],"mappings":"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","file":"/home/runner/_work/revault/revault/packages/sdk/lib/bake.cjs","sourcesContent":[null,"import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\nexport * from \"./types\";\nexport { type CreateRequestInput, createAndApproveRequest } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n /* v8 ignore else - TODO bake empty tradelink org -- @preserve */\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n approveRequest,\n type CreateRequestInput,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account, workspace);\n }\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(\n account: ManifestAccount,\n workspace: ManifestWorkspace,\n ): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress ?? null,\n tokenIdentifier: account.tokenIdentifier ?? null,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n /* v8 ignore else -- @preserve */\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n // Activate Hedera native account right after creation (before token accounts are created)\n // This ensures token accounts can be created within one Bake process\n if (\n account.currency === \"hedera\" &&\n account.contractAddress === undefined &&\n workspace.hederaData &&\n req\n ) {\n const salt = engine.__options.salt;\n const hederaAccountsForSalt = workspace.hederaData[salt];\n const hederaAccountData = hederaAccountsForSalt?.find(\n (h) => h.index === account.index && h.activate,\n );\n if (hederaAccountData) {\n try {\n await admin1.client.accounts.hedera.activateAccount.mutate({\n id: req.targetId!,\n onchainId: hederaAccountData.onChainId,\n });\n logSubStep(`Hedera account \"${account.name}\" has been activated`);\n } catch (error) {\n logger.warning(`Activation for \"${account.name}\" failed: ${error} (likely expected)`);\n }\n }\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n /* v8 ignore else -- @preserve */\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n /* v8 ignore else -- @preserve */\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\n \"SEND\",\n \"STAKE\",\n \"DEPLOY_CONTRACT\",\n \"EXECUTE_CONTRACT\",\n \"SIGN_MESSAGE\",\n \"RECEIVE\",\n ]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n tokenIdentifier: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Hedera data ------------------------------------------------------------------\n\nconst zManifestHederaData = z\n .object({\n index: z.number(),\n onChainId: z.string(),\n activate: z.boolean().default(true),\n })\n .strict();\n\nexport type ManifestHederaData = z.infer<typeof zManifestHederaData>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n hederaData: z.record(z.string(), z.array(zManifestHederaData)).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"]}
|
package/lib/bake.d.cts
CHANGED
|
@@ -98,6 +98,7 @@ declare const zManifestAccount: z.ZodObject<{
|
|
|
98
98
|
currency: z.ZodString;
|
|
99
99
|
index: z.ZodNumber;
|
|
100
100
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
101
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
101
102
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
102
103
|
type: z.ZodLiteral<"CLASSIC">;
|
|
103
104
|
rules: z.ZodArray<z.ZodObject<{
|
|
@@ -323,6 +324,7 @@ declare const zManifestWorkspace: z.ZodObject<{
|
|
|
323
324
|
currency: z.ZodString;
|
|
324
325
|
index: z.ZodNumber;
|
|
325
326
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
327
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
326
328
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
327
329
|
type: z.ZodLiteral<"CLASSIC">;
|
|
328
330
|
rules: z.ZodArray<z.ZodObject<{
|
|
@@ -514,6 +516,7 @@ declare const zManifest: z.ZodObject<{
|
|
|
514
516
|
currency: z.ZodString;
|
|
515
517
|
index: z.ZodNumber;
|
|
516
518
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
519
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
517
520
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
518
521
|
type: z.ZodLiteral<"CLASSIC">;
|
|
519
522
|
rules: z.ZodArray<z.ZodObject<{
|
package/lib/bake.d.ts
CHANGED
|
@@ -98,6 +98,7 @@ declare const zManifestAccount: z.ZodObject<{
|
|
|
98
98
|
currency: z.ZodString;
|
|
99
99
|
index: z.ZodNumber;
|
|
100
100
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
101
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
101
102
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
102
103
|
type: z.ZodLiteral<"CLASSIC">;
|
|
103
104
|
rules: z.ZodArray<z.ZodObject<{
|
|
@@ -323,6 +324,7 @@ declare const zManifestWorkspace: z.ZodObject<{
|
|
|
323
324
|
currency: z.ZodString;
|
|
324
325
|
index: z.ZodNumber;
|
|
325
326
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
327
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
326
328
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
327
329
|
type: z.ZodLiteral<"CLASSIC">;
|
|
328
330
|
rules: z.ZodArray<z.ZodObject<{
|
|
@@ -514,6 +516,7 @@ declare const zManifest: z.ZodObject<{
|
|
|
514
516
|
currency: z.ZodString;
|
|
515
517
|
index: z.ZodNumber;
|
|
516
518
|
contractAddress: z.ZodOptional<z.ZodString>;
|
|
519
|
+
tokenIdentifier: z.ZodOptional<z.ZodString>;
|
|
517
520
|
governance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
518
521
|
type: z.ZodLiteral<"CLASSIC">;
|
|
519
522
|
rules: z.ZodArray<z.ZodObject<{
|
package/lib/bake.js
CHANGED
|
@@ -284,13 +284,9 @@ async function bakeWorkspace(options, logger) {
|
|
|
284
284
|
if (workspace.accounts) {
|
|
285
285
|
logTitle("Accounts");
|
|
286
286
|
for (const account of workspace.accounts) {
|
|
287
|
-
await createAccount(account);
|
|
287
|
+
await createAccount(account, workspace);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
|
-
if (workspace.hederaData) {
|
|
291
|
-
logTitle("Activate Hedera Accounts");
|
|
292
|
-
await activateHederaAccount(workspace.hederaData);
|
|
293
|
-
}
|
|
294
290
|
async function createWhitelists(whitelists) {
|
|
295
291
|
for (const whitelist of whitelists) {
|
|
296
292
|
await createWhitelist(whitelist);
|
|
@@ -330,7 +326,7 @@ async function bakeWorkspace(options, logger) {
|
|
|
330
326
|
whitelistIds: rule.whitelistNames?.map(whitelistIdFromName)
|
|
331
327
|
};
|
|
332
328
|
}
|
|
333
|
-
async function createAccount(account) {
|
|
329
|
+
async function createAccount(account, workspace2) {
|
|
334
330
|
let req = null;
|
|
335
331
|
const existing = existingAccounts.find(
|
|
336
332
|
(a) => a.currency === account.currency && a.index === account.index && (a.contractAddress ?? null) === (account.contractAddress ?? null)
|
|
@@ -341,7 +337,8 @@ async function bakeWorkspace(options, logger) {
|
|
|
341
337
|
// general fields
|
|
342
338
|
name: account.name,
|
|
343
339
|
currency: account.currency,
|
|
344
|
-
contractAddress: account.contractAddress,
|
|
340
|
+
contractAddress: account.contractAddress ?? null,
|
|
341
|
+
tokenIdentifier: account.tokenIdentifier ?? null,
|
|
345
342
|
index: account.index,
|
|
346
343
|
// governance fields
|
|
347
344
|
governance: account.governance.type === "TRADELINK" ? {
|
|
@@ -415,33 +412,25 @@ async function bakeWorkspace(options, logger) {
|
|
|
415
412
|
logger
|
|
416
413
|
);
|
|
417
414
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
try {
|
|
436
|
-
await admin1.client.accounts.hedera.activateAccount.mutate({
|
|
437
|
-
id: account.id,
|
|
438
|
-
onchainId: hederaAccount.onChainId
|
|
439
|
-
});
|
|
440
|
-
logger.info(`[ACTIVATED] Hedera account "${account.name}" has been activated`);
|
|
441
|
-
} catch (error) {
|
|
442
|
-
logger.warning(`Activation for "${account.name}" failed: ${error} (likely expected)`);
|
|
415
|
+
if (account.currency === "hedera" && account.contractAddress === void 0 && workspace2.hederaData && req) {
|
|
416
|
+
const salt = engine.__options.salt;
|
|
417
|
+
const hederaAccountsForSalt = workspace2.hederaData[salt];
|
|
418
|
+
const hederaAccountData = hederaAccountsForSalt?.find(
|
|
419
|
+
(h) => h.index === account.index && h.activate
|
|
420
|
+
);
|
|
421
|
+
if (hederaAccountData) {
|
|
422
|
+
try {
|
|
423
|
+
await admin1.client.accounts.hedera.activateAccount.mutate({
|
|
424
|
+
id: req.targetId,
|
|
425
|
+
onchainId: hederaAccountData.onChainId
|
|
426
|
+
});
|
|
427
|
+
logSubStep(`Hedera account "${account.name}" has been activated`);
|
|
428
|
+
} catch (error) {
|
|
429
|
+
logger.warning(`Activation for "${account.name}" failed: ${error} (likely expected)`);
|
|
430
|
+
}
|
|
443
431
|
}
|
|
444
432
|
}
|
|
433
|
+
logSubStep(`Account ${account.name} has been created`);
|
|
445
434
|
}
|
|
446
435
|
async function createUser(role, deviceIndex) {
|
|
447
436
|
const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);
|
|
@@ -832,6 +821,7 @@ var zManifestAccount = z.object({
|
|
|
832
821
|
currency: z.string(),
|
|
833
822
|
index: z.number().nonnegative(),
|
|
834
823
|
contractAddress: z.string().optional(),
|
|
824
|
+
tokenIdentifier: z.string().optional(),
|
|
835
825
|
governance: zManifestAccountGovernance
|
|
836
826
|
}).strict();
|
|
837
827
|
var zManifestHederaData = z.object({
|
|
@@ -947,5 +937,4 @@ export {
|
|
|
947
937
|
};
|
|
948
938
|
/* v8 ignore else - TODO bake empty tradelink org -- @preserve */
|
|
949
939
|
/* v8 ignore else -- @preserve */
|
|
950
|
-
/* v8 ignore next -- @preserve */
|
|
951
940
|
//# sourceMappingURL=bake.js.map
|
package/lib/bake.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"sourcesContent":["import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\nexport * from \"./types\";\nexport { type CreateRequestInput, createAndApproveRequest } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n /* v8 ignore else - TODO bake empty tradelink org -- @preserve */\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestHederaData,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n approveRequest,\n type CreateRequestInput,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account);\n }\n }\n\n if (workspace.hederaData) {\n logTitle(\"Activate Hedera Accounts\");\n await activateHederaAccount(workspace.hederaData);\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(account: ManifestAccount): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n /* v8 ignore else -- @preserve */\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n /**\n * Look for existing Hedera accounts for {salt;index}\n * getAccount() does not return lesWalletId, so try to activate them anyway and catch error\n */\n async function activateHederaAccount(\n hederaData: Record<string, ManifestHederaData[]>,\n ): Promise<void> {\n const salt = engine.__options.salt;\n const hederaAccounts = hederaData[salt];\n if (!hederaAccounts) {\n logger.info(`[SKIPPED] No Hedera accounts to activate for salt: \"${salt}\"`);\n return;\n }\n for (const hederaAccount of hederaAccounts.filter((h) => h.activate)) {\n const account = existingAccounts.find((a) => a.index === hederaAccount.index);\n if (!account) {\n logger.info(\n `[SKIPPED] Cannot ActivateHedera Account with index ${hederaAccount.index}, it has not been created`,\n );\n continue;\n }\n try {\n await admin1.client.accounts.hedera.activateAccount.mutate({\n id: account.id,\n onchainId: hederaAccount.onChainId,\n });\n logger.info(`[ACTIVATED] Hedera account \"${account.name}\" has been activated`);\n } catch (error) {\n /* v8 ignore next -- @preserve */\n logger.warning(`Activation for \"${account.name}\" failed: ${error} (likely expected)`);\n }\n }\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n /* v8 ignore else -- @preserve */\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n /* v8 ignore else -- @preserve */\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\n \"SEND\",\n \"STAKE\",\n \"DEPLOY_CONTRACT\",\n \"EXECUTE_CONTRACT\",\n \"SIGN_MESSAGE\",\n \"RECEIVE\",\n ]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Hedera data ------------------------------------------------------------------\n\nconst zManifestHederaData = z\n .object({\n index: z.number(),\n onChainId: z.string(),\n activate: z.boolean().default(true),\n })\n .strict();\n\nexport type ManifestHederaData = z.infer<typeof zManifestHederaData>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n hederaData: z.record(z.string(), z.array(zManifestHederaData)).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"],"mappings":"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","names":["invariant","invariant","_","account","invariant","exchange","blueprintExchange","_","invariant","invariant","assetManager","usersWithDeviceIndex","acc","exchange","invariant"]}
|
|
1
|
+
{"version":3,"sources":["../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"sourcesContent":["import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\nexport * from \"./types\";\nexport { type CreateRequestInput, createAndApproveRequest } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n /* v8 ignore else - TODO bake empty tradelink org -- @preserve */\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n approveRequest,\n type CreateRequestInput,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n\n /* v8 ignore else -- @preserve */\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account, workspace);\n }\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(\n account: ManifestAccount,\n workspace: ManifestWorkspace,\n ): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress ?? null,\n tokenIdentifier: account.tokenIdentifier ?? null,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n /* v8 ignore else -- @preserve */\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n // Activate Hedera native account right after creation (before token accounts are created)\n // This ensures token accounts can be created within one Bake process\n if (\n account.currency === \"hedera\" &&\n account.contractAddress === undefined &&\n workspace.hederaData &&\n req\n ) {\n const salt = engine.__options.salt;\n const hederaAccountsForSalt = workspace.hederaData[salt];\n const hederaAccountData = hederaAccountsForSalt?.find(\n (h) => h.index === account.index && h.activate,\n );\n if (hederaAccountData) {\n try {\n await admin1.client.accounts.hedera.activateAccount.mutate({\n id: req.targetId!,\n onchainId: hederaAccountData.onChainId,\n });\n logSubStep(`Hedera account \"${account.name}\" has been activated`);\n } catch (error) {\n logger.warning(`Activation for \"${account.name}\" failed: ${error} (likely expected)`);\n }\n }\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n /* v8 ignore else -- @preserve */\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n /* v8 ignore else -- @preserve */\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n /* v8 ignore else -- @preserve */\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\n \"SEND\",\n \"STAKE\",\n \"DEPLOY_CONTRACT\",\n \"EXECUTE_CONTRACT\",\n \"SIGN_MESSAGE\",\n \"RECEIVE\",\n ]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n tokenIdentifier: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Hedera data ------------------------------------------------------------------\n\nconst zManifestHederaData = z\n .object({\n index: z.number(),\n onChainId: z.string(),\n activate: z.boolean().default(true),\n })\n .strict();\n\nexport type ManifestHederaData = z.infer<typeof zManifestHederaData>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n hederaData: z.record(z.string(), z.array(zManifestHederaData)).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"],"mappings":"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","names":["invariant","invariant","_","account","invariant","exchange","blueprintExchange","_","invariant","workspace","invariant","assetManager","usersWithDeviceIndex","acc","exchange","invariant"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/revault-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@ledgerhq/errors": "^6.27.0",
|
|
48
48
|
"@ledgerhq/hw-transport": "^6.31.13",
|
|
49
|
-
"@trpc/client": "11.
|
|
50
|
-
"@trpc/server": "11.
|
|
49
|
+
"@trpc/client": "11.7.2",
|
|
50
|
+
"@trpc/server": "11.7.2",
|
|
51
51
|
"asn1.js": "^5.4.1",
|
|
52
52
|
"axios": "^1.13.2",
|
|
53
53
|
"axios-retry": "^4.5.0",
|
|
54
54
|
"bn.js": "^5.2.2",
|
|
55
55
|
"elliptic": "^6.6.1",
|
|
56
56
|
"invariant": "^2.2.4",
|
|
57
|
-
"jose": "^6.1.
|
|
57
|
+
"jose": "^6.1.3",
|
|
58
58
|
"lodash": "^4.17.21",
|
|
59
59
|
"rxjs": "^7.8.2",
|
|
60
60
|
"superjson": "^2.2.6",
|
|
61
61
|
"uuid": "^13.0.0",
|
|
62
62
|
"zod": "^4.1.13",
|
|
63
|
-
"@ledgerhq/revault-api": "1.43.
|
|
63
|
+
"@ledgerhq/revault-api": "1.43.1"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@eslint/js": "^9.39.1",
|
|
@@ -69,22 +69,23 @@
|
|
|
69
69
|
"@types/invariant": "^2.2.37",
|
|
70
70
|
"@types/lodash": "^4.17.21",
|
|
71
71
|
"@types/node": "^22.19.1",
|
|
72
|
-
"@vitest/coverage-v8": "^4.0.
|
|
73
|
-
"@vitest/ui": "^4.0.
|
|
72
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
73
|
+
"@vitest/ui": "^4.0.15",
|
|
74
74
|
"eslint": "^9.39.1",
|
|
75
|
-
"eslint-plugin-unicorn": "^
|
|
75
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
76
76
|
"tsup": "^8.5.1",
|
|
77
77
|
"tsx": "^4.21.0",
|
|
78
78
|
"typescript": "^5.9.3",
|
|
79
|
-
"typescript-eslint": "^8.48.
|
|
79
|
+
"typescript-eslint": "^8.48.1",
|
|
80
80
|
"vite-plugin-node-polyfills": "^0.24.0",
|
|
81
|
-
"vitest": "^4.0.
|
|
81
|
+
"vitest": "^4.0.15",
|
|
82
82
|
"vitest-mock-extended": "^3.1.0"
|
|
83
83
|
},
|
|
84
84
|
"scripts": {
|
|
85
85
|
"build": "tsup",
|
|
86
86
|
"dev": "tsup --watch",
|
|
87
87
|
"lint": "biome check --error-on-warnings",
|
|
88
|
+
"lint:fix": "biome check --write --unsafe",
|
|
88
89
|
"test": "vitest run --coverage --coverage.thresholds.100=true",
|
|
89
90
|
"test:unit": "vitest",
|
|
90
91
|
"typecheck": "tsgo --noEmit"
|