@cardano-sdk/e2e 0.46.0 → 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 +2 -0
- package/CHANGELOG.md +12 -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 +11 -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 +11 -1
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -18
- package/src/environment.ts +4 -0
- package/src/factories.ts +26 -0
- package/src/scripts/generate-dotenv.sh +3 -0
- package/test/load-test-custom/wallet-init/wallet-init.test.ts +6 -0
- package/test/wallet_epoch_3/PersonalWallet/drepRetirement.test.ts +296 -0
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",
|
|
@@ -75,20 +75,20 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.4",
|
|
77
77
|
"@cardano-ogmios/client": "6.9.0",
|
|
78
|
-
"@cardano-sdk/cardano-services": "~0.33.
|
|
79
|
-
"@cardano-sdk/cardano-services-client": "~0.23.
|
|
80
|
-
"@cardano-sdk/core": "~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
81
|
"@cardano-sdk/crypto": "~0.1.32",
|
|
82
|
-
"@cardano-sdk/hardware-ledger": "~0.12.
|
|
83
|
-
"@cardano-sdk/hardware-trezor": "~0.6.
|
|
84
|
-
"@cardano-sdk/input-selection": "~0.13.
|
|
85
|
-
"@cardano-sdk/key-management": "~0.24.
|
|
86
|
-
"@cardano-sdk/ogmios": "~0.18.
|
|
87
|
-
"@cardano-sdk/tx-construction": "~0.
|
|
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",
|
|
88
88
|
"@cardano-sdk/util": "~0.15.5",
|
|
89
|
-
"@cardano-sdk/util-dev": "~0.
|
|
90
|
-
"@cardano-sdk/util-rxjs": "~0.7.
|
|
91
|
-
"@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",
|
|
92
92
|
"@dcspark/cardano-multiplatform-lib-nodejs": "^3.1.1",
|
|
93
93
|
"@shiroyasha9/axios-fetch-adapter": "1.0.3",
|
|
94
94
|
"axios": "^1.7.4",
|
|
@@ -118,10 +118,10 @@
|
|
|
118
118
|
"@babel/core": "^7.18.2",
|
|
119
119
|
"@babel/preset-env": "^7.18.2",
|
|
120
120
|
"@babel/preset-typescript": "^7.17.12",
|
|
121
|
-
"@cardano-sdk/dapp-connector": "~0.12.
|
|
122
|
-
"@cardano-sdk/projection": "~0.12.
|
|
123
|
-
"@cardano-sdk/projection-typeorm": "~0.9.
|
|
124
|
-
"@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",
|
|
125
125
|
"@dcspark/cardano-multiplatform-lib-browser": "^3.1.1",
|
|
126
126
|
"@emurgo/cardano-message-signing-asmjs": "^1.0.1",
|
|
127
127
|
"@types/bunyan": "^1.8.8",
|
|
@@ -181,5 +181,5 @@
|
|
|
181
181
|
"publishConfig": {
|
|
182
182
|
"access": "public"
|
|
183
183
|
},
|
|
184
|
-
"gitHead": "
|
|
184
|
+
"gitHead": "cfb81dc2bf655e0a4d433b7c13a2aaa494510444"
|
|
185
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,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
BlockfrostAssetProvider,
|
|
40
41
|
BlockfrostChainHistoryProvider,
|
|
41
42
|
BlockfrostClient,
|
|
43
|
+
BlockfrostDRepProvider,
|
|
42
44
|
BlockfrostNetworkInfoProvider,
|
|
43
45
|
BlockfrostRewardsProvider,
|
|
44
46
|
BlockfrostTxSubmitProvider,
|
|
@@ -81,6 +83,7 @@ export type CreateKeyAgent = (dependencies: KeyAgentDependencies) => Promise<Asy
|
|
|
81
83
|
export const keyManagementFactory = new ProviderFactory<CreateKeyAgent>();
|
|
82
84
|
export const assetProviderFactory = new ProviderFactory<AssetProvider>();
|
|
83
85
|
export const chainHistoryProviderFactory = new ProviderFactory<ChainHistoryProvider>();
|
|
86
|
+
export const drepProviderFactory = new ProviderFactory<DRepProvider>();
|
|
84
87
|
export const networkInfoProviderFactory = new ProviderFactory<NetworkInfoProvider>();
|
|
85
88
|
export const rewardsProviderFactory = new ProviderFactory<RewardsProvider>();
|
|
86
89
|
export const txSubmitProviderFactory = new ProviderFactory<TxSubmitProvider>();
|
|
@@ -181,6 +184,19 @@ chainHistoryProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, lo
|
|
|
181
184
|
});
|
|
182
185
|
});
|
|
183
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
|
+
|
|
184
200
|
networkInfoProviderFactory.register(
|
|
185
201
|
HTTP_PROVIDER,
|
|
186
202
|
async (params: any, logger: Logger): Promise<NetworkInfoProvider> => {
|
|
@@ -483,6 +499,11 @@ export const getWallet = async (props: GetWalletProps) => {
|
|
|
483
499
|
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
484
500
|
logger
|
|
485
501
|
),
|
|
502
|
+
drepProvider: await drepProviderFactory.create(
|
|
503
|
+
env.TEST_CLIENT_DREP_PROVIDER,
|
|
504
|
+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
|
|
505
|
+
logger
|
|
506
|
+
),
|
|
486
507
|
handleProvider: await handleProviderFactory.create(
|
|
487
508
|
env.TEST_CLIENT_HANDLE_PROVIDER,
|
|
488
509
|
env.TEST_CLIENT_HANDLE_PROVIDER_PARAMS,
|
|
@@ -571,6 +592,11 @@ export const getSharedWallet = async (props: GetSharedWalletProps) => {
|
|
|
571
592
|
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
572
593
|
logger
|
|
573
594
|
),
|
|
595
|
+
drepProvider: await drepProviderFactory.create(
|
|
596
|
+
env.TEST_CLIENT_DREP_PROVIDER,
|
|
597
|
+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
|
|
598
|
+
logger
|
|
599
|
+
),
|
|
574
600
|
handleProvider: await handleProviderFactory.create(
|
|
575
601
|
env.TEST_CLIENT_HANDLE_PROVIDER,
|
|
576
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
|
|
@@ -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,
|
|
@@ -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
|
+
});
|