@ledgerhq/vault-common 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.turbo/turbo-build.log +19 -59
  2. package/CHANGELOG.md +12 -0
  3. package/lib/{chunk-GAKIXPAF.js → chunk-65DEEXP4.js} +1 -1
  4. package/lib/chunk-65DEEXP4.js.map +1 -0
  5. package/lib/createHSMBridge.d.ts +1 -1
  6. package/lib/{index-Cm_O9VIx.d.ts → index-BpLhb-bQ.d.ts} +11 -0
  7. package/lib/index.d.ts +2 -2
  8. package/lib/index.js +2 -2
  9. package/lib/recipeManifest.d.ts +1 -1
  10. package/lib/reviewAPIRequest.d.ts +1 -1
  11. package/lib/types/index.d.ts +1 -1
  12. package/lib/types/index.js +2 -2
  13. package/lib/utils.d.ts +1 -1
  14. package/package.json +8 -9
  15. package/tsup.config.ts +1 -1
  16. package/lib/chunk-54MXA3ZY.mjs +0 -14
  17. package/lib/chunk-54MXA3ZY.mjs.map +0 -1
  18. package/lib/chunk-6TT6A6YA.mjs +0 -1176
  19. package/lib/chunk-6TT6A6YA.mjs.map +0 -1
  20. package/lib/chunk-GAKIXPAF.js.map +0 -1
  21. package/lib/chunk-HU7O2ZFW.mjs +0 -249
  22. package/lib/chunk-HU7O2ZFW.mjs.map +0 -1
  23. package/lib/chunk-J5LGTIGS.mjs +0 -10
  24. package/lib/chunk-J5LGTIGS.mjs.map +0 -1
  25. package/lib/chunk-MNUHUKY3.mjs +0 -503
  26. package/lib/chunk-MNUHUKY3.mjs.map +0 -1
  27. package/lib/chunk-QNNV5GBH.mjs +0 -1261
  28. package/lib/chunk-QNNV5GBH.mjs.map +0 -1
  29. package/lib/chunk-VOB7PA3G.mjs +0 -97
  30. package/lib/chunk-VOB7PA3G.mjs.map +0 -1
  31. package/lib/chunk-ZJCMYPBL.mjs +0 -83
  32. package/lib/chunk-ZJCMYPBL.mjs.map +0 -1
  33. package/lib/createHSMBridge.d.mts +0 -27
  34. package/lib/createHSMBridge.mjs +0 -10
  35. package/lib/createHSMBridge.mjs.map +0 -1
  36. package/lib/crypto/utils.d.mts +0 -14
  37. package/lib/crypto/utils.mjs +0 -12
  38. package/lib/crypto/utils.mjs.map +0 -1
  39. package/lib/index-Cm_O9VIx.d.mts +0 -2010
  40. package/lib/index.d.mts +0 -161
  41. package/lib/index.mjs +0 -3252
  42. package/lib/index.mjs.map +0 -1
  43. package/lib/recipeManifest.d.mts +0 -6
  44. package/lib/recipeManifest.mjs +0 -11
  45. package/lib/recipeManifest.mjs.map +0 -1
  46. package/lib/reviewAPIRequest.d.mts +0 -20
  47. package/lib/reviewAPIRequest.mjs +0 -11
  48. package/lib/reviewAPIRequest.mjs.map +0 -1
  49. package/lib/types/index.d.mts +0 -6
  50. package/lib/types/index.mjs +0 -10
  51. package/lib/types/index.mjs.map +0 -1
  52. package/lib/utils.d.mts +0 -29
  53. package/lib/utils.mjs +0 -38
  54. package/lib/utils.mjs.map +0 -1
