@cardano-sdk/e2e 0.45.4 → 0.47.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/.env.example +13 -10
- package/CHANGELOG.md +22 -0
- package/README.md +2 -0
- package/dist/cjs/environment.d.ts +4 -2
- package/dist/cjs/environment.d.ts.map +1 -1
- package/dist/cjs/environment.js +4 -0
- package/dist/cjs/environment.js.map +1 -1
- package/dist/cjs/factories.d.ts +4 -1
- package/dist/cjs/factories.d.ts.map +1 -1
- package/dist/cjs/factories.js +46 -1
- package/dist/cjs/factories.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/environment.d.ts +4 -2
- package/dist/esm/environment.d.ts.map +1 -1
- package/dist/esm/environment.js +4 -0
- package/dist/esm/environment.js.map +1 -1
- package/dist/esm/factories.d.ts +4 -1
- package/dist/esm/factories.d.ts.map +1 -1
- package/dist/esm/factories.js +46 -1
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -20
- package/src/environment.ts +4 -0
- package/src/factories.ts +97 -0
- package/src/scripts/generate-dotenv.sh +3 -0
- package/test/blockfrost/queryTransactions.test.ts +4 -9
- package/test/load-test-custom/wallet-init/wallet-init.test.ts +6 -0
- package/test/wallet_epoch_0/PersonalWallet/multiAddress.test.ts +1 -0
- package/test/wallet_epoch_3/PersonalWallet/drepRetirement.test.ts +296 -0
- package/test/blockfrost-providers/networkInfo.test.ts +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardano-sdk/e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.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",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"load-test-custom:wallet-restoration": "ts-node test/load-test-custom/wallet-restoration/wallet-restoration.test.ts",
|
|
24
24
|
"test": "echo 'test' command not implemented yet",
|
|
25
25
|
"test:blockfrost": "jest -c jest.config.js --forceExit --selectProjects blockfrost --runInBand --verbose",
|
|
26
|
-
"test:blockfrost:providers": "jest -c jest.config.js --forceExit --selectProjects blockfrost-providers --runInBand --verbose",
|
|
27
26
|
"test:utils": "jest -c jest.config.js --forceExit --selectProjects utils --verbose",
|
|
28
27
|
"test:long-running": "jest -c jest.config.js --forceExit --selectProjects long-running --runInBand --verbose",
|
|
29
28
|
"test:local-network": "jest -c jest.config.js --forceExit --selectProjects local-network --runInBand --verbose",
|
|
@@ -76,20 +75,20 @@
|
|
|
76
75
|
"dependencies": {
|
|
77
76
|
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.4",
|
|
78
77
|
"@cardano-ogmios/client": "6.9.0",
|
|
79
|
-
"@cardano-sdk/cardano-services": "~0.
|
|
80
|
-
"@cardano-sdk/cardano-services-client": "~0.
|
|
81
|
-
"@cardano-sdk/core": "~0.
|
|
82
|
-
"@cardano-sdk/crypto": "~0.1.
|
|
83
|
-
"@cardano-sdk/hardware-ledger": "~0.12.
|
|
84
|
-
"@cardano-sdk/hardware-trezor": "~0.6.
|
|
85
|
-
"@cardano-sdk/input-selection": "~0.13.
|
|
86
|
-
"@cardano-sdk/key-management": "~0.24.
|
|
87
|
-
"@cardano-sdk/ogmios": "~0.18.
|
|
88
|
-
"@cardano-sdk/tx-construction": "~0.
|
|
78
|
+
"@cardano-sdk/cardano-services": "~0.33.1",
|
|
79
|
+
"@cardano-sdk/cardano-services-client": "~0.23.1",
|
|
80
|
+
"@cardano-sdk/core": "~0.42.0",
|
|
81
|
+
"@cardano-sdk/crypto": "~0.1.32",
|
|
82
|
+
"@cardano-sdk/hardware-ledger": "~0.12.15",
|
|
83
|
+
"@cardano-sdk/hardware-trezor": "~0.6.14",
|
|
84
|
+
"@cardano-sdk/input-selection": "~0.13.30",
|
|
85
|
+
"@cardano-sdk/key-management": "~0.24.12",
|
|
86
|
+
"@cardano-sdk/ogmios": "~0.18.15",
|
|
87
|
+
"@cardano-sdk/tx-construction": "~0.22.0",
|
|
89
88
|
"@cardano-sdk/util": "~0.15.5",
|
|
90
|
-
"@cardano-sdk/util-dev": "~0.
|
|
91
|
-
"@cardano-sdk/util-rxjs": "~0.7.
|
|
92
|
-
"@cardano-sdk/wallet": "~0.
|
|
89
|
+
"@cardano-sdk/util-dev": "~0.24.0",
|
|
90
|
+
"@cardano-sdk/util-rxjs": "~0.7.43",
|
|
91
|
+
"@cardano-sdk/wallet": "~0.45.0",
|
|
93
92
|
"@dcspark/cardano-multiplatform-lib-nodejs": "^3.1.1",
|
|
94
93
|
"@shiroyasha9/axios-fetch-adapter": "1.0.3",
|
|
95
94
|
"axios": "^1.7.4",
|
|
@@ -119,10 +118,10 @@
|
|
|
119
118
|
"@babel/core": "^7.18.2",
|
|
120
119
|
"@babel/preset-env": "^7.18.2",
|
|
121
120
|
"@babel/preset-typescript": "^7.17.12",
|
|
122
|
-
"@cardano-sdk/dapp-connector": "~0.12.
|
|
123
|
-
"@cardano-sdk/projection": "~0.12.
|
|
124
|
-
"@cardano-sdk/projection-typeorm": "~0.9.
|
|
125
|
-
"@cardano-sdk/web-extension": "~0.34.
|
|
121
|
+
"@cardano-sdk/dapp-connector": "~0.12.46",
|
|
122
|
+
"@cardano-sdk/projection": "~0.12.15",
|
|
123
|
+
"@cardano-sdk/projection-typeorm": "~0.9.15",
|
|
124
|
+
"@cardano-sdk/web-extension": "~0.34.23",
|
|
126
125
|
"@dcspark/cardano-multiplatform-lib-browser": "^3.1.1",
|
|
127
126
|
"@emurgo/cardano-message-signing-asmjs": "^1.0.1",
|
|
128
127
|
"@types/bunyan": "^1.8.8",
|
|
@@ -182,5 +181,5 @@
|
|
|
182
181
|
"publishConfig": {
|
|
183
182
|
"access": "public"
|
|
184
183
|
},
|
|
185
|
-
"gitHead": "
|
|
184
|
+
"gitHead": "cfb81dc2bf655e0a4d433b7c13a2aaa494510444"
|
|
186
185
|
}
|
package/src/environment.ts
CHANGED
|
@@ -92,6 +92,8 @@ const validators = {
|
|
|
92
92
|
TEST_CLIENT_ASSET_PROVIDER_PARAMS: providerParams(),
|
|
93
93
|
TEST_CLIENT_CHAIN_HISTORY_PROVIDER: str(),
|
|
94
94
|
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS: providerParams(),
|
|
95
|
+
TEST_CLIENT_DREP_PROVIDER: str({ choices: ['blockfrost'] }),
|
|
96
|
+
TEST_CLIENT_DREP_PROVIDER_PARAMS: providerParams(),
|
|
95
97
|
TEST_CLIENT_HANDLE_PROVIDER: str(),
|
|
96
98
|
TEST_CLIENT_HANDLE_PROVIDER_PARAMS: providerParams(),
|
|
97
99
|
TEST_CLIENT_NETWORK_INFO_PROVIDER: str(),
|
|
@@ -145,6 +147,8 @@ export const walletVariables = [
|
|
|
145
147
|
'TEST_CLIENT_ASSET_PROVIDER_PARAMS',
|
|
146
148
|
'TEST_CLIENT_CHAIN_HISTORY_PROVIDER',
|
|
147
149
|
'TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS',
|
|
150
|
+
'TEST_CLIENT_DREP_PROVIDER',
|
|
151
|
+
'TEST_CLIENT_DREP_PROVIDER_PARAMS',
|
|
148
152
|
'TEST_CLIENT_HANDLE_PROVIDER',
|
|
149
153
|
'TEST_CLIENT_HANDLE_PROVIDER_PARAMS',
|
|
150
154
|
'KEY_MANAGEMENT_PARAMS',
|
package/src/factories.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
AssetProvider,
|
|
19
19
|
Cardano,
|
|
20
20
|
ChainHistoryProvider,
|
|
21
|
+
DRepProvider,
|
|
21
22
|
HandleProvider,
|
|
22
23
|
NetworkInfoProvider,
|
|
23
24
|
ProviderFactory,
|
|
@@ -37,7 +38,13 @@ import {
|
|
|
37
38
|
} from '@cardano-sdk/key-management';
|
|
38
39
|
import {
|
|
39
40
|
BlockfrostAssetProvider,
|
|
41
|
+
BlockfrostChainHistoryProvider,
|
|
40
42
|
BlockfrostClient,
|
|
43
|
+
BlockfrostDRepProvider,
|
|
44
|
+
BlockfrostNetworkInfoProvider,
|
|
45
|
+
BlockfrostRewardsProvider,
|
|
46
|
+
BlockfrostTxSubmitProvider,
|
|
47
|
+
BlockfrostUtxoProvider,
|
|
41
48
|
CardanoWsClient,
|
|
42
49
|
assetInfoHttpProvider,
|
|
43
50
|
chainHistoryHttpProvider,
|
|
@@ -76,6 +83,7 @@ export type CreateKeyAgent = (dependencies: KeyAgentDependencies) => Promise<Asy
|
|
|
76
83
|
export const keyManagementFactory = new ProviderFactory<CreateKeyAgent>();
|
|
77
84
|
export const assetProviderFactory = new ProviderFactory<AssetProvider>();
|
|
78
85
|
export const chainHistoryProviderFactory = new ProviderFactory<ChainHistoryProvider>();
|
|
86
|
+
export const drepProviderFactory = new ProviderFactory<DRepProvider>();
|
|
79
87
|
export const networkInfoProviderFactory = new ProviderFactory<NetworkInfoProvider>();
|
|
80
88
|
export const rewardsProviderFactory = new ProviderFactory<RewardsProvider>();
|
|
81
89
|
export const txSubmitProviderFactory = new ProviderFactory<TxSubmitProvider>();
|
|
@@ -162,6 +170,33 @@ chainHistoryProviderFactory.register(
|
|
|
162
170
|
async (_params: any, logger: Logger) => (await getWsClient(logger)).chainHistoryProvider
|
|
163
171
|
);
|
|
164
172
|
|
|
173
|
+
chainHistoryProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger) => {
|
|
174
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostChainHistoryProvider.name}: ${MISSING_URL_PARAM}`);
|
|
175
|
+
|
|
176
|
+
return new Promise(async (resolve) => {
|
|
177
|
+
resolve(
|
|
178
|
+
new BlockfrostChainHistoryProvider(
|
|
179
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
180
|
+
await networkInfoProviderFactory.create('blockfrost', params, logger),
|
|
181
|
+
logger
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
drepProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger): Promise<DRepProvider> => {
|
|
188
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostDRepProvider.name}: ${MISSING_URL_PARAM}`);
|
|
189
|
+
|
|
190
|
+
return new Promise<DRepProvider>(async (resolve) => {
|
|
191
|
+
resolve(
|
|
192
|
+
new BlockfrostDRepProvider(
|
|
193
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
194
|
+
logger
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
165
200
|
networkInfoProviderFactory.register(
|
|
166
201
|
HTTP_PROVIDER,
|
|
167
202
|
async (params: any, logger: Logger): Promise<NetworkInfoProvider> => {
|
|
@@ -178,6 +213,19 @@ networkInfoProviderFactory.register(
|
|
|
178
213
|
async (_params: any, logger: Logger) => (await getWsClient(logger)).networkInfoProvider
|
|
179
214
|
);
|
|
180
215
|
|
|
216
|
+
networkInfoProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger) => {
|
|
217
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostNetworkInfoProvider.name}: ${MISSING_URL_PARAM}`);
|
|
218
|
+
|
|
219
|
+
return new Promise(async (resolve) => {
|
|
220
|
+
resolve(
|
|
221
|
+
new BlockfrostNetworkInfoProvider(
|
|
222
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
223
|
+
logger
|
|
224
|
+
)
|
|
225
|
+
);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
181
229
|
rewardsProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<RewardsProvider> => {
|
|
182
230
|
if (params.baseUrl === undefined) throw new Error(`${rewardsHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
183
231
|
|
|
@@ -186,6 +234,19 @@ rewardsProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logge
|
|
|
186
234
|
});
|
|
187
235
|
});
|
|
188
236
|
|
|
237
|
+
rewardsProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger) => {
|
|
238
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostRewardsProvider.name}: ${MISSING_URL_PARAM}`);
|
|
239
|
+
|
|
240
|
+
return new Promise(async (resolve) => {
|
|
241
|
+
resolve(
|
|
242
|
+
new BlockfrostRewardsProvider(
|
|
243
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
244
|
+
logger
|
|
245
|
+
)
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
189
250
|
txSubmitProviderFactory.register(OGMIOS_PROVIDER, async (params: any, logger: Logger): Promise<TxSubmitProvider> => {
|
|
190
251
|
if (params.baseUrl === undefined) throw new Error(`${NodeTxSubmitProvider.name}: ${MISSING_URL_PARAM}`);
|
|
191
252
|
|
|
@@ -220,6 +281,19 @@ txSubmitProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logg
|
|
|
220
281
|
});
|
|
221
282
|
});
|
|
222
283
|
|
|
284
|
+
txSubmitProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger) => {
|
|
285
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostTxSubmitProvider.name}: ${MISSING_URL_PARAM}`);
|
|
286
|
+
|
|
287
|
+
return new Promise(async (resolve) => {
|
|
288
|
+
resolve(
|
|
289
|
+
new BlockfrostTxSubmitProvider(
|
|
290
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
291
|
+
logger
|
|
292
|
+
)
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
|
|
223
297
|
utxoProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<UtxoProvider> => {
|
|
224
298
|
if (params.baseUrl === undefined) throw new Error(`${utxoHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
225
299
|
|
|
@@ -233,6 +307,19 @@ utxoProviderFactory.register(
|
|
|
233
307
|
async (_params: any, logger: Logger) => (await getWsClient(logger)).utxoProvider
|
|
234
308
|
);
|
|
235
309
|
|
|
310
|
+
utxoProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger) => {
|
|
311
|
+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostUtxoProvider.name}: ${MISSING_URL_PARAM}`);
|
|
312
|
+
|
|
313
|
+
return new Promise(async (resolve) => {
|
|
314
|
+
resolve(
|
|
315
|
+
new BlockfrostUtxoProvider(
|
|
316
|
+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
|
|
317
|
+
logger
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
236
323
|
handleProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<HandleProvider> => {
|
|
237
324
|
if (params.baseUrl === undefined) throw new Error(`${handleHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
238
325
|
|
|
@@ -412,6 +499,11 @@ export const getWallet = async (props: GetWalletProps) => {
|
|
|
412
499
|
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
413
500
|
logger
|
|
414
501
|
),
|
|
502
|
+
drepProvider: await drepProviderFactory.create(
|
|
503
|
+
env.TEST_CLIENT_DREP_PROVIDER,
|
|
504
|
+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
|
|
505
|
+
logger
|
|
506
|
+
),
|
|
415
507
|
handleProvider: await handleProviderFactory.create(
|
|
416
508
|
env.TEST_CLIENT_HANDLE_PROVIDER,
|
|
417
509
|
env.TEST_CLIENT_HANDLE_PROVIDER_PARAMS,
|
|
@@ -500,6 +592,11 @@ export const getSharedWallet = async (props: GetSharedWalletProps) => {
|
|
|
500
592
|
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
501
593
|
logger
|
|
502
594
|
),
|
|
595
|
+
drepProvider: await drepProviderFactory.create(
|
|
596
|
+
env.TEST_CLIENT_DREP_PROVIDER,
|
|
597
|
+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
|
|
598
|
+
logger
|
|
599
|
+
),
|
|
503
600
|
handleProvider: await handleProviderFactory.create(
|
|
504
601
|
env.TEST_CLIENT_HANDLE_PROVIDER,
|
|
505
602
|
env.TEST_CLIENT_HANDLE_PROVIDER_PARAMS,
|
|
@@ -40,6 +40,9 @@ TEST_CLIENT_ASSET_PROVIDER=http
|
|
|
40
40
|
TEST_CLIENT_ASSET_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
|
|
41
41
|
TEST_CLIENT_CHAIN_HISTORY_PROVIDER=ws
|
|
42
42
|
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
|
|
43
|
+
TEST_CLIENT_DREP_PROVIDER: 'blockfrost'
|
|
44
|
+
# TODO: use blockfrost URL
|
|
45
|
+
TEST_CLIENT_DREP_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
|
|
43
46
|
TEST_CLIENT_HANDLE_PROVIDER=http
|
|
44
47
|
TEST_CLIENT_HANDLE_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
|
|
45
48
|
TEST_CLIENT_NETWORK_INFO_PROVIDER=ws
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { BlockfrostChainHistoryProvider, BlockfrostNetworkInfoProvider
|
|
1
|
+
import { BlockfrostChainHistoryProvider, BlockfrostNetworkInfoProvider } from '@cardano-sdk/cardano-services-client';
|
|
2
2
|
import { Cardano, ChainHistoryProvider } from '@cardano-sdk/core';
|
|
3
3
|
import { logger } from '@cardano-sdk/util-dev';
|
|
4
|
+
import { util } from '@cardano-sdk/cardano-services';
|
|
4
5
|
|
|
5
6
|
describe.only('BlockfrostChainHistoryProvider', () => {
|
|
6
7
|
let chainHistoryProvider: ChainHistoryProvider;
|
|
7
|
-
let blockfrost;
|
|
8
8
|
beforeAll(async () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
chainHistoryProvider = new BlockfrostChainHistoryProvider({
|
|
12
|
-
blockfrost,
|
|
13
|
-
logger,
|
|
14
|
-
networkInfoProvider
|
|
15
|
-
});
|
|
9
|
+
const networkInfoProvider = new BlockfrostNetworkInfoProvider(util.getBlockfrostClient(), logger);
|
|
10
|
+
chainHistoryProvider = new BlockfrostChainHistoryProvider(util.getBlockfrostClient(), networkInfoProvider, logger);
|
|
16
11
|
});
|
|
17
12
|
|
|
18
13
|
describe('transactionsByHashes', () => {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
assetProviderFactory,
|
|
17
17
|
bip32Ed25519Factory,
|
|
18
18
|
chainHistoryProviderFactory,
|
|
19
|
+
drepProviderFactory,
|
|
19
20
|
getEnv,
|
|
20
21
|
getLoadTestScheduler,
|
|
21
22
|
keyManagementFactory,
|
|
@@ -55,6 +56,11 @@ const getProviders = async () => ({
|
|
|
55
56
|
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
56
57
|
logger
|
|
57
58
|
),
|
|
59
|
+
drepProvider: await drepProviderFactory.create(
|
|
60
|
+
env.TEST_CLIENT_DREP_PROVIDER,
|
|
61
|
+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
|
|
62
|
+
logger
|
|
63
|
+
),
|
|
58
64
|
networkInfoProvider: await networkInfoProviderFactory.create(
|
|
59
65
|
env.TEST_CLIENT_NETWORK_INFO_PROVIDER,
|
|
60
66
|
env.TEST_CLIENT_NETWORK_INFO_PROVIDER_PARAMS,
|
|
@@ -139,6 +139,7 @@ describe('PersonalWallet/multiAddress', () => {
|
|
|
139
139
|
expect(returnAdaTxFoundInHistory.id).toEqual(returnAdaSignedTx.id);
|
|
140
140
|
expect(normalizeTxBody(returnAdaTxFoundInHistory.body)).toEqual(normalizeTxBody(returnAdaSignedTx.body));
|
|
141
141
|
|
|
142
|
+
await walletReady(newWallet.wallet);
|
|
142
143
|
const endingBalance = await firstValueFromTimed(newWallet.wallet.balance.utxo.total$);
|
|
143
144
|
const expectedEndingBalance = 1_500_000n - returnAdaTxFoundInHistory.body.fee;
|
|
144
145
|
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/* eslint-disable unicorn/consistent-destructuring */
|
|
2
|
+
|
|
3
|
+
import * as Crypto from '@cardano-sdk/crypto';
|
|
4
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
5
|
+
import { Cardano, setInConwayEra } from '@cardano-sdk/core';
|
|
6
|
+
import { logger } from '@cardano-sdk/util-dev';
|
|
7
|
+
|
|
8
|
+
import { filter, firstValueFrom, map } from 'rxjs';
|
|
9
|
+
import {
|
|
10
|
+
firstValueFromTimed,
|
|
11
|
+
getEnv,
|
|
12
|
+
getWallet,
|
|
13
|
+
submitAndConfirm,
|
|
14
|
+
unDelegateWallet,
|
|
15
|
+
waitForWalletStateSettle,
|
|
16
|
+
walletReady,
|
|
17
|
+
walletVariables
|
|
18
|
+
} from '../../../src';
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
Test that rewardAccounts$ drepDelegatees are updated when dreps retire, provided one of the following conditions are met:
|
|
22
|
+
- a transaction build is attempted
|
|
23
|
+
- drepDelegatees change, new ones are added, old ones removed
|
|
24
|
+
Both of these actions trigger a refetch for all dreps found in drepDelegatees.
|
|
25
|
+
|
|
26
|
+
Setup:
|
|
27
|
+
- create three accounts (wallet, drepWallet, drepWallet2)
|
|
28
|
+
- drep* wallets register as dreps
|
|
29
|
+
- wallet delegates to 2 stake pools, resulting in 2 registered stake keys
|
|
30
|
+
- wallet delegates voting power: stakeKey1 & stakeKey2 to drepWallet & drepWallet2 respectively
|
|
31
|
+
- Expect to see DRep1 & DRep2 in drepDelegatees
|
|
32
|
+
- DRep1 retires - no change in drepDelegatees because a refresh was not triggered
|
|
33
|
+
- Build a transaction with wallet, but do not submit
|
|
34
|
+
- Expect to see DRep1 removed from drepDelegatees
|
|
35
|
+
- DRep2 retires - no change in drepDelegatees because a refresh was not triggered
|
|
36
|
+
- Using another instance of the wallet, delegate stakeKey1 to AlwaysAbstain
|
|
37
|
+
- Original wallet detects the change of delegatees according to tx history, which triggers a refetch for all dreps
|
|
38
|
+
- Expect DRep2 to be removed from drepDelegatees
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
const { CertificateType, CredentialType, RewardAccount, StakePoolStatus } = Cardano;
|
|
42
|
+
|
|
43
|
+
const env = getEnv(walletVariables);
|
|
44
|
+
|
|
45
|
+
const anchor = {
|
|
46
|
+
dataHash: '3e33018e8293d319ef5b3ac72366dd28006bd315b715f7e7cfcbd3004129b80d' as Crypto.Hash32ByteBase16,
|
|
47
|
+
url: 'https://testing.this'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const getTestWallet = async (idx: number, name: string, minCoinBalance?: bigint) => {
|
|
51
|
+
const { wallet } = await getWallet({ env, idx, logger, name, polling: { interval: 50 } });
|
|
52
|
+
|
|
53
|
+
await walletReady(wallet, minCoinBalance);
|
|
54
|
+
|
|
55
|
+
return wallet;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
describe('PersonalWallet/drepRetirement', () => {
|
|
59
|
+
let dRepWallet1: BaseWallet;
|
|
60
|
+
let dRepWallet2: BaseWallet;
|
|
61
|
+
let delegatingWallet: BaseWallet;
|
|
62
|
+
|
|
63
|
+
let dRepCredential1: Cardano.Credential & { type: Cardano.CredentialType.KeyHash };
|
|
64
|
+
let drepId1: Cardano.DRepID;
|
|
65
|
+
let dRepCredential2: Cardano.Credential & { type: Cardano.CredentialType.KeyHash };
|
|
66
|
+
let drepId2: Cardano.DRepID;
|
|
67
|
+
let poolId1: Cardano.PoolId;
|
|
68
|
+
let poolId2: Cardano.PoolId;
|
|
69
|
+
let stakeCredential1: Cardano.Credential;
|
|
70
|
+
let stakeCredential2: Cardano.Credential;
|
|
71
|
+
|
|
72
|
+
let dRepDeposit: bigint;
|
|
73
|
+
|
|
74
|
+
const getDRepCredential = async (wallet: BaseWallet) => {
|
|
75
|
+
const drepPubKey = await wallet.governance.getPubDRepKey();
|
|
76
|
+
const dRepKeyHash = Crypto.Hash28ByteBase16.fromEd25519KeyHashHex(
|
|
77
|
+
(await Crypto.Ed25519PublicKey.fromHex(drepPubKey!).hash()).hex()
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return { hash: dRepKeyHash, type: CredentialType.KeyHash } as typeof dRepCredential1;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const getDeposits = async () => {
|
|
84
|
+
const protocolParameters = await delegatingWallet.networkInfoProvider.protocolParameters();
|
|
85
|
+
|
|
86
|
+
return [
|
|
87
|
+
BigInt(protocolParameters.dRepDeposit!),
|
|
88
|
+
BigInt(protocolParameters.governanceActionDeposit!),
|
|
89
|
+
BigInt(protocolParameters.stakeKeyDeposit)
|
|
90
|
+
];
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const getPoolIds = async () => {
|
|
94
|
+
const activePools = await delegatingWallet.stakePoolProvider.queryStakePools({
|
|
95
|
+
filters: { status: [StakePoolStatus.Active] },
|
|
96
|
+
pagination: { limit: 2, startAt: 0 }
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return activePools.pageResults.map(({ id }) => id);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const getStakeCredential = async () => {
|
|
103
|
+
const rewardAccounts = await firstValueFrom(
|
|
104
|
+
delegatingWallet.addresses$.pipe(map((addresses) => addresses.map(({ rewardAccount }) => rewardAccount)))
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return rewardAccounts.map((rewardAccount) => ({
|
|
108
|
+
hash: Crypto.Hash28ByteBase16.fromEd25519KeyHashHex(RewardAccount.toHash(rewardAccount)),
|
|
109
|
+
type: CredentialType.KeyHash
|
|
110
|
+
}));
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const feedDRepWallet = async (dRepWallet: BaseWallet, amount: bigint) => {
|
|
114
|
+
const balance = await firstValueFrom(dRepWallet.balance.utxo.total$);
|
|
115
|
+
|
|
116
|
+
if (balance.coins > amount) return;
|
|
117
|
+
|
|
118
|
+
const address = await firstValueFrom(dRepWallet.addresses$.pipe(map((addresses) => addresses[0].address)));
|
|
119
|
+
|
|
120
|
+
const signedTx = await delegatingWallet
|
|
121
|
+
.createTxBuilder()
|
|
122
|
+
.addOutput({ address, value: { coins: amount } })
|
|
123
|
+
.build()
|
|
124
|
+
.sign();
|
|
125
|
+
|
|
126
|
+
await submitAndConfirm(delegatingWallet, signedTx.tx, 1);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const sendDRepRegCert = async (dRepWallet: BaseWallet, register: boolean) => {
|
|
130
|
+
const dRepCredential = await getDRepCredential(dRepWallet);
|
|
131
|
+
const common = { dRepCredential, deposit: dRepDeposit };
|
|
132
|
+
const dRepUnRegCert: Cardano.UnRegisterDelegateRepresentativeCertificate = {
|
|
133
|
+
__typename: CertificateType.UnregisterDelegateRepresentative,
|
|
134
|
+
...common
|
|
135
|
+
};
|
|
136
|
+
const dRepRegCert: Cardano.RegisterDelegateRepresentativeCertificate = {
|
|
137
|
+
__typename: CertificateType.RegisterDelegateRepresentative,
|
|
138
|
+
anchor,
|
|
139
|
+
...common
|
|
140
|
+
};
|
|
141
|
+
const certificate = register ? dRepRegCert : dRepUnRegCert;
|
|
142
|
+
const signedTx = await dRepWallet
|
|
143
|
+
.createTxBuilder()
|
|
144
|
+
.customize(({ txBody }) => ({ ...txBody, certificates: [certificate] }))
|
|
145
|
+
.build()
|
|
146
|
+
.sign();
|
|
147
|
+
await submitAndConfirm(dRepWallet, signedTx.tx, 1);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const isRegisteredDRep = async (wallet: BaseWallet) => {
|
|
151
|
+
await waitForWalletStateSettle(wallet);
|
|
152
|
+
return await firstValueFrom(wallet.governance.isRegisteredAsDRep$);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
beforeAll(async () => {
|
|
156
|
+
// TODO: remove once mainnet hardforks to conway-era, and this becomes "the norm"
|
|
157
|
+
setInConwayEra(true);
|
|
158
|
+
|
|
159
|
+
[delegatingWallet, dRepWallet1, dRepWallet2] = await Promise.all([
|
|
160
|
+
getTestWallet(0, 'wallet-delegating', 100_000_000n),
|
|
161
|
+
getTestWallet(1, 'wallet-DRep1', 0n),
|
|
162
|
+
getTestWallet(2, 'wallet-DRep2', 0n)
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
[dRepCredential1, dRepCredential2, [dRepDeposit], [poolId1, poolId2]] = await Promise.all([
|
|
166
|
+
getDRepCredential(dRepWallet1),
|
|
167
|
+
getDRepCredential(dRepWallet2),
|
|
168
|
+
getDeposits(),
|
|
169
|
+
getPoolIds()
|
|
170
|
+
]);
|
|
171
|
+
|
|
172
|
+
drepId1 = Cardano.DRepID.cip129FromCredential(dRepCredential1);
|
|
173
|
+
drepId2 = Cardano.DRepID.cip129FromCredential(dRepCredential2);
|
|
174
|
+
|
|
175
|
+
await feedDRepWallet(dRepWallet1, dRepDeposit * 2n);
|
|
176
|
+
await feedDRepWallet(dRepWallet2, dRepDeposit * 2n);
|
|
177
|
+
|
|
178
|
+
if (!(await isRegisteredDRep(dRepWallet1))) await sendDRepRegCert(dRepWallet1, true);
|
|
179
|
+
if (!(await isRegisteredDRep(dRepWallet2))) await sendDRepRegCert(dRepWallet2, true);
|
|
180
|
+
|
|
181
|
+
const txBuilder = delegatingWallet.createTxBuilder().delegatePortfolio({
|
|
182
|
+
name: 'Test Portfolio',
|
|
183
|
+
pools: [
|
|
184
|
+
{ id: Cardano.PoolIdHex(Cardano.PoolId.toKeyHash(poolId1)), weight: 1 },
|
|
185
|
+
{ id: Cardano.PoolIdHex(Cardano.PoolId.toKeyHash(poolId2)), weight: 1 }
|
|
186
|
+
]
|
|
187
|
+
});
|
|
188
|
+
const poolDelegationTx = await txBuilder.build().sign();
|
|
189
|
+
await submitAndConfirm(delegatingWallet, poolDelegationTx.tx, 1);
|
|
190
|
+
|
|
191
|
+
[stakeCredential1, stakeCredential2] = await getStakeCredential();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
afterAll(async () => {
|
|
195
|
+
if (await isRegisteredDRep(dRepWallet1)) await sendDRepRegCert(dRepWallet1, false);
|
|
196
|
+
if (await isRegisteredDRep(dRepWallet2)) await sendDRepRegCert(dRepWallet2, false);
|
|
197
|
+
await unDelegateWallet(delegatingWallet);
|
|
198
|
+
|
|
199
|
+
delegatingWallet.shutdown();
|
|
200
|
+
dRepWallet1.shutdown();
|
|
201
|
+
dRepWallet2.shutdown();
|
|
202
|
+
|
|
203
|
+
// TODO: remove once mainnet hardforks to conway-era, and this becomes "the norm"
|
|
204
|
+
setInConwayEra(false);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('emits drepDelegatees after delegating voting power', async () => {
|
|
208
|
+
const voteDelegCert1: Cardano.VoteDelegationCertificate = {
|
|
209
|
+
__typename: CertificateType.VoteDelegation,
|
|
210
|
+
dRep: dRepCredential1,
|
|
211
|
+
stakeCredential: stakeCredential1
|
|
212
|
+
};
|
|
213
|
+
const voteDelegCert2: Cardano.VoteDelegationCertificate = {
|
|
214
|
+
__typename: CertificateType.VoteDelegation,
|
|
215
|
+
dRep: dRepCredential2,
|
|
216
|
+
stakeCredential: stakeCredential2
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const signedTx = await delegatingWallet
|
|
220
|
+
.createTxBuilder()
|
|
221
|
+
.customize(({ txBody }) => ({ ...txBody, certificates: [voteDelegCert1, voteDelegCert2] }))
|
|
222
|
+
.build()
|
|
223
|
+
.sign();
|
|
224
|
+
await submitAndConfirm(delegatingWallet, signedTx.tx, 1);
|
|
225
|
+
|
|
226
|
+
const drepDelegatees = await firstValueFrom(
|
|
227
|
+
delegatingWallet.delegation.rewardAccounts$.pipe(
|
|
228
|
+
map((accounts) => accounts.map(({ dRepDelegatee }) => dRepDelegatee))
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
expect(drepDelegatees).toEqual([
|
|
233
|
+
{ delegateRepresentative: expect.objectContaining({ active: true, id: drepId1 }) },
|
|
234
|
+
{ delegateRepresentative: expect.objectContaining({ active: true, id: drepId2 }) }
|
|
235
|
+
]);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('transaction build triggers detection of retired DRep', async () => {
|
|
239
|
+
// Retire DRep1
|
|
240
|
+
await sendDRepRegCert(dRepWallet1, false);
|
|
241
|
+
|
|
242
|
+
// Only build and inspect to trigger the refetch of drep infos
|
|
243
|
+
await delegatingWallet.createTxBuilder().delegatePortfolio(null).build().inspect();
|
|
244
|
+
|
|
245
|
+
const drepDelegatees = await firstValueFrom(
|
|
246
|
+
delegatingWallet.delegation.rewardAccounts$.pipe(
|
|
247
|
+
map((accounts) => accounts.map(({ dRepDelegatee }) => dRepDelegatee))
|
|
248
|
+
)
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
expect(drepDelegatees).toEqual([
|
|
252
|
+
{ delegateRepresentative: expect.objectContaining({ active: false, id: drepId1 }) },
|
|
253
|
+
{ delegateRepresentative: expect.objectContaining({ active: true, amount: 0n, hasScript: false, id: drepId2 }) }
|
|
254
|
+
]);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('tx history vote delegation change triggers refresh of all delegations', async () => {
|
|
258
|
+
// Retire DRep2
|
|
259
|
+
await sendDRepRegCert(dRepWallet2, false);
|
|
260
|
+
|
|
261
|
+
// Create a clone of the delegatingWallet and change drep delegation.
|
|
262
|
+
// The delegatingWallet tx history will update, which will trigger a refetch of all dreps, including DRep2 which was retired.
|
|
263
|
+
const delegatingWalletClone = await getTestWallet(0, 'wallet-delegating-clone', 0n);
|
|
264
|
+
const signedTx = await delegatingWalletClone
|
|
265
|
+
.createTxBuilder()
|
|
266
|
+
.customize(({ txBody }) => ({
|
|
267
|
+
...txBody,
|
|
268
|
+
certificates: [
|
|
269
|
+
{
|
|
270
|
+
__typename: CertificateType.VoteDelegation,
|
|
271
|
+
dRep: { __typename: 'AlwaysAbstain' },
|
|
272
|
+
stakeCredential: stakeCredential1
|
|
273
|
+
} as Cardano.VoteDelegationCertificate
|
|
274
|
+
]
|
|
275
|
+
}))
|
|
276
|
+
.build()
|
|
277
|
+
.sign();
|
|
278
|
+
await submitAndConfirm(delegatingWalletClone, signedTx.tx, 1);
|
|
279
|
+
|
|
280
|
+
const drepDelegatees = await firstValueFromTimed(
|
|
281
|
+
delegatingWallet.delegation.rewardAccounts$.pipe(
|
|
282
|
+
map((accounts) => accounts.map(({ dRepDelegatee }) => dRepDelegatee)),
|
|
283
|
+
filter(
|
|
284
|
+
([firstDelegatee]) =>
|
|
285
|
+
!!firstDelegatee?.delegateRepresentative &&
|
|
286
|
+
Cardano.isDRepAlwaysAbstain(firstDelegatee.delegateRepresentative)
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
expect(drepDelegatees).toEqual([
|
|
292
|
+
{ delegateRepresentative: { __typename: 'AlwaysAbstain' } },
|
|
293
|
+
{ delegateRepresentative: expect.objectContaining({ active: false, amount: 0n, hasScript: false, id: drepId2 }) }
|
|
294
|
+
]);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// cSpell:ignore cardano utxos
|
|
2
|
-
|
|
3
|
-
import { NetworkInfoProvider } from '@cardano-sdk/core';
|
|
4
|
-
import { logger } from '@cardano-sdk/util-dev';
|
|
5
|
-
import { networkInfoHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
6
|
-
import { toSerializableObject } from '@cardano-sdk/util';
|
|
7
|
-
|
|
8
|
-
// LW-11858 to enable this
|
|
9
|
-
describe.skip('Web Socket', () => {
|
|
10
|
-
const legacyProvider = networkInfoHttpProvider({ baseUrl: 'http://localhost:4000/', logger });
|
|
11
|
-
const provider = networkInfoHttpProvider({ baseUrl: 'http://localhost:4001/', logger });
|
|
12
|
-
|
|
13
|
-
const methods: (keyof NetworkInfoProvider)[] = [
|
|
14
|
-
'eraSummaries',
|
|
15
|
-
'genesisParameters',
|
|
16
|
-
'lovelaceSupply',
|
|
17
|
-
'protocolParameters',
|
|
18
|
-
'stake'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
test.each(methods)('compare %s', async (method) => {
|
|
22
|
-
const [legacyResponse, response] = await Promise.all([legacyProvider[method](), provider[method]()]);
|
|
23
|
-
|
|
24
|
-
expect(toSerializableObject(response)).toEqual(toSerializableObject(legacyResponse));
|
|
25
|
-
});
|
|
26
|
-
});
|