@cardano-sdk/e2e 0.43.0 → 0.44.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardano-sdk/e2e",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "End to end tests for the cardano-js-sdk packages.",
5
5
  "repository": "https://github.com/input-output-hk/cardano-js-sdk",
6
6
  "license": "Apache-2.0",
@@ -30,7 +30,7 @@
30
30
  "test:ogmios": "jest -c jest.config.js --forceExit --selectProjects ogmios --runInBand --verbose",
31
31
  "test:pg-boss": "jest -c jest.config.js --forceExit --selectProjects pg-boss --runInBand --verbose",
32
32
  "test:providers": "jest -c jest.config.js --forceExit --selectProjects providers --runInBand --verbose",
33
- "test:wallet": "yarn wait-for-network-init ; yarn test:wallet:epoch0 && yarn test:ws && { yarn wait-for-network-epoch-3 ; yarn test:wallet:epoch3 ; }",
33
+ "test:wallet": "yarn wait-for-network-init ; yarn test:wallet:epoch0 && { yarn wait-for-network-epoch-3 ; yarn test:wallet:epoch3 && yarn test:ws ; }",
34
34
  "test:wallet:epoch0": "jest -c jest.config.js --forceExit --selectProjects wallet_epoch_0 --runInBand --verbose",
35
35
  "test:wallet:epoch3": "jest -c jest.config.js --forceExit --selectProjects wallet_epoch_3 --runInBand --verbose",
36
36
  "test:wallet-real-ada": "NETWORK_SPEED=slow jest -c jest.config.js --forceExit --selectProjects wallet-real-ada --runInBand --verbose",
@@ -76,20 +76,20 @@
76
76
  "dependencies": {
77
77
  "@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.2",
78
78
  "@cardano-ogmios/client": "6.5.0",
79
- "@cardano-sdk/cardano-services": "~0.30.0",
80
- "@cardano-sdk/cardano-services-client": "~0.20.9",
81
- "@cardano-sdk/core": "~0.40.0",
79
+ "@cardano-sdk/cardano-services": "~0.31.0",
80
+ "@cardano-sdk/cardano-services-client": "~0.21.0",
81
+ "@cardano-sdk/core": "~0.41.0",
82
82
  "@cardano-sdk/crypto": "~0.1.30",
83
- "@cardano-sdk/hardware-ledger": "~0.12.4",
84
- "@cardano-sdk/hardware-trezor": "~0.6.4",
85
- "@cardano-sdk/input-selection": "~0.13.20",
86
- "@cardano-sdk/key-management": "~0.24.3",
87
- "@cardano-sdk/ogmios": "~0.18.0",
88
- "@cardano-sdk/tx-construction": "~0.21.5",
83
+ "@cardano-sdk/hardware-ledger": "~0.12.6",
84
+ "@cardano-sdk/hardware-trezor": "~0.6.6",
85
+ "@cardano-sdk/input-selection": "~0.13.22",
86
+ "@cardano-sdk/key-management": "~0.24.5",
87
+ "@cardano-sdk/ogmios": "~0.18.2",
88
+ "@cardano-sdk/tx-construction": "~0.21.7",
89
89
  "@cardano-sdk/util": "~0.15.5",
90
- "@cardano-sdk/util-dev": "~0.23.0",
91
- "@cardano-sdk/util-rxjs": "~0.7.33",
92
- "@cardano-sdk/wallet": "~0.44.4",
90
+ "@cardano-sdk/util-dev": "~0.23.2",
91
+ "@cardano-sdk/util-rxjs": "~0.7.35",
92
+ "@cardano-sdk/wallet": "~0.44.6",
93
93
  "@dcspark/cardano-multiplatform-lib-nodejs": "^3.1.1",
94
94
  "@shiroyasha9/axios-fetch-adapter": "1.0.3",
95
95
  "axios": "^1.7.4",
@@ -119,10 +119,10 @@
119
119
  "@babel/core": "^7.18.2",
120
120
  "@babel/preset-env": "^7.18.2",
121
121
  "@babel/preset-typescript": "^7.17.12",
122
- "@cardano-sdk/dapp-connector": "~0.12.37",
123
- "@cardano-sdk/projection": "~0.12.0",
124
- "@cardano-sdk/projection-typeorm": "~0.9.0",
125
- "@cardano-sdk/web-extension": "~0.34.3",
122
+ "@cardano-sdk/dapp-connector": "~0.12.39",
123
+ "@cardano-sdk/projection": "~0.12.2",
124
+ "@cardano-sdk/projection-typeorm": "~0.9.2",
125
+ "@cardano-sdk/web-extension": "~0.34.5",
126
126
  "@dcspark/cardano-multiplatform-lib-browser": "^3.1.1",
127
127
  "@emurgo/cardano-message-signing-asmjs": "^1.0.1",
128
128
  "@types/bunyan": "^1.8.8",
@@ -182,5 +182,5 @@
182
182
  "publishConfig": {
183
183
  "access": "public"
184
184
  },
185
- "gitHead": "58513e2ae961e81bd0f168e3d65f29b15aa4ff87"
185
+ "gitHead": "7b57a20fa480214f31a2773e7da732f2572243ce"
186
186
  }
