@cardano-sdk/e2e 0.14.2 → 0.15.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/CHANGELOG.md +15 -0
- package/dist/cjs/factories.d.ts.map +1 -1
- package/dist/cjs/factories.js +12 -7
- package/dist/cjs/factories.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/factories.d.ts.map +1 -1
- package/dist/esm/factories.js +13 -8
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -16
- package/src/factories.ts +16 -8
- package/test/artillery/StakePoolSearch.ts +2 -2
- package/test/blockfrost/StakePoolCompare.test.ts +2 -2
- package/test/load-test-custom/stake-pool-search/stake-pool-search.test.ts +2 -2
- package/test/long-running/delegation-rewards.test.ts +7 -1
- package/test/providers/StakePoolProvider.test.ts +2 -2
- package/test/wallet/PersonalWallet/delegation.test.ts +2 -2
- package/test/wallet/PersonalWallet/delegationDistribution.test.ts +42 -78
- package/test/wallet/PersonalWallet/handle.test.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardano-sdk/e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "End to end tests for the cardano-js-sdk packages.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=16.0"
|
|
@@ -81,18 +81,18 @@
|
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@cardano-foundation/ledgerjs-hw-app-cardano": "^6.0.0",
|
|
83
83
|
"@cardano-ogmios/client": "5.6.0",
|
|
84
|
-
"@cardano-sdk/cardano-services": "~0.13.
|
|
85
|
-
"@cardano-sdk/cardano-services-client": "~0.9.
|
|
86
|
-
"@cardano-sdk/core": "~0.
|
|
84
|
+
"@cardano-sdk/cardano-services": "~0.13.3",
|
|
85
|
+
"@cardano-sdk/cardano-services-client": "~0.9.9",
|
|
86
|
+
"@cardano-sdk/core": "~0.15.0",
|
|
87
87
|
"@cardano-sdk/crypto": "~0.1.6",
|
|
88
|
-
"@cardano-sdk/hardware-ledger": "~0.2.
|
|
89
|
-
"@cardano-sdk/key-management": "~0.7.
|
|
90
|
-
"@cardano-sdk/ogmios": "~0.12.
|
|
91
|
-
"@cardano-sdk/tx-construction": "~0.
|
|
88
|
+
"@cardano-sdk/hardware-ledger": "~0.2.8",
|
|
89
|
+
"@cardano-sdk/key-management": "~0.7.7",
|
|
90
|
+
"@cardano-sdk/ogmios": "~0.12.5",
|
|
91
|
+
"@cardano-sdk/tx-construction": "~0.8.0",
|
|
92
92
|
"@cardano-sdk/util": "~0.11.0",
|
|
93
|
-
"@cardano-sdk/util-dev": "~0.13.
|
|
94
|
-
"@cardano-sdk/util-rxjs": "~0.4.
|
|
95
|
-
"@cardano-sdk/wallet": "~0.16.
|
|
93
|
+
"@cardano-sdk/util-dev": "~0.13.3",
|
|
94
|
+
"@cardano-sdk/util-rxjs": "~0.4.16",
|
|
95
|
+
"@cardano-sdk/wallet": "~0.16.3",
|
|
96
96
|
"@vespaiach/axios-fetch-adapter": "^0.3.0",
|
|
97
97
|
"axios": "^0.27.2",
|
|
98
98
|
"bunyan": "^1.8.15",
|
|
@@ -122,10 +122,10 @@
|
|
|
122
122
|
"@babel/core": "^7.18.2",
|
|
123
123
|
"@babel/preset-env": "^7.18.2",
|
|
124
124
|
"@babel/preset-typescript": "^7.17.12",
|
|
125
|
-
"@cardano-sdk/dapp-connector": "~0.9.
|
|
126
|
-
"@cardano-sdk/projection": "~0.6.
|
|
127
|
-
"@cardano-sdk/projection-typeorm": "~0.3.
|
|
128
|
-
"@cardano-sdk/web-extension": "~0.
|
|
125
|
+
"@cardano-sdk/dapp-connector": "~0.9.7",
|
|
126
|
+
"@cardano-sdk/projection": "~0.6.9",
|
|
127
|
+
"@cardano-sdk/projection-typeorm": "~0.3.5",
|
|
128
|
+
"@cardano-sdk/web-extension": "~0.13.0",
|
|
129
129
|
"@dcspark/cardano-multiplatform-lib-browser": "^3.1.1",
|
|
130
130
|
"@emurgo/cardano-message-signing-asmjs": "^1.0.1",
|
|
131
131
|
"@types/bunyan": "^1.8.8",
|
|
@@ -173,5 +173,5 @@
|
|
|
173
173
|
"webpack-cli": "^4.9.2",
|
|
174
174
|
"webpack-merge": "^5.8.0"
|
|
175
175
|
},
|
|
176
|
-
"gitHead": "
|
|
176
|
+
"gitHead": "7368568d3dd7844bb48513c92f3a7f26773bf2c7"
|
|
177
177
|
}
|
package/src/factories.ts
CHANGED
|
@@ -42,7 +42,8 @@ import {
|
|
|
42
42
|
rewardsHttpProvider,
|
|
43
43
|
stakePoolHttpProvider,
|
|
44
44
|
txSubmitHttpProvider,
|
|
45
|
-
utxoHttpProvider
|
|
45
|
+
utxoHttpProvider,
|
|
46
|
+
version
|
|
46
47
|
} from '@cardano-sdk/cardano-services-client';
|
|
47
48
|
import { LedgerKeyAgent } from '@cardano-sdk/hardware-ledger';
|
|
48
49
|
import { Logger } from 'ts-log';
|
|
@@ -100,7 +101,14 @@ assetProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger)
|
|
|
100
101
|
if (params.baseUrl === undefined) throw new Error(`${assetInfoHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
101
102
|
|
|
102
103
|
return new Promise<AssetProvider>(async (resolve) => {
|
|
103
|
-
resolve(
|
|
104
|
+
resolve(
|
|
105
|
+
assetInfoHttpProvider({
|
|
106
|
+
adapter: customHttpFetchAdapter,
|
|
107
|
+
baseUrl: params.baseUrl,
|
|
108
|
+
logger,
|
|
109
|
+
version
|
|
110
|
+
})
|
|
111
|
+
);
|
|
104
112
|
});
|
|
105
113
|
});
|
|
106
114
|
|
|
@@ -110,7 +118,7 @@ chainHistoryProviderFactory.register(
|
|
|
110
118
|
if (params.baseUrl === undefined) throw new Error(`${chainHistoryHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
111
119
|
|
|
112
120
|
return new Promise<ChainHistoryProvider>(async (resolve) => {
|
|
113
|
-
resolve(chainHistoryHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
121
|
+
resolve(chainHistoryHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
114
122
|
});
|
|
115
123
|
}
|
|
116
124
|
);
|
|
@@ -121,7 +129,7 @@ networkInfoProviderFactory.register(
|
|
|
121
129
|
if (params.baseUrl === undefined) throw new Error(`${networkInfoHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
122
130
|
|
|
123
131
|
return new Promise<NetworkInfoProvider>(async (resolve) => {
|
|
124
|
-
resolve(networkInfoHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
132
|
+
resolve(networkInfoHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
125
133
|
});
|
|
126
134
|
}
|
|
127
135
|
);
|
|
@@ -130,7 +138,7 @@ rewardsProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logge
|
|
|
130
138
|
if (params.baseUrl === undefined) throw new Error(`${rewardsHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
131
139
|
|
|
132
140
|
return new Promise<RewardsProvider>(async (resolve) => {
|
|
133
|
-
resolve(rewardsHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
141
|
+
resolve(rewardsHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
134
142
|
});
|
|
135
143
|
});
|
|
136
144
|
|
|
@@ -152,7 +160,7 @@ txSubmitProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logg
|
|
|
152
160
|
if (params.baseUrl === undefined) throw new Error(`${txSubmitHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
153
161
|
|
|
154
162
|
return new Promise<TxSubmitProvider>(async (resolve) => {
|
|
155
|
-
resolve(txSubmitHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
163
|
+
resolve(txSubmitHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
156
164
|
});
|
|
157
165
|
});
|
|
158
166
|
|
|
@@ -160,7 +168,7 @@ utxoProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger):
|
|
|
160
168
|
if (params.baseUrl === undefined) throw new Error(`${utxoHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
161
169
|
|
|
162
170
|
return new Promise<UtxoProvider>(async (resolve) => {
|
|
163
|
-
resolve(utxoHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
171
|
+
resolve(utxoHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
164
172
|
});
|
|
165
173
|
});
|
|
166
174
|
|
|
@@ -187,7 +195,7 @@ stakePoolProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Log
|
|
|
187
195
|
if (params.baseUrl === undefined) throw new Error(`${stakePoolHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
188
196
|
|
|
189
197
|
return new Promise<StakePoolProvider>(async (resolve) => {
|
|
190
|
-
resolve(stakePoolHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger }));
|
|
198
|
+
resolve(stakePoolHttpProvider({ adapter: customHttpFetchAdapter, baseUrl: params.baseUrl, logger, version }));
|
|
191
199
|
});
|
|
192
200
|
});
|
|
193
201
|
|
|
@@ -2,7 +2,7 @@ import * as envalid from 'envalid';
|
|
|
2
2
|
import { ArtilleryContext, FunctionHook, WhileTrueHook } from './artillery';
|
|
3
3
|
import { Cardano, Paginated, QueryStakePoolsArgs } from '@cardano-sdk/core';
|
|
4
4
|
import { logger } from '@cardano-sdk/util-dev';
|
|
5
|
-
import { stakePoolHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
5
|
+
import { stakePoolHttpProvider, version } from '@cardano-sdk/cardano-services-client';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* The context variables shared between all the hooks.
|
|
@@ -26,7 +26,7 @@ interface StakePoolSearchVars extends Paginated<Cardano.StakePool> {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const env = envalid.cleanEnv(process.env, { STAKE_POOL_PROVIDER_URL: envalid.str() });
|
|
29
|
-
const provider = stakePoolHttpProvider({ baseUrl: env.STAKE_POOL_PROVIDER_URL, logger });
|
|
29
|
+
const provider = stakePoolHttpProvider({ baseUrl: env.STAKE_POOL_PROVIDER_URL, logger, version });
|
|
30
30
|
|
|
31
31
|
const PAGE_SIZE = 20;
|
|
32
32
|
|
|
@@ -4,7 +4,7 @@ import { ChildProcess, fork } from 'child_process';
|
|
|
4
4
|
import { WriteStream, createWriteStream } from 'fs';
|
|
5
5
|
import { getRandomPort } from 'get-port-please';
|
|
6
6
|
import { logger } from '@cardano-sdk/util-dev';
|
|
7
|
-
import { stakePoolHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
7
|
+
import { stakePoolHttpProvider, version } from '@cardano-sdk/cardano-services-client';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
|
|
10
10
|
type StakePoolRecord = Record<string, Cardano.StakePool>;
|
|
@@ -127,7 +127,7 @@ describe('StakePoolCompare', () => {
|
|
|
127
127
|
};
|
|
128
128
|
|
|
129
129
|
const setupProvider = async (args: string[] = []) => {
|
|
130
|
-
const provider = stakePoolHttpProvider({ baseUrl: await startServer(args), logger });
|
|
130
|
+
const provider = stakePoolHttpProvider({ baseUrl: await startServer(args), logger, version });
|
|
131
131
|
|
|
132
132
|
// eslint-disable-next-line no-constant-condition
|
|
133
133
|
while (true) {
|
|
@@ -4,7 +4,7 @@ import { Logger } from 'ts-log';
|
|
|
4
4
|
import { MeasurementUtil, getEnv, getLoadTestScheduler } from '../../../src';
|
|
5
5
|
import { bufferTime, from, tap } from 'rxjs';
|
|
6
6
|
import { logger } from '@cardano-sdk/util-dev';
|
|
7
|
-
import { stakePoolHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
7
|
+
import { stakePoolHttpProvider, version } from '@cardano-sdk/cardano-services-client';
|
|
8
8
|
|
|
9
9
|
// Example call:
|
|
10
10
|
/* STAKE_POOL_PROVIDER_URL="http://mhvm:4000/stake-pool" \
|
|
@@ -14,7 +14,7 @@ import { stakePoolHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const { STAKE_POOL_PROVIDER_URL } = envalid.cleanEnv(process.env, { STAKE_POOL_PROVIDER_URL: envalid.str() });
|
|
17
|
-
const provider = stakePoolHttpProvider({ baseUrl: STAKE_POOL_PROVIDER_URL, logger });
|
|
17
|
+
const provider = stakePoolHttpProvider({ baseUrl: STAKE_POOL_PROVIDER_URL, logger, version });
|
|
18
18
|
const testLogger: Logger = console;
|
|
19
19
|
const intermediateResultsInterval = 10_000;
|
|
20
20
|
|
|
@@ -70,7 +70,13 @@ describe('delegation rewards', () => {
|
|
|
70
70
|
|
|
71
71
|
const submitDelegationTx = async () => {
|
|
72
72
|
logger.info(`Creating delegation tx at epoch #${(await firstValueFrom(wallet1.currentEpoch$)).epochNo}`);
|
|
73
|
-
const { tx: signedTx } = await wallet1
|
|
73
|
+
const { tx: signedTx } = await wallet1
|
|
74
|
+
.createTxBuilder()
|
|
75
|
+
.delegatePortfolio({
|
|
76
|
+
pools: [{ id: Cardano.PoolIdHex(Cardano.PoolId.toKeyHash(poolId)), weight: 1 }]
|
|
77
|
+
})
|
|
78
|
+
.build()
|
|
79
|
+
.sign();
|
|
74
80
|
await wallet1.submitTx(signedTx);
|
|
75
81
|
const { epochNo } = await firstValueFrom(wallet1.currentEpoch$);
|
|
76
82
|
logger.info(`Delegation tx ${signedTx.id} submitted at epoch #${epochNo}`);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as envalid from 'envalid';
|
|
4
4
|
import { Cardano, QueryStakePoolsArgs, StakePoolProvider } from '@cardano-sdk/core';
|
|
5
5
|
import { logger } from '@cardano-sdk/util-dev';
|
|
6
|
-
import { stakePoolHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
6
|
+
import { stakePoolHttpProvider, version } from '@cardano-sdk/cardano-services-client';
|
|
7
7
|
|
|
8
8
|
const stringToRegExEqualsTo = (str: string) => `^${str.replace(/[$()*+.?[\\\]^{|}-]/g, '\\$&')}$`;
|
|
9
9
|
|
|
@@ -140,7 +140,7 @@ describe('StakePoolProvider', () => {
|
|
|
140
140
|
|
|
141
141
|
beforeAll(async () => {
|
|
142
142
|
const env = envalid.cleanEnv(process.env, { STAKE_POOL_PROVIDER_URL: envalid.url() });
|
|
143
|
-
const config = { baseUrl: env.STAKE_POOL_PROVIDER_URL, logger };
|
|
143
|
+
const config = { baseUrl: env.STAKE_POOL_PROVIDER_URL, logger, version };
|
|
144
144
|
|
|
145
145
|
provider = stakePoolHttpProvider(config);
|
|
146
146
|
pools = await fetchAllPools();
|
|
@@ -113,7 +113,7 @@ describe('PersonalWallet/delegation', () => {
|
|
|
113
113
|
|
|
114
114
|
const { tx } = await txBuilder
|
|
115
115
|
.addOutput(await txBuilder.buildOutput().address(destAddresses).coin(tx1OutputCoins).build())
|
|
116
|
-
.
|
|
116
|
+
.delegatePortfolio({ pools: [{ id: Cardano.PoolIdHex(Cardano.PoolId.toKeyHash(poolId)), weight: 1 }] })
|
|
117
117
|
.build()
|
|
118
118
|
.sign();
|
|
119
119
|
await sourceWallet.submitTx(tx);
|
|
@@ -163,7 +163,7 @@ describe('PersonalWallet/delegation', () => {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// Make a 2nd tx with key de-registration
|
|
166
|
-
const { tx: txDeregisterSigned } = await sourceWallet.createTxBuilder().
|
|
166
|
+
const { tx: txDeregisterSigned } = await sourceWallet.createTxBuilder().delegatePortfolio(null).build().sign();
|
|
167
167
|
await sourceWallet.submitTx(txDeregisterSigned);
|
|
168
168
|
await waitForTx(sourceWallet, txDeregisterSigned.id);
|
|
169
169
|
const tx2ConfirmedState = await getWalletStateSnapshot(sourceWallet);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AddressType } from '@cardano-sdk/key-management';
|
|
2
1
|
import { Cardano } from '@cardano-sdk/core';
|
|
3
2
|
import { DelegatedStake, PersonalWallet, createUtxoBalanceByAddressTracker } from '@cardano-sdk/wallet';
|
|
4
3
|
import { MINUTE, firstValueFromTimed, getWallet, submitAndConfirm, walletReady } from '../../../src';
|
|
@@ -6,29 +5,17 @@ import { Observable, filter, firstValueFrom, map, tap } from 'rxjs';
|
|
|
6
5
|
import { Percent } from '@cardano-sdk/util';
|
|
7
6
|
import { createLogger } from '@cardano-sdk/util-dev';
|
|
8
7
|
import { getEnv, walletVariables } from '../../../src/environment';
|
|
9
|
-
import delay from 'delay';
|
|
10
8
|
|
|
11
9
|
const env = getEnv(walletVariables);
|
|
12
10
|
const logger = createLogger();
|
|
13
11
|
const TEST_FUNDS = 1_000_000_000n;
|
|
12
|
+
const POOLS_COUNT = 5;
|
|
14
13
|
const distributionMessage = 'ObservableWallet.delegation.distribution$:';
|
|
15
14
|
|
|
16
|
-
const deriveStakeKeys = async (wallet: PersonalWallet) => {
|
|
17
|
-
await walletReady(wallet, 0n);
|
|
18
|
-
// Add 4 new addresses with different stake keys.
|
|
19
|
-
for (let i = 1; i < 5; ++i) {
|
|
20
|
-
await wallet.keyAgent.deriveAddress({ index: 0, type: AddressType.External }, i);
|
|
21
|
-
}
|
|
22
|
-
// Allow status tracker to change status with debounce.
|
|
23
|
-
// Otherwise the updates are be debounced and next calls find the wallet ready before it had a chance to update the status.
|
|
24
|
-
await delay(2);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
15
|
/** Distribute the wallet funds evenly across all its addresses */
|
|
28
|
-
const
|
|
16
|
+
const fundWallet = async (wallet: PersonalWallet) => {
|
|
29
17
|
await walletReady(wallet, 0n);
|
|
30
18
|
const addresses = await firstValueFrom(wallet.addresses$);
|
|
31
|
-
expect(addresses.length).toBeGreaterThan(1);
|
|
32
19
|
|
|
33
20
|
// Check that we have enough funds. Otherwise, fund it from wallet account at index 0
|
|
34
21
|
let { coins: totalCoins } = await firstValueFrom(wallet.balance.utxo.available$);
|
|
@@ -50,22 +37,6 @@ const distributeFunds = async (wallet: PersonalWallet) => {
|
|
|
50
37
|
await walletReady(wallet);
|
|
51
38
|
totalCoins = (await firstValueFrom(wallet.balance.utxo.available$)).coins;
|
|
52
39
|
}
|
|
53
|
-
|
|
54
|
-
const coinsPerAddress = totalCoins / BigInt(addresses.length);
|
|
55
|
-
|
|
56
|
-
const txBuilder = wallet.createTxBuilder();
|
|
57
|
-
|
|
58
|
-
logger.info(`Sending ${coinsPerAddress} to the ${addresses.length - 1} derived addresses`);
|
|
59
|
-
// The first one was generated when the wallet was created.
|
|
60
|
-
for (let i = 1; i < addresses.length; ++i) {
|
|
61
|
-
const derivedAddress = addresses[i];
|
|
62
|
-
logger.info('Funding', derivedAddress.address, coinsPerAddress);
|
|
63
|
-
logger.info(derivedAddress.rewardAccount);
|
|
64
|
-
txBuilder.addOutput(txBuilder.buildOutput().address(derivedAddress.address).coin(coinsPerAddress).toTxOut());
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const { tx: signedTx } = await txBuilder.build().sign();
|
|
68
|
-
await submitAndConfirm(wallet, signedTx);
|
|
69
40
|
};
|
|
70
41
|
|
|
71
42
|
/** await for rewardAccounts$ to be registered, unregistered, as defined in states */
|
|
@@ -97,7 +68,7 @@ const deregisterAllStakeKeys = async (wallet: PersonalWallet): Promise<void> =>
|
|
|
97
68
|
} catch {
|
|
98
69
|
// Some stake keys are registered. Deregister them
|
|
99
70
|
const txBuilder = wallet.createTxBuilder();
|
|
100
|
-
txBuilder.
|
|
71
|
+
txBuilder.delegatePortfolio(null);
|
|
101
72
|
const { tx: deregTx } = await txBuilder.build().sign();
|
|
102
73
|
await submitAndConfirm(wallet, deregTx);
|
|
103
74
|
|
|
@@ -109,36 +80,44 @@ const deregisterAllStakeKeys = async (wallet: PersonalWallet): Promise<void> =>
|
|
|
109
80
|
}
|
|
110
81
|
};
|
|
111
82
|
|
|
112
|
-
const getPoolIds = async (wallet: PersonalWallet
|
|
83
|
+
const getPoolIds = async (wallet: PersonalWallet): Promise<Cardano.StakePool[]> => {
|
|
113
84
|
const activePools = await wallet.stakePoolProvider.queryStakePools({
|
|
114
85
|
filters: { status: [Cardano.StakePoolStatus.Active] },
|
|
115
|
-
pagination: { limit:
|
|
86
|
+
pagination: { limit: POOLS_COUNT, startAt: 0 }
|
|
116
87
|
});
|
|
117
|
-
expect(activePools.pageResults.length).toBeGreaterThanOrEqual(
|
|
118
|
-
return Array.from({ length:
|
|
88
|
+
expect(activePools.pageResults.length).toBeGreaterThanOrEqual(POOLS_COUNT);
|
|
89
|
+
return Array.from({ length: POOLS_COUNT }).map((_, index) => activePools.pageResults[index]);
|
|
119
90
|
};
|
|
120
91
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
);
|
|
92
|
+
/** Delegate to unique POOLS_COUNT pools. Use even distribution as default. */
|
|
93
|
+
const delegateToMultiplePools = async (
|
|
94
|
+
wallet: PersonalWallet,
|
|
95
|
+
weights = Array.from({ length: POOLS_COUNT }).map(() => 1)
|
|
96
|
+
) => {
|
|
97
|
+
const poolIds = await getPoolIds(wallet);
|
|
98
|
+
const portfolio: Pick<Cardano.Cip17DelegationPortfolio, 'pools'> = {
|
|
99
|
+
pools: poolIds.map(({ hexId: id }, idx) => ({ id, weight: weights[idx] }))
|
|
100
|
+
};
|
|
101
|
+
logger.debug('Delegating portfolio', portfolio);
|
|
102
|
+
|
|
103
|
+
const { tx } = await wallet.createTxBuilder().delegatePortfolio(portfolio).build().sign();
|
|
104
|
+
await submitAndConfirm(wallet, tx);
|
|
105
|
+
return poolIds;
|
|
106
|
+
};
|
|
131
107
|
|
|
132
|
-
|
|
133
|
-
|
|
108
|
+
const delegateAllToSinglePool = async (wallet: PersonalWallet): Promise<void> => {
|
|
109
|
+
// This is a negative testcase, simulating an HD wallet that has multiple stake keys delegated
|
|
110
|
+
// to the same stake pool. txBuilder.delegatePortfolio does not support this scenario.
|
|
111
|
+
const [{ id: poolId }] = await getPoolIds(wallet);
|
|
112
|
+
const txBuilder = wallet.createTxBuilder();
|
|
113
|
+
const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
|
|
114
|
+
txBuilder.partialTxBody.certificates = rewardAccounts.map(({ address }) =>
|
|
115
|
+
Cardano.createDelegationCert(address, poolId)
|
|
134
116
|
);
|
|
135
117
|
|
|
136
|
-
|
|
137
|
-
// Artificially add the certificates in TxBuilder. An api improvement will make the UX better
|
|
138
|
-
txBuilder.partialTxBody.certificates = [...stakeKeyRegCertificates, ...delegationCertificates];
|
|
118
|
+
logger.debug(`Delegating all stake keys to pool ${poolId}`);
|
|
139
119
|
const { tx } = await txBuilder.build().sign();
|
|
140
120
|
await submitAndConfirm(wallet, tx);
|
|
141
|
-
return poolIds;
|
|
142
121
|
};
|
|
143
122
|
|
|
144
123
|
describe('PersonalWallet/delegationDistribution', () => {
|
|
@@ -146,9 +125,8 @@ describe('PersonalWallet/delegationDistribution', () => {
|
|
|
146
125
|
|
|
147
126
|
beforeAll(async () => {
|
|
148
127
|
wallet = (await getWallet({ env, idx: 3, logger, name: 'Wallet', polling: { interval: 50 } })).wallet;
|
|
149
|
-
await
|
|
128
|
+
await fundWallet(wallet);
|
|
150
129
|
await deregisterAllStakeKeys(wallet);
|
|
151
|
-
await distributeFunds(wallet);
|
|
152
130
|
});
|
|
153
131
|
|
|
154
132
|
afterAll(() => {
|
|
@@ -158,19 +136,16 @@ describe('PersonalWallet/delegationDistribution', () => {
|
|
|
158
136
|
it('reports observable wallet multi delegation as delegationDistribution by pool', async () => {
|
|
159
137
|
await walletReady(wallet);
|
|
160
138
|
|
|
161
|
-
const walletAddresses = await firstValueFromTimed(wallet.addresses$);
|
|
162
|
-
const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
|
|
163
|
-
|
|
164
|
-
expect(rewardAccounts.length).toBe(5);
|
|
165
|
-
|
|
166
139
|
// No stake distribution initially
|
|
167
140
|
const delegationDistribution = await firstValueFrom(wallet.delegation.distribution$);
|
|
168
141
|
logger.info('Empty delegation distribution initially');
|
|
169
142
|
expect(delegationDistribution).toEqual(new Map());
|
|
170
143
|
|
|
171
144
|
const poolIds = await delegateToMultiplePools(wallet);
|
|
172
|
-
|
|
173
|
-
await
|
|
145
|
+
const walletAddresses = await firstValueFromTimed(wallet.addresses$);
|
|
146
|
+
const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
|
|
147
|
+
|
|
148
|
+
expect(rewardAccounts.length).toBe(POOLS_COUNT);
|
|
174
149
|
|
|
175
150
|
// Check that reward addresses were delegated
|
|
176
151
|
await walletReady(wallet);
|
|
@@ -204,20 +179,11 @@ describe('PersonalWallet/delegationDistribution', () => {
|
|
|
204
179
|
|
|
205
180
|
expect([...actualDelegationDistribution.values()]).toEqual(expectedDelegationDistribution);
|
|
206
181
|
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
txBuilder
|
|
213
|
-
.buildOutput()
|
|
214
|
-
.address(walletAddresses[walletAddresses.length - 1].address)
|
|
215
|
-
.coin(totalCoins - 2_000_000n) // leave some behind for fees
|
|
216
|
-
.toTxOut()
|
|
217
|
-
)
|
|
218
|
-
.build()
|
|
219
|
-
.sign();
|
|
220
|
-
await submitAndConfirm(wallet, txMoveFunds);
|
|
182
|
+
// Delegate so that last address has all funds
|
|
183
|
+
await delegateToMultiplePools(
|
|
184
|
+
wallet,
|
|
185
|
+
Array.from({ length: POOLS_COUNT }).map((_, idx) => (POOLS_COUNT === idx + 1 ? 1 : 0))
|
|
186
|
+
);
|
|
221
187
|
|
|
222
188
|
let simplifiedDelegationDistribution: Partial<DelegatedStake>[] = await firstValueFrom(
|
|
223
189
|
wallet.delegation.distribution$.pipe(
|
|
@@ -246,9 +212,7 @@ describe('PersonalWallet/delegationDistribution', () => {
|
|
|
246
212
|
);
|
|
247
213
|
|
|
248
214
|
// Delegate all reward accounts to the same pool. delegationDistribution$ should have 1 entry with 100% distribution
|
|
249
|
-
|
|
250
|
-
const { tx: txDelegateTo1Pool } = await txBuilder.delegate(poolIds[0].id).build().sign();
|
|
251
|
-
await submitAndConfirm(wallet, txDelegateTo1Pool);
|
|
215
|
+
await delegateAllToSinglePool(wallet);
|
|
252
216
|
simplifiedDelegationDistribution = await firstValueFrom(
|
|
253
217
|
wallet.delegation.distribution$.pipe(
|
|
254
218
|
tap((distribution) => {
|
|
@@ -68,7 +68,7 @@ describe('Ada handle', () => {
|
|
|
68
68
|
let policyScript: Cardano.NativeScript;
|
|
69
69
|
let assetIds: Cardano.AssetId[];
|
|
70
70
|
|
|
71
|
-
const assetNames = ['
|
|
71
|
+
const assetNames = ['68616e646c6531', '68616e646c6532'];
|
|
72
72
|
let walletAddress: Cardano.PaymentAddress;
|
|
73
73
|
const coins = 2_000_000n; // number of coins to use in each transaction
|
|
74
74
|
|