@cardano-sdk/e2e 0.14.1 → 0.14.2

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 (119) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/factories.d.ts +3 -2
  3. package/dist/cjs/factories.d.ts.map +1 -1
  4. package/dist/cjs/factories.js +0 -1
  5. package/dist/cjs/factories.js.map +1 -1
  6. package/dist/cjs/scripts/mnemonic.js +2 -2
  7. package/dist/cjs/scripts/mnemonic.js.map +1 -1
  8. package/dist/cjs/tools/multi-delegation-data-gen/index.d.ts +2 -0
  9. package/dist/cjs/tools/multi-delegation-data-gen/index.d.ts.map +1 -0
  10. package/dist/cjs/tools/multi-delegation-data-gen/index.js +64 -0
  11. package/dist/cjs/tools/multi-delegation-data-gen/index.js.map +1 -0
  12. package/dist/cjs/tools/multi-delegation-data-gen/utils/config.d.ts +40 -0
  13. package/dist/cjs/tools/multi-delegation-data-gen/utils/config.d.ts.map +1 -0
  14. package/dist/cjs/tools/multi-delegation-data-gen/utils/config.js +110 -0
  15. package/dist/cjs/tools/multi-delegation-data-gen/utils/config.js.map +1 -0
  16. package/dist/cjs/tools/multi-delegation-data-gen/utils/files.d.ts +12 -0
  17. package/dist/cjs/tools/multi-delegation-data-gen/utils/files.d.ts.map +1 -0
  18. package/dist/cjs/tools/multi-delegation-data-gen/utils/files.js +66 -0
  19. package/dist/cjs/tools/multi-delegation-data-gen/utils/files.js.map +1 -0
  20. package/dist/cjs/tools/multi-delegation-data-gen/utils/index.d.ts +5 -0
  21. package/dist/cjs/tools/multi-delegation-data-gen/utils/index.d.ts.map +1 -0
  22. package/dist/cjs/tools/multi-delegation-data-gen/utils/index.js +21 -0
  23. package/dist/cjs/tools/multi-delegation-data-gen/utils/index.js.map +1 -0
  24. package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts +19 -0
  25. package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts.map +1 -0
  26. package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js +107 -0
  27. package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js.map +1 -0
  28. package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.d.ts +46 -0
  29. package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.d.ts.map +1 -0
  30. package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.js +172 -0
  31. package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.js.map +1 -0
  32. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  33. package/dist/cjs/util/index.d.ts +1 -0
  34. package/dist/cjs/util/index.d.ts.map +1 -1
  35. package/dist/cjs/util/index.js +1 -0
  36. package/dist/cjs/util/index.js.map +1 -1
  37. package/dist/cjs/util/util.d.ts +40 -0
  38. package/dist/cjs/util/util.d.ts.map +1 -0
  39. package/dist/cjs/util/util.js +171 -0
  40. package/dist/cjs/util/util.js.map +1 -0
  41. package/dist/esm/factories.d.ts +3 -2
  42. package/dist/esm/factories.d.ts.map +1 -1
  43. package/dist/esm/factories.js +0 -1
  44. package/dist/esm/factories.js.map +1 -1
  45. package/dist/esm/scripts/mnemonic.js +1 -1
  46. package/dist/esm/scripts/mnemonic.js.map +1 -1
  47. package/dist/esm/tools/multi-delegation-data-gen/index.d.ts +2 -0
  48. package/dist/esm/tools/multi-delegation-data-gen/index.d.ts.map +1 -0
  49. package/dist/esm/tools/multi-delegation-data-gen/index.js +59 -0
  50. package/dist/esm/tools/multi-delegation-data-gen/index.js.map +1 -0
  51. package/dist/esm/tools/multi-delegation-data-gen/utils/config.d.ts +40 -0
  52. package/dist/esm/tools/multi-delegation-data-gen/utils/config.d.ts.map +1 -0
  53. package/dist/esm/tools/multi-delegation-data-gen/utils/config.js +104 -0
  54. package/dist/esm/tools/multi-delegation-data-gen/utils/config.js.map +1 -0
  55. package/dist/esm/tools/multi-delegation-data-gen/utils/files.d.ts +12 -0
  56. package/dist/esm/tools/multi-delegation-data-gen/utils/files.d.ts.map +1 -0
  57. package/dist/esm/tools/multi-delegation-data-gen/utils/files.js +37 -0
  58. package/dist/esm/tools/multi-delegation-data-gen/utils/files.js.map +1 -0
  59. package/dist/esm/tools/multi-delegation-data-gen/utils/index.d.ts +5 -0
  60. package/dist/esm/tools/multi-delegation-data-gen/utils/index.d.ts.map +1 -0
  61. package/dist/esm/tools/multi-delegation-data-gen/utils/index.js +5 -0
  62. package/dist/esm/tools/multi-delegation-data-gen/utils/index.js.map +1 -0
  63. package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts +19 -0
  64. package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts.map +1 -0
  65. package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js +100 -0
  66. package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js.map +1 -0
  67. package/dist/esm/tools/multi-delegation-data-gen/utils/utils.d.ts +46 -0
  68. package/dist/esm/tools/multi-delegation-data-gen/utils/utils.d.ts.map +1 -0
  69. package/dist/esm/tools/multi-delegation-data-gen/utils/utils.js +153 -0
  70. package/dist/esm/tools/multi-delegation-data-gen/utils/utils.js.map +1 -0
  71. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  72. package/dist/esm/util/index.d.ts +1 -0
  73. package/dist/esm/util/index.d.ts.map +1 -1
  74. package/dist/esm/util/index.js +1 -0
  75. package/dist/esm/util/index.js.map +1 -1
  76. package/dist/esm/util/util.d.ts +40 -0
  77. package/dist/esm/util/util.d.ts.map +1 -0
  78. package/dist/esm/util/util.js +127 -0
  79. package/dist/esm/util/util.js.map +1 -0
  80. package/docker-compose.yml +3 -0
  81. package/local-network/README.md +1 -1
  82. package/local-network/scripts/make-babbage.sh +3 -1
  83. package/local-network/scripts/mint-handles.sh +52 -0
  84. package/local-network/scripts/mint-tokens.sh +1 -1
  85. package/local-network/scripts/start.sh +2 -0
  86. package/package.json +27 -18
  87. package/src/factories.ts +2 -3
  88. package/src/scripts/mnemonic.ts +1 -1
  89. package/src/tools/multi-delegation-data-gen/example.json +31 -0
  90. package/src/tools/multi-delegation-data-gen/index.ts +110 -0
  91. package/src/tools/multi-delegation-data-gen/utils/config.ts +112 -0
  92. package/src/tools/multi-delegation-data-gen/utils/files.ts +73 -0
  93. package/src/tools/multi-delegation-data-gen/utils/index.ts +4 -0
  94. package/src/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.ts +147 -0
  95. package/src/tools/multi-delegation-data-gen/utils/utils.ts +416 -0
  96. package/src/util/index.ts +1 -0
  97. package/{test → src/util}/util.ts +4 -20
  98. package/test/artillery/wallet-restoration/WalletRestoration.ts +11 -3
  99. package/test/load-test-custom/wallet-init/wallet-init.test.ts +1 -1
  100. package/test/load-test-custom/wallet-restoration/wallet-restoration.test.ts +3 -3
  101. package/test/load-testing/tx-submit-load.test.ts +1 -2
  102. package/test/local-network/register-pool.test.ts +10 -2
  103. package/test/long-running/cache-invalidation.test.ts +7 -3
  104. package/test/long-running/delegation-rewards.test.ts +7 -4
  105. package/test/util.test.ts +1 -1
  106. package/test/wallet/PersonalWallet/byron.test.ts +1 -2
  107. package/test/wallet/PersonalWallet/delegation.test.ts +10 -2
  108. package/test/wallet/PersonalWallet/delegationDistribution.test.ts +3 -15
  109. package/test/wallet/PersonalWallet/handle.test.ts +10 -2
  110. package/test/wallet/PersonalWallet/metadata.test.ts +1 -2
  111. package/test/wallet/PersonalWallet/mint.test.ts +9 -2
  112. package/test/wallet/PersonalWallet/multiAddress.test.ts +16 -2
  113. package/test/wallet/PersonalWallet/multisignature.test.ts +9 -2
  114. package/test/wallet/PersonalWallet/nft.test.ts +10 -2
  115. package/test/wallet/PersonalWallet/phase2validation.test.ts +1 -2
  116. package/test/wallet/PersonalWallet/pouchDbWalletStores.test.ts +1 -2
  117. package/test/wallet/PersonalWallet/txChainHistory.test.ts +1 -2
  118. package/test/wallet/PersonalWallet/txChaining.test.ts +1 -2
  119. package/test/wallet/PersonalWallet/unspendableUtxos.test.ts +1 -2