package/src/factories.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ // cSpell:ignore dcspark ledgerjs multiplatform shiroyasha vespaiach
2
3
  import * as CML from '@dcspark/cardano-multiplatform-lib-nodejs';
3
4
  import * as Crypto from '@cardano-sdk/crypto';
4
5
  import {
@@ -64,9 +65,10 @@ const customHttpFetchAdapter = isNodeJs ? undefined : require('@shiroyasha9/axio
64
65
  const HTTP_PROVIDER = 'http';
65
66
  const OGMIOS_PROVIDER = 'ogmios';
66
67
  const STUB_PROVIDER = 'stub';
67
- const MISSING_URL_PARAM = 'Missing URL';
68
68
  const WS_PROVIDER = 'ws';
69
69
 
70
+ const MISSING_URL_PARAM = 'Missing URL';
71
+
70
72
  export type CreateKeyAgent = (dependencies: KeyAgentDependencies) => Promise<AsyncKeyAgent>;
71
73
  export const keyManagementFactory = new ProviderFactory<CreateKeyAgent>();
72
74
  export const assetProviderFactory = new ProviderFactory<AssetProvider>();
@@ -93,6 +95,25 @@ addressDiscoveryFactory.register(
93
95
  bip32Ed25519Factory.register('CML', async () => new Crypto.CmlBip32Ed25519(CML));
94
96
  bip32Ed25519Factory.register('Sodium', async () => new Crypto.SodiumBip32Ed25519());
95
97
 
98
+ // Web Socket
99
+
100
+ let wsClient: CardanoWsClient;
101
+
102
+ const getWsClient = async (logger: Logger) => {
103
+ if (wsClient) return wsClient;
104
+
105
+ const env = getEnv(walletVariables);
106
+ const chainHistoryProvider = await chainHistoryProviderFactory.create(
107
+ HTTP_PROVIDER,
108
+ env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
109
+ logger
110
+ );
111
+
112
+ if (env.WS_PROVIDER_URL === undefined) throw new Error(`${networkInfoHttpProvider.name}: ${MISSING_URL_PARAM}`);
113
+
114
+ return (wsClient = new CardanoWsClient({ chainHistoryProvider, logger }, { url: new URL(env.WS_PROVIDER_URL) }));
115
+ };
116
+
96
117
  // Asset providers
97
118
 
98
119
  assetProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<AssetProvider> => {
@@ -120,6 +141,11 @@ chainHistoryProviderFactory.register(
120
141
  }
121
142
  );
122
143
 
144
+ chainHistoryProviderFactory.register(
145
+ WS_PROVIDER,
146
+ async (_params: any, logger: Logger) => (await getWsClient(logger)).chainHistoryProvider
147
+ );
148
+
123
149
  networkInfoProviderFactory.register(
124
150
  HTTP_PROVIDER,
125
151
  async (params: any, logger: Logger): Promise<NetworkInfoProvider> => {
@@ -131,15 +157,10 @@ networkInfoProviderFactory.register(
131
157
  }
132
158
  );
133
159
 
134
- networkInfoProviderFactory.register(WS_PROVIDER, (_params: any, logger: Logger): Promise<NetworkInfoProvider> => {
135
- const env = getEnv(walletVariables);
136
-
137
- if (env.WS_PROVIDER_URL === undefined) throw new Error(`${networkInfoHttpProvider.name}: ${MISSING_URL_PARAM}`);
138
-
139
- const wsClient = new CardanoWsClient({ logger }, { url: new URL(env.WS_PROVIDER_URL) });
140
-
141
- return Promise.resolve(wsClient.networkInfoProvider);
142
- });
160
+ networkInfoProviderFactory.register(
161
+ WS_PROVIDER,
162
+ async (_params: any, logger: Logger) => (await getWsClient(logger)).networkInfoProvider
163
+ );
143
164
 
144
165
  rewardsProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<RewardsProvider> => {
145
166
  if (params.baseUrl === undefined) throw new Error(`${rewardsHttpProvider.name}: ${MISSING_URL_PARAM}`);
@@ -191,6 +212,11 @@ utxoProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger):
191
212
  });
192
213
  });