@@ -1,1176 +0,0 @@
1
- import {
2
- createNetwork
3
- } from "./chunk-VOB7PA3G.mjs";
4
- import {
5
- getAccountTypeByCurrency,
6
- getAccountUnit,
7
- getCurrencyUnit,
8
- getWorkspaceFromGate,
9
- serializeUnitValue,
10
- unwrapConnection,
11
- wait
12
- } from "./chunk-QNNV5GBH.mjs";
13
- import {
14
- decodeData,
15
- genKeys,
16
- sign
17
- } from "./chunk-HU7O2ZFW.mjs";
18
-
19
- // src/reviewAPIRequest.ts
20
- import { SILENT_LOGGER as SILENT_LOGGER2 } from "@ledgerhq/vault-utils";
21
-
22
- // src/apiUser/index.ts
23
- import chalk from "chalk";
24
-
25
- // src/createDefaultRunner.ts
26
- import { SILENT_LOGGER } from "@ledgerhq/vault-utils";
27
- import invariant2 from "invariant";
28
- import { v4 as uuidv4 } from "uuid";
29
-
30
- // src/prepareRequest.ts
31
- import invariant from "invariant";
32
- var prepareUserCreation = ({ data }) => {
33
- const { role, name, userID } = data;
34
- return {
35
- type: role === "operator" ? "CREATE_OPERATOR" : "CREATE_ADMIN",
36
- username: name,
37
- user_id: userID
38
- };
39
- };
40
- var prepareAPIUserCreation = ({ data }) => {
41
- const { publicKey, name, role } = data;
42
- return {
43
- type: "CREATE_API_USER",
44
- user_data: {
45
- username: name,
46
- public_key: publicKey,
47
- role
48
- }
49
- };
50
- };
51
- var prepareAPIUserAccessCreation = ({ data }) => {
52
- const { name } = data;
53
- return {
54
- type: "CREATE_API_USER_ACCESS",
55
- user_data: {
56
- username: name
57
- }
58
- };
59
- };
60
- var prepareAccountCreation = ({ type, data }) => {
61
- const {
62
- account,
63
- usersByDevice,
64
- whitelistsIDsByName,
65
- groupsIDsByName,
66
- accountsByName,
67
- hsmCustodiansIDsByName,
68
- hsmAssetManagersIDsByName,
69
- hsmExchangesIDsByName,
70
- usersByName,
71
- tokens
72
- } = data;
73
- const allAccounts = Object.keys(accountsByName).map((key) => accountsByName[key]);
74
- const token = "contractAddress" in account ? tokens.find((t) => t.contract_address === account.contractAddress) : null;
75
- if ("contractAddress" in account && !token) {
76
- throw new Error(`Can't find token with contract address ${account.contractAddress}`);
77
- }
78
- let account_type = null;
79
- if (token?.family === "ethereum") {
80
- if (token.parent_currency === "bsc") {
81
- account_type = "Bep20";
82
- } else {
83
- account_type = "Erc20";
84
- }
85
- } else if ("accountType" in account) {
86
- account_type = account.accountType;
87
- } else if ("currency" in account) {
88
- account_type = getAccountTypeByCurrency(account.currency);
89
- }
90
- if (!account_type) {
91
- throw new Error(`Can't determine account type`);
92
- }
93
- const unit = getAccountUnit(account, tokens);
94
- const governance_rules = "tradelink_data" in account && !!account.tradelink_data ? null : transformManifestRules({
95
- rules: account.rules,
96
- unit,
97
- usersByDevice,
98
- usersByName,
99
- whitelistsIDsByName,
100
- groupsIDsByName,
101
- // VG-18120 accounts *must* enforce having a tx-filter rule of type SEND for rules that are
102
- // not SCI and not "any-other-type-of-filter".
103
- enforceSendTxFilter: true
104
- });
105
- const account_data = {
106
- name: account.name,
107
- ...governance_rules ? { governance_rules } : {}
108
- };
109
- if ("readOnly" in account && !!account.readOnly) {
110
- Object.assign(account_data, {
111
- xpub: account.readOnly.xpub,
112
- extended_public_key: {
113
- public_key: account.readOnly.publicKey,
114
- chain_code: account.readOnly.chainCode
115
- },
116
- address: account.readOnly.address
117
- });
118
- }
119
- if ("contractAddress" in account && token) {
120
- const currencyName = token.parent_currency;
121
- const parentAccountName = account.parentAccount;
122
- const parent_account = parentAccountName ? (() => {
123
- let parentAccountID = null;
124
- const existingParentAccount = allAccounts.find(
125
- (a) => !!a && a.name === parentAccountName
126
- );
127
- if (existingParentAccount) {
128
- parentAccountID = existingParentAccount.id;
129
- } else {
130
- const createdParentAccount = accountsByName[parentAccountName];
131
- if (!createdParentAccount) {
132
- return { name: parentAccountName };
133
- }
134
- parentAccountID = createdParentAccount.id;
135
- }
136
- return { id: parentAccountID };
137
- })() : null;
138
- if (process.env.LEGACY_TOKENS) {
139
- const erc20 = {
140
- ticker: token.ticker,
141
- address: token.contract_address,
142
- decimals: token.units[0].magnitude,
143
- hsm_account_parameters: token.__legacy_hsm_account_parameters,
144
- hsm_signature: token.__legacy_hsm_signature
145
- };
146
- Object.assign(account_data, { erc20 });
147
- } else {
148
- Object.assign(account_data, {
149
- token: { type: token.token_type, address: token.contract_address }
150
- });
151
- }
152
- Object.assign(account_data, {
153
- currency: { name: currencyName },
154
- parent_account
155
- });
156
- }
157
- if ("currency" in account) {
158
- Object.assign(account_data, {
159
- currency: {
160
- name: account.currency
161
- }
162
- });
163
- if ("derivationMode" in account) {
164
- Object.assign(account_data, {
165
- derivation_mode: account.derivationMode
166
- });
167
- }
168
- }
169
- let tradelinkData;
170
- if ("tradelink_data" in account && !!account.tradelink_data) {
171
- const custodianID = hsmCustodiansIDsByName[account.tradelink_data.custodian.name];
172
- if (typeof custodianID === "undefined")
173
- throw new Error(`Invalid custodian name ${account.tradelink_data.custodian.name}`);
174
- const assetManagerID = hsmAssetManagersIDsByName[account.tradelink_data.asset_manager.name];
175
- if (typeof assetManagerID === "undefined")
176
- throw new Error(`Invalid asset manager name ${account.tradelink_data.asset_manager.name}`);
177
- tradelinkData = {
178
- currency: account.tradelink_data.currency,
179
- custodian: custodianID,
180
- asset_manager: assetManagerID,
181
- exchanges: account.tradelink_data.exchanges.map((exchange) => {
182
- const exchangeID = hsmExchangesIDsByName[exchange.name];
183
- if (typeof exchangeID === "undefined")
184
- throw new Error(`Invalid exchange name ${exchange.name}`);
185
- return {
186
- auto_repledge_enabled: exchange.auto_repledge_enabled,
187
- requires_pre_approval: exchange.requires_pre_approval,
188
- id: exchangeID
189
- };
190
- })
191
- };
192
- }
193
- return {
194
- type,
195
- ...account.index !== void 0 ? { index: account.index } : {},
196
- ...tradelinkData ? { tradelink_data: tradelinkData } : {},
197
- account_type,
198
- account_data
199
- };
200
- };
201
- var prepareAccountEdition = ({ type, data }) => {
202
- const {
203
- account,
204
- existingAccount,
205
- usersByDevice,
206
- usersByName,
207
- whitelistsIDsByName,
208
- groupsIDsByName,
209
- tokens
210
- } = data;
211
- if (!existingAccount) {
212
- throw new Error("No existingAccount given");
213
- }
214
- const unit = getAccountUnit(account, tokens);
215
- const governance_rules = transformManifestRules({
216
- rules: account.rules,
217
- unit,
218
- usersByDevice,
219
- usersByName,
220
- whitelistsIDsByName,
221
- groupsIDsByName,
222
- enforceSendTxFilter: true
223
- });
224
- const edit_data = {
225
- name: account.name,
226
- governance_rules
227
- };
228
- if ("contractAddress" in account) {
229
- const token = tokens.find((t) => t.contract_address === account.contractAddress);
230
- if (!token) {
231
- throw new Error(`Can't find token with contract address ${account.contractAddress}`);
232
- }
233
- if (process.env.LEGACY_TOKENS) {
234
- const erc20 = {
235
- ticker: token.ticker,
236
- address: token.contract_address,
237
- decimals: token.units[0].magnitude,
238
- hsm_account_parameters: token.__legacy_hsm_account_parameters,
239
- hsm_signature: token.__legacy_hsm_signature
240
- };
241
- Object.assign(edit_data, { erc20 });
242
- } else {
243
- Object.assign(edit_data, {
244
- token: { type: "erc20", address: token.contract_address }
245
- });
246
- }
247
- }
248
- return {
249
- type,
250
- account_id: existingAccount.id,
251
- edit_data
252
- };
253
- };
254
- var serializeGroupMembers = (groupUsers, { usersByDevice, usersByName }) => {
255
- return groupUsers.map((device) => {
256
- if (typeof device === "number") {
257
- const u = usersByDevice[device];
258
- if (!u) throw new Error(`Invalid device ${device}`);
259
- return u.id;
260
- } else {
261
- const u = usersByName[device];
262
- if (!u) throw new Error(`Invalid user name ${device}`);
263
- return u.id;
264
- }
265
- });
266
- };
267
- var prepareGroupCreation = ({ type, data }) => {
268
- const { group } = data;
269
- const members = serializeGroupMembers(group.users, data);
270
- return {
271
- type,
272
- name: group.name,
273
- description: group.description || "",
274
- members
275
- };
276
- };
277
- var prepareGroupEdition = ({ type, data }) => {
278
- const { group, existingGroup } = data;
279
- if (!existingGroup) {
280
- throw new Error("No existingGroup given");
281
- }
282
- const members = serializeGroupMembers(group.users, data);
283
- return {
284
- type,
285
- name: group.name,
286
- description: group.description || "",
287
- group_id: existingGroup.id,
288
- edit_data: {
289
- name: group.name,
290
- members
291
- }
292
- };
293
- };
294
- var serializeVaultEntityAccounts = (vaultEntityAccounts, { accountsByName }) => {
295
- return vaultEntityAccounts.map((accountName) => {
296
- const a = accountsByName[accountName];
297
- if (!a) throw new Error(`Invalid account ${accountName}`);
298
- return a.id;
299
- });
300
- };
301
- var prepareVaultEntityCreation = ({ type, data }) => {
302
- const {
303
- vaultEntity: { name, accounts }
304
- } = data;
305
- return {
306
- type,
307
- name,
308
- accounts: accounts ? serializeVaultEntityAccounts(accounts, data) : []
309
- };
310
- };
311
- var prepareVaultEntityEdition = ({ type, data }) => {
312
- const { vaultEntity, existingVaultEntity } = data;
313
- if (!existingVaultEntity) {
314
- throw new Error("No existing VaultEntity given");
315
- }
316
- return {
317
- type,
318
- entity_id: existingVaultEntity.id,
319
- edit_data: {
320
- name: vaultEntity.name,
321
- accounts: vaultEntity.accounts ? serializeVaultEntityAccounts(vaultEntity.accounts, data) : []
322
- }
323
- };
324
- };
325
- var prepareWhitelistCreation = ({ type, data }) => {
326
- const { whitelist } = data;
327
- const addresses = whitelist.addresses.map((a, i) => ({
328
- ...a,
329
- name: a.name || `${a.currency}-${i + 1}`
330
- }));
331
- return {
332
- type,
333
- name: whitelist.name,
334
- description: whitelist.description || "",
335
- addresses,
336
- ...whitelist.type && { whitelist_type: whitelist.type }
337
- };
338
- };
339
- var prepareWhitelistEdition = ({ type, data }) => {
340
- const { whitelist, existingWhitelist } = data;
341
- if (!existingWhitelist) {
342
- throw new Error(`No existingWhitelist given`);
343
- }
344
- const addresses = whitelist.addresses.map((a, i) => ({
345
- ...a,
346
- name: a.name || `${a.currency}-${i + 1}`
347
- }));
348
- return {
349
- type,
350
- name: whitelist.name,
351
- description: "",
352
- whitelist_id: existingWhitelist.id,
353
- edit_data: {
354
- name: whitelist.name,
355
- addresses
356
- }
357
- };
358
- };
359
- var prepareExchangeCreation = ({ type, data }) => {
360
- const { exchange, usersByDevice, usersByName, groupsIDsByName } = data;
361
- const governance_rules = exchange.rules ? transformManifestRules({ rules: exchange.rules, usersByDevice, usersByName, groupsIDsByName }) : [];
362
- return {
363
- type,
364
- exchange_data: {
365
- name: exchange.name,
366
- governance_rules,
367
- platform: exchange.platform,
368
- credentials: {
369
- apiKey: exchange.configuration.apiKey,
370
- secret: exchange.configuration.apiSecret
371
- }
372
- }
373
- };
374
- };
375
- var preparePolicyCreation = ({ type, data }) => {
376
- const { policy, usersByName, usersByDevice, groupsIDsByName, whitelistsIDsByName } = data;
377
- const unit = getCurrencyUnit(data.policy.currency);
378
- const governance_rules = transformManifestRules({
379
- rules: policy.rules,
380
- unit,
381
- usersByDevice,
382
- usersByName,
383
- groupsIDsByName,
384
- whitelistsIDsByName
385
- });
386
- return {
387
- type,
388
- policy_data: {
389
- name: policy.name,
390
- governance_rules,
391
- currency: {
392
- name: policy.currency
393
- }
394
- }
395
- };
396
- };
397
- var prepareQuorumEdition = ({ data }) => {
398
- return {
399
- type: "UPDATE_QUORUM",
400
- quorum: data.quorum
401
- };
402
- };
403
- var prepareRequest = (data) => {
404
- if (data.type === "EDIT_GROUP") {
405
- return prepareGroupEdition(data);
406
- }
407
- if (data.type === "CREATE_GROUP") {
408
- return prepareGroupCreation(data);
409
- }
410
- if (data.type === "EDIT_WHITELIST") {
411
- return prepareWhitelistEdition(data);
412
- }
413
- if (data.type === "CREATE_WHITELIST") {
414
- return prepareWhitelistCreation(data);
415
- }
416
- if (data.type === "CREATE_ACCOUNT") {
417
- return prepareAccountCreation(data);
418
- }
419
- if (data.type === "EDIT_ACCOUNT") {
420
- return prepareAccountEdition(data);
421
- }
422
- if (data.type === "CREATE_ENTITY") {
423
- return prepareVaultEntityCreation(data);
424
- }
425
- if (data.type === "EDIT_ENTITY") {
426
- return prepareVaultEntityEdition(data);
427
- }
428
- if (data.type === "CREATE_ADMIN" || data.type === "CREATE_OPERATOR") {
429
- return prepareUserCreation(data);
430
- }
431
- if (data.type === "CREATE_API_USER") {
432
- return prepareAPIUserCreation(data);
433
- }
434
- if (data.type === "CREATE_API_USER_ACCESS") {
435
- return prepareAPIUserAccessCreation(data);
436
- }
437
- if (data.type === "UPDATE_QUORUM") {
438
- return prepareQuorumEdition(data);
439
- }
440
- if (data.type === "IMPORT_EXCHANGE") {
441
- return prepareExchangeCreation(data);
442
- }
443
- if (data.type === "CREATE_POLICY") {
444
- return preparePolicyCreation(data);
445
- }
446
- throw new Error(`Unhandled request type ${data.type}`);
447
- };
448
- var getGroupID = (groupsIDsByName, groupName) => {
449
- const groupID = groupsIDsByName[groupName];
450
- if (typeof groupID === "undefined") throw new Error(`Invalid group name ${groupName}`);
451
- return groupID;
452
- };
453
- var transformMultiAuthRuleFromManifest = (rule, groupsIDsByName, usersByDevice, usersByName) => {
454
- return {
455
- type: rule.type,
456
- data: rule.steps.map((step) => {
457
- return {
458
- quorum: step.quorum,
459
- ..."group" in step ? { group_id: getGroupID(groupsIDsByName, step.group) } : {
460
- users: step.users.map((d) => {
461
- if (typeof d === "number") {
462
- const user2 = usersByDevice[d];
463
- if (!user2) throw new Error(`Invalid device ${d}`);
464
- return user2.id;
465
- }
466
- const user = usersByName[d];
467
- if (!user) throw new Error(`Invalid name ${d}`);
468
- return user.id;
469
- })
470
- }
471
- };
472
- })
473
- };
474
- };
475
- var transformWhitelistRuleFromManifest = (rule, whitelistsIDsByName) => {
476
- return {
477
- type: rule.type,
478
- data: rule.whitelists.map((w) => {
479
- const whitelistID = whitelistsIDsByName[w];
480
- if (typeof whitelistID === "undefined") throw new Error(`Invalid whitelist name ${w}`);
481
- return whitelistID;
482
- })
483
- };
484
- };
485
- var transformSCIRuleFromManifest = (rule) => {
486
- return {
487
- type: rule.type,
488
- data: [
489
- {
490
- enabled: rule.enabled
491
- }
492
- ]
493
- };
494
- };
495
- var transformTezosDelegationRuleFromManifest = () => {
496
- return { type: "TRANSACTION_FILTER", data: { preset: "TEZOS_DELEGATION" } };
497
- };
498
- var transformPolkadotStakingRuleFromManifest = () => {
499
- return { type: "TRANSACTION_FILTER", data: { preset: "POLKADOT_STAKING" } };
500
- };
501
- var transformSolanaStakingRuleFromManifest = () => {
502
- return { type: "TRANSACTION_FILTER", data: { preset: "SOLANA_STAKING" } };
503
- };
504
- var transformMessageSigningRuleFromManifest = () => {
505
- return { type: "TRANSACTION_FILTER", data: { preset: "MESSAGE_SIGNING" } };
506
- };
507
- var transformCreateSplTokenAccountRuleFromManifest = () => {
508
- return { type: "TRANSACTION_FILTER", data: { preset: "CREATE_SPL_TOKEN_ACCOUNT" } };
509
- };
510
- var transformCardanoStakingRuleFromManifest = () => {
511
- return { type: "TRANSACTION_FILTER", data: { preset: "CARDANO_STAKING" } };
512
- };
513
- var transformRawTransactionRuleFromManifest = () => {
514
- return { type: "TRANSACTION_FILTER", data: { preset: "RAW_SIGNING" } };
515
- };
516
- var transformSendTransactionRuleFromManifest = () => {
517
- return { type: "TRANSACTION_FILTER", data: { preset: "SEND" } };
518
- };
519
- var transformSmartContractDeploymentFromManifest = () => {
520
- return { type: "TRANSACTION_FILTER", data: { preset: "DEPLOY_CONTRACT" } };
521
- };
522
- var transformStakeTransactionRuleFromManifest = () => {
523
- return { type: "TRANSACTION_FILTER", data: { preset: "STAKE" } };
524
- };
525
- var transformThresholdRuleFromManifest = (rule, unit) => {
526
- return {
527
- type: rule.type,
528
- data: [
529
- {
530
- currency_type: "CRYPTO",
531
- ...rule.max ? { max: serializeUnitValue(unit, rule.max) } : {},
532
- min: serializeUnitValue(unit, rule.min || 0)
533
- }
534
- ]
535
- };
536
- };
537
- var transformManifestRules = ({
538
- rules,
539
- unit,
540
- usersByDevice,
541
- usersByName,
542
- whitelistsIDsByName,
543
- groupsIDsByName,
544
- enforceSendTxFilter
545
- }) => {
546
- const governance_rules = rules && rules.length ? rules.map((rules2, i) => {
547
- return {
548
- name: `Rule ${i + 1}`,
549
- rules: rules2.map((rule) => {
550
- if (rule.type === "MULTI_AUTHORIZATIONS") {
551
- return transformMultiAuthRuleFromManifest(
552
- rule,
553
- groupsIDsByName,
554
- usersByDevice,
555
- usersByName
556
- );
557
- }
558
- if (rule.type === "WHITELIST") {
559
- invariant(
560
- whitelistsIDsByName,
561
- "WHITELIST rule configured outside of account context"
562
- );
563
- return transformWhitelistRuleFromManifest(rule, whitelistsIDsByName);
564
- }
565
- if (rule.type === "THRESHOLD") {
566
- invariant(unit, "THRESHOLD: no unit provided");
567
- return transformThresholdRuleFromManifest(rule, unit);
568
- }
569
- if (rule.type === "SMART_CONTRACT_INTERACTION") {
570
- return transformSCIRuleFromManifest(rule);
571
- }
572
- if (rule.type === "DEPLOY_CONTRACT") {
573
- return transformSmartContractDeploymentFromManifest();
574
- }
575
- if (rule.type === "TEZOS_DELEGATION") {
576
- return transformTezosDelegationRuleFromManifest();
577
- }
578
- if (rule.type === "POLKADOT_STAKING") {
579
- return transformPolkadotStakingRuleFromManifest();
580
- }
581
- if (rule.type === "SOLANA_STAKING") {
582
- return transformSolanaStakingRuleFromManifest();
583
- }
584
- if (rule.type === "CARDANO_STAKING") {
585
- return transformCardanoStakingRuleFromManifest();
586
- }
587
- if (rule.type === "RAW_SIGNING") {
588
- return transformRawTransactionRuleFromManifest();
589
- }
590
- if (rule.type === "SEND") {
591
- return transformSendTransactionRuleFromManifest();
592
- }
593
- if (rule.type === "STAKE") {
594
- return transformStakeTransactionRuleFromManifest();
595
- }
596
- if (rule.type === "MESSAGE_SIGNING") {
597
- return transformMessageSigningRuleFromManifest();
598
- }
599
- if (rule.type === "CREATE_SPL_TOKEN_ACCOUNT") {
600
- return transformCreateSplTokenAccountRuleFromManifest();
601
- }
602
- throw new Error(`Unhandled rule type ${rule.type}`);
603
- })
604
- };
605
- }) : getDefaultRule(usersByDevice);
606
- if (enforceSendTxFilter) {
607
- governance_rules.forEach((rulesSet) => {
608
- const hasTxFilterRule = !!rulesSet.rules.find((r) => r.type === "TRANSACTION_FILTER");
609
- const hasSCIRule = !!rulesSet.rules.find((r) => r.type === "SMART_CONTRACT_INTERACTION");
610
- if (!hasTxFilterRule && !hasSCIRule) {
611
- rulesSet.rules.unshift({ type: "TRANSACTION_FILTER", data: { preset: "SEND" } });
612
- }
613
- });
614
- }
615
- return governance_rules;
616
- };
617
- var getDefaultRule = (usersByDevice) => {
618
- const operatorsDevices = Object.keys(usersByDevice).filter((key) => {
619
- const u = usersByDevice[key];
620
- if (!u) throw new Error(`Invalid device ${key}`);
621
- return u.role === "OPERATOR";
622
- });
623
- const lastCreatedOperatorDevice = operatorsDevices[0];
624
- if (!lastCreatedOperatorDevice) {
625
- throw new Error(`Can't get the last created operator device`);
626
- }
627
- const lastCreatedOperator = usersByDevice[lastCreatedOperatorDevice];
628
- if (!lastCreatedOperator) {
629
- throw new Error(`Can't get the last created operator`);
630
- }
631
- return [
632
- {
633
- name: "Rule 1",
634
- rules: [
635
- {
636
- type: "MULTI_AUTHORIZATIONS",
637
- data: [
638
- {
639
- quorum: 1,
640
- users: [lastCreatedOperator.id]
641
- }
642
- ]
643
- }
644
- ]
645
- }
646
- ];
647
- };
648
- var TWO_STEPS_CREATION_REQUESTS = [
649
- "CREATE_ACCOUNT",
650
- "CREATE_GROUP",
651
- "CREATE_TRANSACTION",
652
- "CREATE_WHITELIST",
653
- "EDIT_ACCOUNT",
654
- "EDIT_GROUP",
655
- "EDIT_WHITELIST",
656
- "REVOKE_USER",
657
- "UPDATE_QUORUM"
658
- ];
659
- var performRequest = async (payload, pool, options) => {
660
- const adminDevices = await pool.getOnboardingAdminDevices();
661
- const admin = await pool.login(adminDevices[0][1]);
662
- let request = options?.existingRequest;
663
- if (!request) {
664
- const enableTwoStepsCreation = options?.twoStepsRequest && TWO_STEPS_CREATION_REQUESTS.includes(payload.type);
665
- if (enableTwoStepsCreation) {
666
- Object.assign(payload, { enable_two_step_request_creation: true });
667
- }
668
- const r = await admin.post("/requests", payload);
669
- request = r;
670
- if (enableTwoStepsCreation) {
671
- const pingChallenge = async () => {
672
- try {
673
- await admin.post(`/requests/${r.id}/post-create`, {});
674
- } catch (err) {
675
- await pingChallenge();
676
- }
677
- };
678
- await pingChallenge();
679
- }
680
- }
681
- if (!options || !options.noApproval) {
682
- await pool.runWithQuorum(
683
- (admin2) => options?.withoutHSM ? admin2.approveRequestWithoutHSM(request) : admin2.approveRequest(request)
684
- );
685
- }
686
- return request;
687
- };
688
- var prepareRequest_default = prepareRequest;
689
-
690
- // src/createDefaultRunner.ts
691
- var createDefaultRunner = (pool, options) => {
692
- const { twoStepsRequest } = options;
693
- const basicHandler = (type, options2) => {
694
- return async (params) => {
695
- const { data, existingRequest, noApproval } = params;
696
- const payload = prepareRequest_default({ type, data });
697
- const extra = { noApproval, existingRequest, twoStepsRequest, ...options2 };
698
- return performRequest(payload, pool, extra);
699
- };
700
- };
701
- const createAccount = async (params) => {
702
- const { account, data, tradelinkAM } = params;
703
- if ("readOnly" in account && account.readOnly) {
704
- const adminDevices = await pool.getOnboardingAdminDevices();
705
- const admin = await pool.login(adminDevices[0][1]);
706
- const payload = prepareRequest_default({ type: "CREATE_ACCOUNT", data });
707
- return admin.post("/dev/accounts", payload);
708
- }
709
- let res;
710
- try {
711
- res = await basicHandler("CREATE_ACCOUNT")(params);
712
- if (tradelinkAM) {
713
- const adminDevices = await pool.getOnboardingAdminDevices();
714
- const admin = await pool.login(adminDevices[0][1]);
715
- const reqResp = await admin.get(
716
- `/requests?page=1&type=ACTIVATE&target_id=${res.account.id}`
717
- );
718
- const requests = unwrapConnection(reqResp);
719
- const activationRequest = requests[0];
720
- if (!activationRequest) {
721
- throw new Error(`No account activation request found for account ${res.account.name}`);
722
- }
723
- if (!pool.apiGateway) {
724
- throw new Error("apiGateway URL is not set");
725
- }
726
- await reviewAPIRequest_default(
727
- {
728
- pool,
729
- requestID: activationRequest.id,
730
- apiUser: tradelinkAM,
731
- gate: pool.gate,
732
- apiGateway: pool.apiGateway,
733
- reviewType: "APPROVE"
734
- },
735
- { logger: SILENT_LOGGER }
736
- );
737
- }
738
- } catch (err) {
739
- if (err instanceof Error && err.name === "ACCOUNT_CHILD_ALREADY_EXISTED_EXCEPTION" && "contractAddress" in account && !!account.parentAccount) {
740
- const adminDevices = await pool.getOnboardingAdminDevices();
741
- const admin = await pool.login(adminDevices[0][1]);
742
- const parentAccountsConnection = await admin.network(
743
- "GET",
744
- `/accounts?name=${account.parentAccount}`
745
- );
746
- const parentAccountEdge = parentAccountsConnection.edges.find(
747
- (e) => e.node.name === account.parentAccount
748
- );
749
- invariant2(parentAccountEdge, `Parent account not found for ${account.name}`);
750
- const parentAccount = parentAccountEdge.node;
751
- const rawCurrencyQuery = `${parentAccount.currency}:${account.contractAddress}`;
752
- const currencyQuery = encodeURIComponent(rawCurrencyQuery);
753
- const potentialAccounts = await admin.network(
754
- "GET",
755
- `/accounts?currency=${currencyQuery}&index=${parentAccount.index}`
756
- );
757
- invariant2(
758
- potentialAccounts.edges.length === 1,
759
- `We should have one matching token account for ${currencyQuery} (index: ${parentAccount.index})`
760
- );
761
- const existingAccount = potentialAccounts.edges[0].node;
762
- const editParams = {
763
- ...params,
764
- data: { ...params.data, existingAccount }
765
- };
766
- res = await basicHandler("EDIT_ACCOUNT")(editParams);
767
- } else {
768
- throw err;
769
- }
770
- }
771
- if (params.waitForActive) {
772
- const accountId = res.target_id;
773
- const adminDevices = await pool.getOnboardingAdminDevices();
774
- const admin = await pool.login(adminDevices[0][1]);
775
- for (let i = 0; i < 60; i++) {
776
- const account2 = await admin.get(`/accounts/${accountId}`);
777
- if (account2.status === "ACTIVE") {
778
- res.account = account2;
779
- break;
780
- }
781
- await wait(3e3);
782
- }
783
- }
784
- return res;
785
- };
786
- const createUser = async (params) => {
787
- const { role, userID, name, device } = params;
788
- const type = role === "operator" ? "CREATE_OPERATOR" : "CREATE_ADMIN";
789
- const data = { userID, role, name };
790
- const payload = prepareRequest_default({ type, data });
791
- const extra = { noApproval: true };
792
- const req = await performRequest(payload, pool, extra);
793
- const res = await pool.registerDevice(device, req);
794
- req.user.pub_key = res.u2f_key.pubKey;
795
- if (!options.noApproval) {
796
- await pool.runWithQuorum((admin) => admin.approveRequest(req));
797
- }
798
- return req;
799
- };
800
- const createAPIUser = async (params, manifestFromGate) => {
801
- const { user, name, userID } = params;
802
- let request = manifestFromGate.rawData.pendingUserRequests.find((e) => e.user.username === name) || null;
803
- if (!request) {
804
- request = await performRequest(
805
- {
806
- type: "CREATE_OPERATOR",
807
- username: name,
808
- user_id: userID,
809
- is_api: true,
810
- view_all_override: user.viewAll
811
- },
812
- pool,
813
- { noApproval: true }
814
- );
815
- }
816
- if (request.status != "PENDING_APPROVAL")
817
- await pool.lamAPI.registerUser(name, request.url_id);
818
- if (!options.noApproval) {
819
- await pool.runWithQuorum((admin) => admin.approveRequest(request));
820
- }
821
- return request;
822
- };
823
- const createAPIV2User = async (params) => {
824
- const { name, publicKey, role } = params;
825
- const type = "CREATE_API_USER";
826
- const data = { publicKey, name, role };
827
- const payload = prepareRequest_default({ type, data });
828
- const extra = { noApproval: true };
829
- const req = await performRequest(payload, pool, extra);
830
- if (!options.noApproval) {
831
- await pool.runWithQuorum((admin) => admin.approveRequest(req));
832
- }
833
- return req;
834
- };
835
- const createAPIV2UserAccess = async (params) => {
836
- const { name } = params;
837
- const type = "CREATE_API_USER_ACCESS";
838
- const data = { name };
839
- const payload = prepareRequest_default({ type, data });
840
- const extra = { noApproval: true };
841
- return await performRequest(payload, pool, extra);
842
- };
843
- const createTradelinkEntity = async (params) => {
844
- const { tradelinkEntity, type } = params;
845
- const adminDevices = await pool.getOnboardingAdminDevices();
846
- const admin = await pool.login(adminDevices[0][1]);
847
- const data = {
848
- id: tradelinkEntity.id,
849
- name: tradelinkEntity.name,
850
- code: tradelinkEntity.code,
851
- logo_url: tradelinkEntity.logoUrl
852
- };
853
- return await admin.post(`/tradelink/${type}`, data);
854
- };
855
- const createTradelinkNetwork = async (params) => {
856
- const adminDevices = await pool.getOnboardingAdminDevices();
857
- const admin = await pool.login(adminDevices[0][1]);
858
- const data = {
859
- id: uuidv4(),
860
- custodian: params.custodians[0],
861
- exchanges: params.exchanges,
862
- asset_managers: params.assetManagers
863
- };
864
- await admin.network("DELETE", "/tradelink/network").catch(
865
- /* istanbul ignore next */
866
- (error) => {
867
- if (error.message.includes("404")) {
868
- } else {
869
- throw error;
870
- }
871
- }
872
- );
873
- return await admin.post(`/tradelink/network`, data);
874
- };
875
- const createTradelink = async (params) => {
876
- const adminDevices = await pool.getOnboardingAdminDevices();
877
- const admin = await pool.login(adminDevices[0][1]);
878
- const request = await admin.post(`/requests`, params);
879
- await pool.runWithQuorum((admin2) => admin2.approveRequest(request));
880
- return request;
881
- };
882
- const onboardTradelinkEntity = async (params) => {
883
- const { tradelinkEntity, type, tradelinkEntityApprover } = params;
884
- const adminDevices = await pool.getOnboardingAdminDevices();
885
- const admin = await pool.login(adminDevices[0][1]);
886
- let data = {};
887
- let request;
888
- if (type === "exchanges") {
889
- data = {
890
- type: "CREATE_TRADELINK_EXCHANGE",
891
- exchange_name: tradelinkEntity.name,
892
- operators: tradelinkEntity.operators,
893
- addresses: tradelinkEntity.addresses
894
- };
895
- request = await admin.post(`/requests`, data);
896
- } else {
897
- data = {
898
- type: "CREATE_TRADELINK_ASSET_MANAGER",
899
- asset_manager_name: tradelinkEntity.name,
900
- operators: tradelinkEntity.operators,
901
- addresses: tradelinkEntity.addresses
902
- };
903
- request = await admin.post(`/requests`, data);
904
- }
905
- await pool.runWithQuorum((admin2) => admin2.approveRequest(request));
906
- if (!pool.apiGateway) {
907
- throw new Error("apiGateway URL is not set");
908
- }
909
- await reviewAPIRequest_default(
910
- {
911
- pool,
912
- requestID: request.id,
913
- apiUser: tradelinkEntityApprover,
914
- gate: pool.gate,
915
- apiGateway: pool.apiGateway,
916
- reviewType: "APPROVE"
917
- },
918
- { logger: SILENT_LOGGER }
919
- );
920
- return request;
921
- };
922
- const editQuorum = async (params) => {
923
- const { quorum } = params;
924
- const payload = prepareRequest_default({
925
- type: "UPDATE_QUORUM",
926
- data: { quorum }
927
- });
928
- await performRequest(payload, pool);
929
- };
930
- const editWorkspaceRule = async (params) => {
931
- const { rule, usersByName } = params;
932
- const payload = {
933
- type: "EDIT_WORKSPACE_RULE",
934
- permission: rule.permission,
935
- edit_data: {
936
- steps: rule.steps.map((s) => {
937
- return {
938
- quorum: s.quorum,
939
- users: s.users.map((username) => {
940
- const user = usersByName[username];
941
- invariant2(user, `No user with name ${username}`);
942
- return user.pub_key;
943
- })
944
- };
945
- })
946
- }
947
- };
948
- await performRequest(payload, pool);
949
- };
950
- const runner = {
951
- editQuorum,
952
- editWorkspaceRule,
953
- createUser,
954
- createAPIUser,
955
- createAPIV2User,
956
- createAPIV2UserAccess,
957
- createGroup: basicHandler("CREATE_GROUP"),
958
- editGroup: basicHandler("EDIT_GROUP"),
959
- createAccount,
960
- editAccount: basicHandler("EDIT_ACCOUNT"),
961
- createWhitelist: basicHandler("CREATE_WHITELIST"),
962
- editWhitelist: basicHandler("EDIT_WHITELIST"),
963
- createVaultEntity: basicHandler("CREATE_ENTITY", {
964
- withoutHSM: true
965
- }),
966
- editVaultEntity: basicHandler("EDIT_ENTITY", {
967
- withoutHSM: true
968
- }),
969
- createExchange: basicHandler("IMPORT_EXCHANGE", {
970
- withoutHSM: true
971
- }),
972
- editExchange: basicHandler("IMPORT_EXCHANGE", {
973
- withoutHSM: true
974
- }),
975
- createPolicy: basicHandler("CREATE_POLICY"),
976
- createTradelink,
977
- createTradelinkEntity,
978
- onboardTradelinkEntity,
979
- createTradelinkNetwork
980
- };
981
- return runner;
982
- };
983
- var createDefaultRunner_default = createDefaultRunner;
984
-
985
- // src/apiUser/index.ts
986
- function getAPIHeader(bearerToken, workspace) {
987
- return {
988
- headers: {
989
- "X-Ledger-Workspace": workspace,
990
- "Content-Type": "application/json",
991
- Authorization: `Bearer ${bearerToken}`
992
- }
993
- };
994
- }
995
- async function regenerateCredentials(pool, apiNetwork, workspace, apiUser, logger) {
996
- const runner = createDefaultRunner_default(pool, {});
997
- const postApiUserAccess = {
998
- user: apiUser,
999
- publicKey: genKeys(apiUser.name).hexPubKey,
1000
- role: apiUser.role,
1001
- name: apiUser.name
1002
- };
1003
- const userAccessRequest = await runner.createAPIV2UserAccess(postApiUserAccess);
1004
- const apiUserAuth = {
1005
- api_key_id: userAccessRequest.api_key_id,
1006
- api_key_secret: userAccessRequest.api_key_secret
1007
- };
1008
- logger.info(
1009
- chalk`{red.bold IMPORTANT:} {red The API user credentials will not be displayed again so note them somewhere}`
1010
- );
1011
- logger.info(
1012
- JSON.stringify({
1013
- api_key_id: userAccessRequest.api_key_id,
1014
- api_key_secret: userAccessRequest.api_key_secret
1015
- })
1016
- );
1017
- return apiUserAuth;
1018
- }
1019
- async function getAuthTokens(apiNetwork, workspace, apiUserAuth) {
1020
- return await apiNetwork("POST", "/auth/token", apiUserAuth, {
1021
- headers: { "X-Ledger-Workspace": workspace }
1022
- });
1023
- }
1024
- async function authenticate(pool, apiNetwork, workspace, apiUser, logger) {
1025
- const apiUserAuth = await regenerateCredentials(pool, apiNetwork, workspace, apiUser, logger);
1026
- const bearerResp = await getAuthTokens(apiNetwork, workspace, apiUserAuth);
1027
- return bearerResp.access_token;
1028
- }
1029
- async function decodeChallenge({
1030
- apiNetwork,
1031
- workspace,
1032
- bearerToken,
1033
- requestID,
1034
- reviewType
1035
- }) {
1036
- let challengeUrl = `/requests/${requestID}/challenge`;
1037
- if (reviewType === "REJECT") {
1038
- challengeUrl = `${challengeUrl}/reject`;
1039
- }
1040
- const challengeResp = await apiNetwork(
1041
- "GET",
1042
- challengeUrl,
1043
- {},
1044
- getAPIHeader(bearerToken, workspace)
1045
- ).catch((error) => {
1046
- if (error.message.includes("Get abort challenge is only available for tradelink settlement")) {
1047
- return { challenge: "" };
1048
- }
1049
- throw error;
1050
- });
1051
- if (challengeResp.challenge === "") {
1052
- return {
1053
- challenge: "",
1054
- decodedChallenge: ""
1055
- };
1056
- }
1057
- return {
1058
- challenge: challengeResp.challenge,
1059
- decodedChallenge: decodeData(challengeResp.challenge)
1060
- };
1061
- }
1062
- async function signAndApprove({
1063
- apiNetwork,
1064
- workspace,
1065
- bearerToken,
1066
- requestID,
1067
- apiUser,
1068
- challenge,
1069
- reviewType
1070
- }) {
1071
- const keys = genKeys(apiUser.name);
1072
- let jws = "";
1073
- if (challenge !== "") {
1074
- jws = sign(String(keys.privateKey), challenge);
1075
- }
1076
- return await apiNetwork(
1077
- "POST",
1078
- `/requests/${requestID}/${reviewType.toLowerCase()}`,
1079
- { jws },
1080
- getAPIHeader(bearerToken, workspace)
1081
- );
1082
- }
1083
- async function getTradelinkPledge({
1084
- apiNetwork,
1085
- workspace,
1086
- gateAccount,
1087
- bearerToken,
1088
- exchange
1089
- }) {
1090
- const pledgesResp = await apiNetwork(
1091
- "GET",
1092
- `/pledges?account_id=${gateAccount.id}`,
1093
- {},
1094
- getAPIHeader(bearerToken, workspace)
1095
- );
1096
- const pledgeResp = pledgesResp.edges.find((p) => p.node.exchange.name == exchange);
1097
- if (!pledgeResp) {
1098
- throw new Error(`Exchange '${exchange}' not found`);
1099
- }
1100
- return pledgeResp.node;
1101
- }
1102
- async function getTradelinkRecipient({
1103
- pool,
1104
- gateAccount,
1105
- pledge
1106
- }) {
1107
- const exchangeWLId = pledge.exchange.whitelist_id;
1108
- const adminDevices = await pool.getOnboardingAdminDevices();
1109
- const admin = await pool.login(adminDevices[0][1]);
1110
- const wlResp = await admin.network(
1111
- "GET",
1112
- `/whitelists?id=${exchangeWLId}`
1113
- );
1114
- const wlAddress = wlResp.edges[0]?.node.addresses.find(
1115
- (a) => a.currency === gateAccount.currency
1116
- )?.address;
1117
- return String(wlAddress);
1118
- }
1119
-
1120
- // src/reviewAPIRequest.ts
1121
- async function reviewAPIRequest({
1122
- pool,
1123
- requestID,
1124
- apiUser,
1125
- gate,
1126
- apiGateway,
1127
- reviewType,
1128
- skipDecodeChallenge = false
1129
- }, { logger = SILENT_LOGGER2 }) {
1130
- const workspace = getWorkspaceFromGate(gate);
1131
- const apiNetwork = createNetwork({
1132
- baseURL: apiGateway
1133
- });
1134
- logger.info(`Authenticate for ${apiUser.name}`);
1135
- const bearerToken = await authenticate(pool, apiNetwork, workspace, apiUser, logger);
1136
- let apiChallenge = {
1137
- challenge: "",
1138
- decodedChallenge: ""
1139
- };
1140
- if (skipDecodeChallenge === false) {
1141
- logger.info("Decode challenge");
1142
- apiChallenge = await decodeChallenge({
1143
- apiNetwork,
1144
- workspace,
1145
- bearerToken,
1146
- requestID,
1147
- reviewType
1148
- });
1149
- }
1150
- logger.info(apiChallenge.decodedChallenge);
1151
- logger.info("Sign and approve");
1152
- return signAndApprove({
1153
- apiNetwork,
1154
- workspace,
1155
- bearerToken,
1156
- requestID,
1157
- apiUser,
1158
- challenge: apiChallenge.challenge,
1159
- reviewType
1160
- });
1161
- }
1162
- var reviewAPIRequest_default = reviewAPIRequest;
1163
-
1164
- export {
1165
- performRequest,
1166
- prepareRequest_default,
1167
- reviewAPIRequest_default,
1168
- createDefaultRunner_default,
1169
- getAuthTokens,
1170
- authenticate,
1171
- decodeChallenge,
1172
- signAndApprove,
1173
- getTradelinkPledge,
1174
- getTradelinkRecipient
1175
- };
1176
- //# sourceMappingURL=chunk-6TT6A6YA.mjs.map