@@ -0,0 +1,416 @@
1
+ /* eslint-disable no-console, max-statements, max-params, @typescript-eslint/no-floating-promises */
2
+ import { ValueTransferConfig, configLoader } from './config';
3
+
4
+ import { AddressType, AsyncKeyAgent, GroupedAddress, util } from '@cardano-sdk/key-management';
5
+ import { Cardano } from '@cardano-sdk/core';
6
+ import { Files, Paths } from './files';
7
+ import {
8
+ KeyAgentFactoryProps,
9
+ MINUTE,
10
+ firstValueFromTimed,
11
+ getEnv,
12
+ getWallet,
13
+ submitAndConfirm,
14
+ walletReady,
15
+ walletVariables
16
+ } from '../../../';
17
+ import { Observable, filter, firstValueFrom, map } from 'rxjs';
18
+ import { PersonalWallet } from '@cardano-sdk/wallet';
19
+ import { TaskResult, TerminalProgressMonitor } from './terminal-progress-monitor';
20
+ import { logger } from '@cardano-sdk/util-dev';
21
+ import chalk from 'chalk';
22
+
23
+ /**
24
+ * Gets grouped addresses with increasing stake key index.
25
+ *
26
+ * @param keyAgent The key agent to be used to generate the addresses.
27
+ * @param addressCount Number of addresses to be generated.
28
+ */
29
+ export const getStakeAddresses = async (
30
+ keyAgent: AsyncKeyAgent,
31
+ addressCount: number
32
+ ): Promise<Array<GroupedAddress>> => {
33
+ const addresses = new Array<GroupedAddress>();
34
+
35
+ for (let i = 0; i < addressCount; ++i) {
36
+ const address = await keyAgent.deriveAddress(
37
+ {
38
+ index: 0,
39
+ type: AddressType.External
40
+ },
41
+ i
42
+ );
43
+
44
+ addresses.push(address);
45
+ }
46
+
47
+ return addresses;
48
+ };
49
+
50
+ /**
51
+ * Gets a list of the available pool.
52
+ *
53
+ * @param wallet The wallet to get the pools from.
54
+ * @param count The requested number of pools.
55
+ */
56
+ const getPoolIds = async (wallet: PersonalWallet, count: number): Promise<Cardano.StakePool[]> => {
57
+ const activePools = await wallet.stakePoolProvider.queryStakePools({
58
+ filters: { status: [Cardano.StakePoolStatus.Active] },
59
+ pagination: { limit: count, startAt: 0 }
60
+ });
61
+
62
+ return Array.from({ length: count }).map((_, index) => activePools.pageResults[index]);
63
+ };
64
+
65
+ /**
66
+ * Awaits for rewardAccounts$ to be registered, unregistered, as defined in states.
67
+ *
68
+ * @param rewardAccounts$ The reward accounts observable.
69
+ * @param statuses the statuses we are waiting for.
70
+ * @param timeout the amount of time we will wait for the status to change.
71
+ */
72
+ export const rewardAccountStatuses = async (
73
+ rewardAccounts$: Observable<Cardano.RewardAccountInfo[]>,
74
+ statuses: Cardano.StakeKeyStatus[],
75
+ timeout = MINUTE
76
+ ) =>
77
+ firstValueFromTimed(
78
+ rewardAccounts$.pipe(
79
+ map((accts) => accts.map(({ keyStatus }) => keyStatus)),
80
+ filter((statusArr) => statusArr.every((s) => statuses.includes(s)))
81
+ ),
82
+ `Timeout waiting for all reward accounts stake keys to be one of ${statuses.join('|')}`,
83
+ timeout
84
+ );
85
+
86
+ /**
87
+ * Registers and delegates reward accounts to different pools.
88
+ */
89
+ export const delegateToMultiplePools = async (
90
+ fundingWallet: PersonalWallet,
91
+ rewardAccounts: GroupedAddress[],
92
+ monitor: TerminalProgressMonitor
93
+ ) => {
94
+ const stakeKeyRegCertificates = rewardAccounts.map(({ rewardAccount }) =>
95
+ Cardano.createStakeKeyRegistrationCert(rewardAccount)
96
+ );
97
+ const poolIds = await getPoolIds(fundingWallet, rewardAccounts.length);
98
+ const delegationCertificates = rewardAccounts.map((account) =>
99
+ Cardano.createDelegationCert(account.rewardAccount, poolIds[account.stakeKeyDerivationPath!.index].id)
100
+ );
101
+
102
+ monitor.logInfo(
103
+ `Registering accounts: [${chalk.green(rewardAccounts.map(({ rewardAccount }) => rewardAccount).join(', '))}]`
104
+ );
105
+
106
+ monitor.startTask(
107
+ `Delegating to pools [${chalk.green(poolIds.map(({ id }) => id).join(', '))}] and registering ${chalk.green(
108
+ stakeKeyRegCertificates.length
109
+ )} stake keys`
110
+ );
111
+
112
+ const txBuilder = fundingWallet.createTxBuilder();
113
+
114
+ txBuilder.partialTxBody.certificates = [...stakeKeyRegCertificates, ...delegationCertificates];
115
+ const { tx } = await txBuilder.build().sign();
116
+ await submitAndConfirm(fundingWallet, tx);
117
+
118
+ monitor.endTask('Stake keys delegated', TaskResult.Success);
119
+
120
+ return poolIds;
121
+ };
122
+
123
+ const env = getEnv(walletVariables);
124
+
125
+ /**
126
+ * Formats a given number with the given number of decimals.
127
+ *
128
+ * @param num The number to be formatted.
129
+ * @param decimals The number of decimals.
130
+ */
131
+ const format = (num: number, decimals: number) =>
132
+ num.toLocaleString('en-US', {
133
+ maximumFractionDigits: decimals,
134
+ minimumFractionDigits: decimals
135
+ });
136
+
137
+ /**
138
+ * Loads the application configuration.
139
+ *
140
+ * @param monitor The progress monitor
141
+ */
142
+ export const loadConfiguration = async (monitor: TerminalProgressMonitor) => {
143
+ const configFilePath = process.argv[2];
144
+
145
+ monitor.startTask(`Loading config file from ${chalk.green(configFilePath)}.`);
146
+
147
+ configLoader.loadFile(configFilePath);
148
+ configLoader.validate({ allowed: 'strict' });
149
+
150
+ monitor.endTask(`Configuration loaded from ${chalk.green(configFilePath)}`, TaskResult.Success);
151
+
152
+ return configLoader.getProperties();
153
+ };
154
+
155
+ /**
156
+ * Waits until the funding wallet is ready.
157
+ *
158
+ * @param monitor The progress monitor
159
+ */
160
+ export const waitForFundingWallet = async (monitor: TerminalProgressMonitor): Promise<PersonalWallet> => {
161
+ monitor.startTask('Waiting for funding wallet to be ready.');
162
+
163
+ const fundingWallet = (await getWallet({ env, idx: 0, logger, name: 'Funding wallet', polling: { interval: 500 } }))
164
+ .wallet;
165
+
166
+ await walletReady(fundingWallet);
167
+
168
+ monitor.endTask('Funding wallet ready', TaskResult.Success);
169
+
170
+ return fundingWallet;
171
+ };
172
+
173
+ /**
174
+ * Creates a new delegation wallet.
175
+ *
176
+ * @param monitor The progress monitor.
177
+ */
178
+ export const createDelegationWallet = async (monitor: TerminalProgressMonitor) => {
179
+ monitor.startTask('Creating a random set of mnemonics for a brand-new wallet.');
180
+
181
+ const mnemonics = util.generateMnemonicWords();
182
+
183
+ monitor.endTask(`Mnemonics generated: [${chalk.green!(mnemonics.join(', '))}]`, TaskResult.Success);
184
+
185
+ const customKeyParams: KeyAgentFactoryProps = {
186
+ accountIndex: 0,
187
+ chainId: env.KEY_MANAGEMENT_PARAMS.chainId,
188
+ mnemonic: mnemonics.join(' '),
189
+ passphrase: 'some_passphrase'
190
+ };
191
+
192
+ return (
193
+ await getWallet({
194
+ customKeyParams,
195
+ env,
196
+ idx: 0,
197
+ logger,
198
+ name: 'Delegation Wallet',
199
+ polling: { interval: 500 }
200
+ })
201
+ ).wallet;
202
+ };
203
+
204
+ /**
205
+ * Transfers the starting funds from the funding wallet to the delegation wallet.
206
+ *
207
+ * @param fundingWallet The funding wallet contains the original funds, and serves as a faucet.
208
+ * @param delegationWallet The delegation wallet is our test wallet.
209
+ * @param startingFunds The initial funds to be transferred.
210
+ * @param monitor The progress monitor.
211
+ */
212
+ export const transferStartingFunds = async (
213
+ fundingWallet: PersonalWallet,
214
+ delegationWallet: PersonalWallet,
215
+ startingFunds: number,
216
+ monitor: TerminalProgressMonitor
217
+ ) => {
218
+ monitor.startTask(`Transferring ${startingFunds} to delegation wallet.`);
219
+
220
+ const delegationWalletAddress = await firstValueFrom(delegationWallet.addresses$);
221
+
222
+ const txBuilder = fundingWallet.createTxBuilder();
223
+ txBuilder.addOutput(
224
+ txBuilder.buildOutput().address(delegationWalletAddress[0].address).coin(BigInt(startingFunds)).toTxOut()
225
+ );
226
+
227
+ const { tx: signedTx } = await txBuilder.build().sign();
228
+
229
+ await submitAndConfirm(fundingWallet, signedTx);
230
+
231
+ monitor.endTask('Funds transferred', TaskResult.Success);
232
+ };
233
+
234
+ /**
235
+ * Generates a list of stake addresses.
236
+ *
237
+ * @param delegationWallet The delegation wallets.
238
+ * @param stakeKeyCount The number of stake keys to use in the generation of the addresses.
239
+ * @param monitor The progress monitor.
240
+ */
241
+ export const generateStakeAddresses = async (
242
+ delegationWallet: PersonalWallet,
243
+ stakeKeyCount: number,
244
+ monitor: TerminalProgressMonitor
245
+ ) => {
246
+ monitor.startTask('Generating stake addresses.');
247
+
248
+ const stakeAddresses = await getStakeAddresses(delegationWallet.keyAgent, stakeKeyCount);
249
+
250
+ monitor.endTask(
251
+ `Stake addresses generated: [${chalk.green!(stakeAddresses.map(({ rewardAccount }) => rewardAccount).join(', '))}]`,
252
+ TaskResult.Success
253
+ );
254
+
255
+ return stakeAddresses;
256
+ };
257
+
258
+ /**
259
+ * Distribute the stake among different addresses.
260
+ *
261
+ * @param delegationWallet The delegation wallets.
262
+ * @param startingFunds The total starting funds.
263
+ * @param stakeDistribution The stake distribution to be followed.
264
+ * @param stakeAddresses The list of stake addresses.
265
+ * @param monitor The progress monitor.
266
+ */
267
+ export const distributeStake = async (
268
+ delegationWallet: PersonalWallet,
269
+ startingFunds: number,
270
+ stakeDistribution: Array<number>,
271
+ stakeAddresses: Array<GroupedAddress>,
272
+ monitor: TerminalProgressMonitor
273
+ ) => {
274
+ // TODO: Replace with delegatePortfolio once LW-6702 is merged.
275
+ const totalWeight = stakeDistribution.reduce((sum, current) => sum + current, 0);
276
+ const stakeDistributionSsPercent = stakeDistribution.map((value) => value / totalWeight);
277
+ monitor.startTask(`Distribute ${startingFunds} among stake addresses [${stakeDistribution.join(', ')}].`);
278
+
279
+ const txBuilder = delegationWallet.createTxBuilder();
280
+
281
+ let i = 0;
282
+ const startingFundsMinusFee = startingFunds - 5_000_000;
283
+ for (const { address } of stakeAddresses) {
284
+ const coinsToBeDeposited = stakeDistributionSsPercent[i] * startingFundsMinusFee;
285
+ txBuilder.addOutput(txBuilder.buildOutput().address(address).coin(BigInt(coinsToBeDeposited)).toTxOut());
286
+ ++i;
287
+ }
288
+
289
+ const { tx: signedTx } = await txBuilder.build().sign();
290
+
291
+ await submitAndConfirm(delegationWallet, signedTx);
292
+
293
+ monitor.endTask('Funds distributed', TaskResult.Success);
294
+ };
295
+
296
+ /**
297
+ * Logs in the terminal and persist the current state of the wallet.
298
+ *
299
+ * @param delegationWallet The delegation wallet.
300
+ * @param iteration The current test iteration.
301
+ * @param outputPath The output path were to persist the state.
302
+ * @param monitor The progress monitor.
303
+ */
304
+ export const logState = async (
305
+ delegationWallet: PersonalWallet,
306
+ iteration: number,
307
+ outputPath: string,
308
+ monitor: TerminalProgressMonitor
309
+ ) => {
310
+ const paddedIter = `00000${iteration}`.slice(-4);
311
+ const delegationDistribution = await firstValueFrom(delegationWallet.delegation.distribution$);
312
+ const { coins: totalCoins } = await firstValueFrom(delegationWallet.balance.utxo.total$);
313
+ const utxos = await firstValueFrom(delegationWallet.utxo.total$);
314
+
315
+ monitor.logInfo(
316
+ `${paddedIter} - Total coins: ${totalCoins} - Distribution: [${[...delegationDistribution.values()]
317
+ .map(
318
+ (delegatedStake) =>
319
+ // eslint-disable-next-line sonarjs/no-nested-template-literals
320
+ `${delegatedStake.stake.toString()}(${chalk.green(`${format(delegatedStake.percentage * 100, 2)}%`)})`
321
+ )
322
+ .join(', ')}]`
323
+ );
324
+
325
+ const distributionCSV = Files.combine([outputPath, Paths.StakeDistribution]);
326
+ const utxoDirectory = Files.combine([outputPath, Paths.WalletUtxos]);
327
+ const utxosFile = Files.combine([utxoDirectory, `${paddedIter}.json`]);
328
+
329
+ Files.createFolder(outputPath);
330
+ Files.createFolder(utxoDirectory);
331
+
332
+ const csvEntries = [totalCoins, [...delegationDistribution.values()].map((delegatedStake) => delegatedStake.stake)];
333
+
334
+ Files.writeFile(distributionCSV, `${paddedIter},${csvEntries.join(',')}\n`, true);
335
+ Files.writeFile(
336
+ utxosFile,
337
+ JSON.stringify(utxos, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2)
338
+ );
339
+ };
340
+
341
+ /**
342
+ * Gets a random number between two intervals.
343
+ *
344
+ * @param min The lower bound value of te interval (inclusive).
345
+ * @param max The upper bound value of te interval (inclusive).
346
+ */
347
+ export const randomFromInterval = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min);
348
+
349
+ /**
350
+ * Creates a folder name using a timestamp.
351
+ */
352
+ export const getOutputPathName = () =>
353
+ new Date().toISOString().replace(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).*/, '$1_$2_$3_$4_$5_$6');
354
+
355
+ /**
356
+ * Transfer value from one wallet to another following the given value transfer configuration.
357
+ *
358
+ * @param wallet The source wallet.
359
+ * @param targetAddress The target wallet.
360
+ * @param config The value transfer configuration.
361
+ * @param currentIteration the current iteration.
362
+ */
363
+ const transferValue = async (
364
+ wallet: PersonalWallet,
365
+ targetAddress: Cardano.PaymentAddress,
366
+ config: ValueTransferConfig,
367
+ currentIteration: number
368
+ ) => {
369
+ const outputCount = randomFromInterval(config.count.min, config.count.max);
370
+ if (outputCount === 0 || config.period === 0 || currentIteration % config.period !== 0) return;
371
+
372
+ const txBuilder = wallet.createTxBuilder();
373
+
374
+ for (let i = 0; i < outputCount; ++i) {
375
+ const amountToBeGenerated = randomFromInterval(config.amount.min, config.amount.max);
376
+ txBuilder.addOutput(txBuilder.buildOutput().address(targetAddress).coin(BigInt(amountToBeGenerated)).toTxOut());
377
+ }
378
+
379
+ const { tx: signedTx } = await txBuilder.build().sign();
380
+
381
+ await submitAndConfirm(wallet, signedTx);
382
+ };
383
+
384
+ /**
385
+ * Generate and submit transaction following the given input and output configuration.
386
+ *
387
+ * This function will create on transaction transferring funds from the funding wallet to the
388
+ * delegation wallet (inputs), and one transaction transferring funds from the delegation wallet
389
+ * to the funding wallet (outputs).
390
+ *
391
+ * @param fundingWallet The funding wallet contains the original funds, and serves as a faucet.
392
+ * @param delegationWallet The delegation wallet is our test wallet.
393
+ * @param inputsConfig The configuration parameters for the input generation.
394
+ * @param outputsConfig The configuration parameters for the output generation.
395
+ * @param iteration Tue current iteration we are in.
396
+ * @param monitor The progress monitor.
397
+ */
398
+ export const sendTransactions = async (
399
+ fundingWallet: PersonalWallet,
400
+ delegationWallet: PersonalWallet,
401
+ inputsConfig: ValueTransferConfig,
402
+ outputsConfig: ValueTransferConfig,
403
+ iteration: number,
404
+ monitor: TerminalProgressMonitor
405
+ ) => {
406
+ const inputAddress = (await firstValueFrom(delegationWallet.addresses$))[0].address;
407
+ const outputAddress = (await firstValueFrom(fundingWallet.addresses$))[0].address;
408
+ const paddedIter = `00000${iteration}`.slice(-4);
409
+
410
+ monitor.startTask(`${paddedIter} - Generating incoming and outgoing transactions`);
411
+
412
+ await transferValue(fundingWallet, inputAddress, inputsConfig, iteration);
413
+ await transferValue(delegationWallet, outputAddress, outputsConfig, iteration);
414
+
415
+ monitor.endTask('', TaskResult.None);
416
+ };
package/src/util/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './StubKeyAgent';
2
2
  export * from './localNetworkChainId';