193
214
 
215
+ utxoProviderFactory.register(
216
+ WS_PROVIDER,
217
+ async (_params: any, logger: Logger) => (await getWsClient(logger)).utxoProvider
218
+ );
219
+
194
220
  handleProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<HandleProvider> => {
195
221
  if (params.baseUrl === undefined) throw new Error(`${handleHttpProvider.name}: ${MISSING_URL_PARAM}`);
196
222
 
@@ -245,7 +245,7 @@ const syncWallet = ({ wallet, poolAddress }) => {
245
245
  if (RUN_MODE === RunMode.Restore) {
246
246
  sdkCom.stakePoolSearch(poolAddress);
247
247
  }
248
- sdkCom.stats();
248
+ sdkCom.stakePoolStats();
249
249
 
250
250
  // Consider the wallet synced by tracking its first address
251
251
  syncedWallets.add(addresses[0]);
@@ -1,15 +1,25 @@
1
+ // cSpell:ignore loadimpact
2
+
1
3
  import * as k6Utils from '../../../../util-dev/dist/cjs/k6-utils.js';
2
4
  import { Counter, Trend } from 'k6/metrics';
5
+ import { SharedArray } from 'k6/data';
3
6
  import { check } from 'k6';
4
7
  import ws from 'k6/ws';
5
8
 
6
- // eslint-disable-next-line no-undef
7
- const { WALLETS } = Object.assign({ WALLETS: '10000' }, __ENV);
8
- // eslint-disable-next-line no-undef
9
- const dut = k6Utils.getDut(__ENV);
9
+ const { HD_ACTIVE_ADDR_COUNT, HD_MAX_TX_HISTORY, TARGET_NET, WALLETS } = Object.assign(
10
+ { HD_ACTIVE_ADDR_COUNT: '10', HD_MAX_TX_HISTORY: '100', TARGET_NET: 'mainnet', WALLETS: '100' },
11
+ // eslint-disable-next-line no-undef
12
+ __ENV
13
+ );
10
14
 
15
+ // eslint-disable-next-line no-undef
16
+ const dut = k6Utils.getDut(__ENV, { networks: ['mainnet', 'preprod'] });
11
17
  const url = `wss://${dut}/ws`;
12
18
 
19
+ const activeAddrCount = Number.parseInt(HD_ACTIVE_ADDR_COUNT, 10);
20
+ const maxTxHistory = Number.parseInt(HD_MAX_TX_HISTORY, 10);
21
+ const numWallets = Number.parseInt(WALLETS, 10);
22
+
13
23
  export const options = {
14
24
  ext: {
15
25
  loadimpact: {
@@ -21,28 +31,84 @@ export const options = {
21
31
  connections: {
22
32
  executor: 'ramping-vus',
23
33
  gracefulRampDown: '0s',
24
- gracefulStop: '120s',
25
- stages: [{ duration: '3s', target: Number.parseInt(WALLETS, 10) }],
26
- startVUs: 10
34
+ gracefulStop: '10m',
35
+ stages: [{ duration: '3s', target: numWallets }],
36
+ startVUs: 1
27
37
  }
28
38
  }
29
39
  };
30
40
 
41
+ /** Wallet addresses extracted from the JSON dump file */
42
+ const fileName = `../../dump/addresses/${TARGET_NET}.json`;
43
+ // eslint-disable-next-line no-undef
44
+ const walletsOrig = new SharedArray('walletsData', () => JSON.parse(open(fileName)));
45
+
46
+ export const setup = () => {
47
+ check(
48
+ undefined,
49
+ Object.fromEntries(
50
+ [`Number of wallets: ${numWallets}`, `Max transactions per wallet: ${maxTxHistory}`].map((_) => [_, () => true])
51
+ )
52
+ );
53
+
54
+ // Remove "big transaction history wallets"
55
+ const filteredWallets = walletsOrig.filter(({ tx_count }) => tx_count < maxTxHistory);
56
+ // Create chunks of `activeAddrCount` addresses per HD wallet
57
+ const wallets = k6Utils.chunkArray(filteredWallets, activeAddrCount);
58
+
59
+ return { wallets: wallets.slice(0, numWallets) };
60
+ };
61
+
31
62
  const operationalTrend = new Trend('_operational', true);
63
+ const syncTrend = new Trend('_sync', true);
64
+ const syncCount = new Counter('_sync_count');
65
+ const transactionsTrend = new Trend('_transactions_per_wallet');
32
66
  const unexpectedCloseCounter = new Counter('_unexpected_close');
33
67
 
34
- export const run = () => {
68
+ const getDummyAddr = (addr, idx, suffix = 'mh') => {
69
+ const last3Chars = addr.slice(-3);
70
+ const updateChars = last3Chars !== `${suffix}${idx}` ? `${suffix}${idx}` : `${idx}${suffix}`;
71
+ return addr.slice(0, -3) + updateChars;
72
+ };
73
+
74
+ export const run = ({ wallets }) => {
35
75
  const begin = Date.now();
76
+ // eslint-disable-next-line no-undef
77
+ const vu = __VU;
78
+ const wallet = wallets[vu % wallets.length]; // each wallet is a collection of addresses
36
79
 
37
80
  const res = ws.connect(url, null, (socket) => {
38
81
  let closed = false;
39
- let firstMessage = true;
82
+ let requestId = 0;
83
+ let transactionsCount = 0;
40
84
 
41
- socket.on('message', () => {
42
- if (firstMessage) {
43
- operationalTrend.add(Date.now() - begin);
44
- firstMessage = false;
85
+ const nextAddress = () => {
86
+ // Simplified address discovery with 50 fake addresses
87
+ if (++requestId > wallet.length + 50) {
88
+ transactionsTrend.add(transactionsCount);
89
+ syncTrend.add(Date.now() - begin);
90
+ syncCount.add(1);
91
+
92
+ return socket.setTimeout(() => {
93
+ closed = true;
94
+ socket.close();
95
+ }, 1000);
45
96
  }
97
+
98
+ const address =
99
+ requestId <= wallet.length
100
+ ? wallet[requestId - 1].address
101
+ : getDummyAddr(wallet[0].address, requestId - wallet.length);
102
+
103
+ socket.send(JSON.stringify({ requestId, txsByAddresses: { addresses: [address], lower: 0 } }));
104
+ };
105
+
106
+ socket.on('message', (message) => {
107
+ const { clientId, responseTo, transactions } = JSON.parse(message);
108
+
109
+ if (clientId) operationalTrend.add(Date.now() - begin);
110
+ if (clientId || responseTo) nextAddress();
111
+ if (transactions) transactionsCount += transactions.length;
46
112
  });
47
113
 
48
114
  // Count unexpected close
@@ -51,13 +117,11 @@ export const run = () => {
51
117
  });
52
118
 
53
119
  // Heartbeat
54
- socket.setTimeout(() => socket.send('{}'), 30 * 1000);
55
-
56
- // End the test after 80"
57
- socket.setTimeout(() => {
58
- closed = true;
59
- socket.close();
60
- }, 80 * 1000);
120
+ const heartbeat = () => {
121
+ socket.send('{}');
122
+ socket.setTimeout(heartbeat, 30 * 1000);
123
+ };
124
+ heartbeat();
61
125
  });
62
126
 
63
127
  check(res, { 'status is 101': (r) => r && r.status === 101 });
@@ -1,13 +1,15 @@
1
- import { CardanoWsClient } from '@cardano-sdk/cardano-services-client';
1
+ import { CardanoWsClient, chainHistoryHttpProvider } from '@cardano-sdk/cardano-services-client';
2
2
  import { getEnv, walletVariables } from '../../src';
3
3
  import { logger } from '@cardano-sdk/util-dev';
4
4
 
5
5
  const env = getEnv([...walletVariables]);
6
6
 
7
7
  describe('Web Socket', () => {
8
+ const chainHistoryProvider = chainHistoryHttpProvider({ logger, ...env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS });
8
9
  let client: CardanoWsClient;
9
10
 
10
- const openClient = () => (client = new CardanoWsClient({ logger }, { url: new URL(env.WS_PROVIDER_URL) }));
11
+ const openClient = () =>
12
+ (client = new CardanoWsClient({ chainHistoryProvider, logger }, { url: new URL(env.WS_PROVIDER_URL) }));
11
13
 
12
14
  const closeClient = () => (client ? client.close() : Promise.resolve());
13
15
 
@@ -451,8 +451,8 @@ describe('PersonalWallet/conwayTransactions', () => {
451
451
  });
452
452
 
453
453
  describe('with proposal procedure', () => {
454
- let actionId: Cardano.GovernanceActionId;
455
454
  let confirmedTx: Cardano.HydratedTx;
455
+ let id: Cardano.TransactionId;
456
456
  let proposalProcedures: Cardano.ProposalProcedure[];
457
457
 
458
458
  beforeAll(async () => {
@@ -519,10 +519,7 @@ describe('PersonalWallet/conwayTransactions', () => {
519
519
  .customize(({ txBody }) => ({ ...txBody, proposalProcedures }))
520
520
  .build()
521
521
  .sign();
522
- const [id, tx] = await submitAndConfirm(wallet, signedTx.tx, 1);
523
- confirmedTx = tx;
524
-
525
- actionId = { actionIndex: 0, id };
522
+ [id, confirmedTx] = await submitAndConfirm(wallet, signedTx.tx, 1);
526
523
  });
527
524
 
528
525
  it('parameter_change_action correctly submits protocol parameters update', () => {
@@ -533,7 +530,10 @@ describe('PersonalWallet/conwayTransactions', () => {
533
530
  const votingProcedures: Cardano.VotingProcedures = [
534
531
  {
535
532
  voter: { __typename: VoterType.dRepKeyHash, credential: dRepCredential },
536
- votes: [{ actionId, votingProcedure: { anchor, vote: Vote.abstain } }]
533
+ votes: [
534
+ { actionId: { actionIndex: 0, id }, votingProcedure: { anchor, vote: Vote.abstain } },
535
+ { actionId: { actionIndex: 1, id }, votingProcedure: { anchor: null, vote: Vote.yes } }
536
+ ]
537
537
  }
538
538
  ];
539
539
  const signedTx = await dRepWallet