3
+ export * from './util';
@@ -1,8 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import * as Crypto from '@cardano-sdk/crypto';
3
3
  import * as envalid from 'envalid';
4
- import { AddressType, GroupedAddress, InMemoryKeyAgent, TransactionSigner } from '@cardano-sdk/key-management';
5
- import { AddressesModel } from './artillery/wallet-restoration/types';
6
4
  import { Cardano, createSlotEpochCalc } from '@cardano-sdk/core';
7
5
  import {
8
6
  EMPTY,
@@ -20,17 +18,12 @@ import {
20
18
  throwError,
21
19
  timeout
22
20
  } from 'rxjs';
23
- import {
24
- FAST_OPERATION_TIMEOUT_DEFAULT,
25
- SYNC_TIMEOUT_DEFAULT,
26
- TestWallet,
27
- faucetProviderFactory,
28
- getEnv,
29
- networkInfoProviderFactory,
30
- walletVariables
31
- } from '../src';
21
+ import { FAST_OPERATION_TIMEOUT_DEFAULT, SYNC_TIMEOUT_DEFAULT } from '../defaults';
32
22
  import { FinalizeTxProps, ObservableWallet, PersonalWallet } from '@cardano-sdk/wallet';
23
+ import { InMemoryKeyAgent, TransactionSigner } from '@cardano-sdk/key-management';
33
24
  import { InitializeTxProps } from '@cardano-sdk/tx-construction';
25
+ import { TestWallet, faucetProviderFactory, networkInfoProviderFactory } from '../factories';
26
+ import { getEnv, walletVariables } from '../environment';
34
27
  import { logger } from '@cardano-sdk/util-dev';
35
28
  import sortBy from 'lodash/sortBy';
36
29
 
@@ -317,12 +310,3 @@ export const burnTokens = async ({
317
310
  await submitAndConfirm(wallet, signedTx);
318
311
  await txConfirmed(wallet, signedTx);
319
312
  };
320
-
321
- export const mapToGroupedAddress = (addrModel: AddressesModel): GroupedAddress => ({
322
- accountIndex: 0,
323
- address: Cardano.PaymentAddress(addrModel.address),
324
- index: 0,
325
- networkId: addrModel.address.startsWith('addr_test') ? Cardano.NetworkId.Testnet : Cardano.NetworkId.Mainnet,
326
- rewardAccount: Cardano.RewardAccount(addrModel.stake_address),
327
- type: AddressType.External
328
- });
@@ -1,12 +1,20 @@
1
+ import { AddressType, GroupedAddress, util } from '@cardano-sdk/key-management';
1
2
  import { AddressesModel, WalletVars } from './types';
2
3
  import { Cardano } from '@cardano-sdk/core';
3
4
  import { FunctionHook } from '../artillery';
4
5
  import { Pool } from 'pg';
5
- import { StubKeyAgent, getEnv, getWallet, walletVariables } from '../../../src';
6
+ import { StubKeyAgent, getEnv, getWallet, waitForWalletStateSettle, walletVariables } from '../../../src';
6
7
  import { findAddressesWithRegisteredStakeKey } from './queries';
7
8
  import { logger } from '@cardano-sdk/util-dev';
8
- import { mapToGroupedAddress, waitForWalletStateSettle } from '../../util';
9
- import { util } from '@cardano-sdk/key-management';
9
+
10
+ export const mapToGroupedAddress = (addrModel: AddressesModel): GroupedAddress => ({
11
+ accountIndex: 0,
12
+ address: Cardano.PaymentAddress(addrModel.address),
13
+ index: 0,
14
+ networkId: addrModel.address.startsWith('addr_test') ? Cardano.NetworkId.Testnet : Cardano.NetworkId.Mainnet,
15
+ rewardAccount: Cardano.RewardAccount(addrModel.stake_address),
16
+ type: AddressType.External
17
+ });
10
18
 
11
19
  const env = getEnv([
12
20
  ...walletVariables,
@@ -23,9 +23,9 @@ import {
23
23
  stakePoolProviderFactory,
24
24
  txSubmitProviderFactory,
25
25
  utxoProviderFactory,
26
+ waitForWalletStateSettle,
26
27
  walletVariables
27
28
  } from '../../../src';
28
- import { waitForWalletStateSettle } from '../../util';
29
29
 
30
30
  // Example call that creates 5000 wallets in 10 minutes:
31
31
  // VIRTUAL_USERS_GENERATE_DURATION=600 VIRTUAL_USERS_COUNT=5000 yarn load-test-custom:wallet-init
@@ -3,13 +3,13 @@
3
3
  import * as dotenv from 'dotenv';
4
4
  import path from 'path';
5
5
  dotenv.config({ path: path.join(__dirname, '../../../.env') });
6
- import { Cardano } from '@cardano-sdk/core/dist/esm';
6
+ import { Cardano } from '@cardano-sdk/core';
7
7
  import { GroupedAddress, util } from '@cardano-sdk/key-management';
8
8
  import { Logger } from 'ts-log';
9
- import { MINUTE, StubKeyAgent, getEnv, getWallet, walletVariables } from '../../../src';
9
+ import { MINUTE, StubKeyAgent, getEnv, getWallet, waitForWalletStateSettle, walletVariables } from '../../../src';
10
10
  import { PersonalWallet } from '@cardano-sdk/wallet';
11
11
  import { logger } from '@cardano-sdk/util-dev';
12
- import { mapToGroupedAddress, waitForWalletStateSettle } from '../../util';
12
+ import { mapToGroupedAddress } from '../../artillery/wallet-restoration/WalletRestoration';
13
13
 
14
14
  /**
15
15
  * Env var MAX_USERS sets the maximum number of concurrent users to measure
@@ -7,9 +7,8 @@ import { RabbitMQContainer } from '../../../cardano-services/test/TxSubmit/rabbi
7
7
  import { ServiceNames } from '@cardano-sdk/cardano-services';
8
8
  import { createLogger } from '@cardano-sdk/util-dev';
9
9
  import { filter, firstValueFrom } from 'rxjs';
10
- import { getEnv, walletVariables } from '../../src';
10
+ import { getEnv, submitAndConfirm, walletVariables } from '../../src';
11
11
  import { getWallet } from '../../src/factories';
12
- import { submitAndConfirm } from '../util';
13
12
  import JSONBig from 'json-bigint';
14
13
  import path from 'path';
15
14
 
@@ -1,8 +1,16 @@
1
1
  /* eslint-disable max-statements */
2
2
  import { Cardano } from '@cardano-sdk/core';
3
- import { KeyAgentFactoryProps, TestWallet, getEnv, getWallet, walletVariables } from '../../src';
3
+ import {
4
+ KeyAgentFactoryProps,
5
+ TestWallet,
6
+ getEnv,
7
+ getWallet,
8
+ submitCertificate,
9
+ waitForWalletStateSettle,
10
+ walletReady,
11
+ walletVariables
12
+ } from '../../src';
4
13
  import { logger } from '@cardano-sdk/util-dev';
5
- import { submitCertificate, waitForWalletStateSettle, walletReady } from '../util';
6
14
 
7
15
  import { AddressType, KeyRole } from '@cardano-sdk/key-management';
8
16
  import { firstValueFrom } from 'rxjs';
@@ -1,14 +1,18 @@
1
1
  /* eslint-disable max-statements */
2
2
  import { AddressType, KeyRole } from '@cardano-sdk/key-management';
3
3
  import { Cardano } from '@cardano-sdk/core';
4
- import { KeyAgentFactoryProps, TestWallet, getEnv, getWallet, walletVariables } from '../../src';
5
4
  import {
5
+ KeyAgentFactoryProps,
6
+ TestWallet,
7
+ getEnv,
6
8
  getTxConfirmationEpoch,
9
+ getWallet,
7
10
  submitCertificate,
8
11
  waitForEpoch,
9
12
  waitForWalletStateSettle,
10
- walletReady
11
- } from '../util';
13
+ walletReady,
14
+ walletVariables
15
+ } from '../../src';
12
16
  import { logger } from '@cardano-sdk/util-dev';
13
17
 
14
18
  const env = getEnv(walletVariables);
@@ -1,15 +1,18 @@
1
1
  import { Cardano } from '@cardano-sdk/core';
2
2
  import { PersonalWallet } from '@cardano-sdk/wallet';
3
- import { TestWallet, getEnv, getWallet, walletVariables } from '../../src';
4
- import { firstValueFrom } from 'rxjs';
5
3
  import {
4
+ TestWallet,
5
+ getEnv,
6
6
  getTxConfirmationEpoch,
7
+ getWallet,
7
8
  requestCoins,
8
9
  runningAgainstLocalNetwork,
9
10
  submitAndConfirm,
10
11
  transferCoins,
11
- waitForEpoch
12
- } from '../util';
12
+ waitForEpoch,
13
+ walletVariables
14
+ } from '../../src';
15
+ import { firstValueFrom } from 'rxjs';
13
16
  import { logger } from '@cardano-sdk/util-dev';
14
17
  import { waitForWalletStateSettle } from '../../../wallet/test/util';
15
18
 
package/test/util.test.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BehaviorSubject, NEVER, of } from 'rxjs';
2
2
  import { Cardano } from '@cardano-sdk/core';
3
3
  import { ObservableWallet } from '@cardano-sdk/wallet';
4
- import { insufficientFundsMessage, walletReady } from './util';
4
+ import { insufficientFundsMessage, walletReady } from '../src';
5
5
 
6
6
  describe('util for e2e tests', () => {
7
7
  describe('walletReady', () => {
@@ -4,9 +4,8 @@ import { PersonalWallet } from '@cardano-sdk/wallet';
4
4
  import { createLogger } from '@cardano-sdk/util-dev';
5
5
  import { filter, firstValueFrom, map, take } from 'rxjs';
6
6
  import { getEnv, walletVariables } from '../../../src/environment';
7
- import { getWallet } from '../../../src';
7
+ import { getWallet, normalizeTxBody, walletReady } from '../../../src';
8
8
  import { isNotNil } from '@cardano-sdk/util';
9
- import { normalizeTxBody, walletReady } from '../../util';
10
9
 
11
10
  const env = getEnv(walletVariables);
12
11
  const logger = createLogger();
@@ -2,9 +2,17 @@
2
2
  import { BigIntMath } from '@cardano-sdk/util';
3
3
  import { Cardano } from '@cardano-sdk/core';
4
4
  import { ObservableWallet } from '@cardano-sdk/wallet';
5
- import { TX_TIMEOUT_DEFAULT, TestWallet, getEnv, getWallet, walletVariables } from '../../../src';
5
+ import {
6
+ TX_TIMEOUT_DEFAULT,
7
+ TestWallet,
8
+ firstValueFromTimed,
9
+ getEnv,
10
+ getWallet,
11
+ waitForWalletStateSettle,
12
+ walletReady,
13
+ walletVariables
14
+ } from '../../../src';
6
15
  import { combineLatest, filter, firstValueFrom } from 'rxjs';
7
- import { firstValueFromTimed, waitForWalletStateSettle, walletReady } from '../../util';
8
16
  import { logger } from '@cardano-sdk/util-dev';
9
17
 
10
18
  const env = getEnv(walletVariables);
@@ -1,11 +1,10 @@
1
1
  import { AddressType } from '@cardano-sdk/key-management';
2
2
  import { Cardano } from '@cardano-sdk/core';
3
3
  import { DelegatedStake, PersonalWallet, createUtxoBalanceByAddressTracker } from '@cardano-sdk/wallet';
4
- import { MINUTE, getWallet } from '../../../src';
4
+ import { MINUTE, firstValueFromTimed, getWallet, submitAndConfirm, walletReady } from '../../../src';
5
5
  import { Observable, filter, firstValueFrom, map, tap } from 'rxjs';
6
6
  import { Percent } from '@cardano-sdk/util';
7
7
  import { createLogger } from '@cardano-sdk/util-dev';
8
- import { firstValueFromTimed, submitAndConfirm, walletReady } from '../../util';
9
8
  import { getEnv, walletVariables } from '../../../src/environment';
10
9
  import delay from 'delay';
11
10
 
@@ -110,17 +109,6 @@ const deregisterAllStakeKeys = async (wallet: PersonalWallet): Promise<void> =>
110
109
  }
111
110
  };
112
111
 
113
- const createStakeKeyRegistrationCert = (rewardAccount: Cardano.RewardAccount): Cardano.Certificate => ({
114
- __typename: Cardano.CertificateType.StakeKeyRegistration,
115
- stakeKeyHash: Cardano.RewardAccount.toHash(rewardAccount)
116
- });
117
-
118
- const createDelegationCert = (rewardAccount: Cardano.RewardAccount, poolId: Cardano.PoolId): Cardano.Certificate => ({
119
- __typename: Cardano.CertificateType.StakeDelegation,
120
- poolId,
121
- stakeKeyHash: Cardano.RewardAccount.toHash(rewardAccount)
122
- });
123
-
124
112
  const getPoolIds = async (wallet: PersonalWallet, count: number): Promise<Cardano.StakePool[]> => {
125
113
  const activePools = await wallet.stakePoolProvider.queryStakePools({
126
114
  filters: { status: [Cardano.StakePoolStatus.Active] },
@@ -134,11 +122,11 @@ const delegateToMultiplePools = async (wallet: PersonalWallet) => {
134
122
  // Delegating to multiple pools should be added in TxBuilder. Doing it manually for now.
135
123
  // Prepare stakeKey registration certificates
136
124
  const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
137
- const stakeKeyRegCertificates = rewardAccounts.map(({ address }) => createStakeKeyRegistrationCert(address));
125
+ const stakeKeyRegCertificates = rewardAccounts.map(({ address }) => Cardano.createStakeKeyRegistrationCert(address));
138
126
 
139
127
  const poolIds = await getPoolIds(wallet, rewardAccounts.length);
140
128
  const delegationCertificates = rewardAccounts.map(({ address }, index) =>
141
- createDelegationCert(address, poolIds[index].id)
129
+ Cardano.createDelegationCert(address, poolIds[index].id)
142
130
  );
143
131
 
144
132
  logger.debug(