@cardano-sdk/e2e 0.32.8 → 0.33.1
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 +35 -0
- package/dist/cjs/factories.d.ts +26 -2
- package/dist/cjs/factories.d.ts.map +1 -1
- package/dist/cjs/factories.js +30 -2
- package/dist/cjs/factories.js.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/index.js +3 -3
- package/dist/cjs/tools/multi-delegation-data-gen/index.js.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.d.ts +8 -8
- package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.d.ts.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.js +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/util/handle-util.d.ts.map +1 -1
- package/dist/cjs/util/handle-util.js +8 -2
- package/dist/cjs/util/handle-util.js.map +1 -1
- package/dist/cjs/util/util.d.ts +4 -4
- package/dist/cjs/util/util.d.ts.map +1 -1
- package/dist/cjs/util/util.js +13 -6
- package/dist/cjs/util/util.js.map +1 -1
- package/dist/esm/factories.d.ts +26 -2
- package/dist/esm/factories.d.ts.map +1 -1
- package/dist/esm/factories.js +29 -2
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/index.js +3 -3
- package/dist/esm/tools/multi-delegation-data-gen/index.js.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/utils.d.ts +8 -8
- package/dist/esm/tools/multi-delegation-data-gen/utils/utils.d.ts.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/utils.js +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/utils.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/util/handle-util.d.ts.map +1 -1
- package/dist/esm/util/handle-util.js +8 -2
- package/dist/esm/util/handle-util.js.map +1 -1
- package/dist/esm/util/util.d.ts +4 -4
- package/dist/esm/util/util.d.ts.map +1 -1
- package/dist/esm/util/util.js +14 -7
- package/dist/esm/util/util.js.map +1 -1
- package/package.json +19 -19
- package/src/factories.ts +71 -2
- package/src/tools/multi-delegation-data-gen/index.ts +4 -4
- package/src/tools/multi-delegation-data-gen/utils/utils.ts +12 -12
- package/src/util/handle-util.ts +8 -2
- package/src/util/util.ts +19 -10
- package/test/artillery/wallet-restoration/types.ts +2 -2
- package/test/load-test-custom/wallet-init/wallet-init.test.ts +4 -4
- package/test/load-test-custom/wallet-restoration/wallet-restoration.test.ts +2 -2
- package/test/long-running/delegation-rewards.test.ts +6 -6
- package/test/long-running/multisig-wallet/multisig-delegation-rewards.test.ts +6 -6
- package/test/long-running/shared-wallet-delegation-rewards.test.ts +199 -0
- package/test/wallet/PersonalWallet/byron.test.ts +2 -2
- package/test/wallet/PersonalWallet/delegation.test.ts +5 -5
- package/test/wallet/PersonalWallet/delegationDistribution.test.ts +15 -15
- package/test/wallet/PersonalWallet/handle.test.ts +4 -4
- package/test/wallet/PersonalWallet/metadata.test.ts +2 -2
- package/test/wallet/PersonalWallet/mint.test.ts +10 -4
- package/test/wallet/PersonalWallet/multiAddress.test.ts +2 -2
- package/test/wallet/PersonalWallet/multisignature.test.ts +10 -4
- package/test/wallet/PersonalWallet/nft.test.ts +27 -9
- package/test/wallet/PersonalWallet/phase2validation.test.ts +26 -8
- package/test/wallet/PersonalWallet/pouchDbWalletStores.test.ts +1 -1
- package/test/wallet/PersonalWallet/txChainHistory.test.ts +4 -3
- package/test/wallet/PersonalWallet/unspendableUtxos.test.ts +3 -3
- package/test/wallet/SharedWallet/delegation.test.ts +245 -0
- package/test/wallet/SharedWallet/simpleTx.test.ts +123 -0
- package/test/wallet/SharedWallet/ultils.ts +327 -0
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
import * as dotenv from 'dotenv';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
dotenv.config({ path: path.join(__dirname, '../../../.env') });
|
|
6
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
6
7
|
import { Cardano } from '@cardano-sdk/core';
|
|
7
8
|
import { GroupedAddress, util } from '@cardano-sdk/key-management';
|
|
8
9
|
import { Logger } from 'ts-log';
|
|
9
10
|
import { MINUTE, createMockKeyAgent, getEnv, getWallet, waitForWalletStateSettle, walletVariables } from '../../../src';
|
|
10
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
11
11
|
import { logger } from '@cardano-sdk/util-dev';
|
|
12
12
|
import { mapToGroupedAddress } from '../../artillery/wallet-restoration/WalletRestoration';
|
|
13
13
|
|
|
@@ -34,7 +34,7 @@ const range = (toNum: number) => {
|
|
|
34
34
|
return resArr;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
const initWallets = async (walletsNum: number, addresses: GroupedAddress[]): Promise<
|
|
37
|
+
const initWallets = async (walletsNum: number, addresses: GroupedAddress[]): Promise<BaseWallet[]> => {
|
|
38
38
|
testLogger.info('Number of concurrent users: ', walletsNum);
|
|
39
39
|
let currentAddress;
|
|
40
40
|
const wallets = [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
1
2
|
import { Cardano, StakePoolProvider } from '@cardano-sdk/core';
|
|
2
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
3
3
|
import {
|
|
4
4
|
TestWallet,
|
|
5
5
|
getEnv,
|
|
@@ -16,7 +16,7 @@ import { waitForWalletStateSettle } from '../../../wallet/test/util';
|
|
|
16
16
|
|
|
17
17
|
const env = getEnv(walletVariables);
|
|
18
18
|
|
|
19
|
-
const submitDelegationTx = async (wallet:
|
|
19
|
+
const submitDelegationTx = async (wallet: BaseWallet, pools: Cardano.PoolId[]) => {
|
|
20
20
|
logger.info(`Creating delegation tx at epoch #${(await firstValueFrom(wallet.currentEpoch$)).epochNo}`);
|
|
21
21
|
const { tx: signedTx } = await wallet
|
|
22
22
|
.createTxBuilder()
|
|
@@ -33,7 +33,7 @@ const submitDelegationTx = async (wallet: PersonalWallet, pools: Cardano.PoolId[
|
|
|
33
33
|
return signedTx;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
const generateTxs = async (sendingWallet:
|
|
36
|
+
const generateTxs = async (sendingWallet: BaseWallet, receivingWallet: BaseWallet) => {
|
|
37
37
|
logger.info('Sending 100 txs to generate reward fees');
|
|
38
38
|
|
|
39
39
|
const tAdaToSend = 5_000_000n;
|
|
@@ -47,7 +47,7 @@ const generateTxs = async (sendingWallet: PersonalWallet, receivingWallet: Perso
|
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const buildSpendRewardTx = async (sendingWallet:
|
|
50
|
+
const buildSpendRewardTx = async (sendingWallet: BaseWallet, receivingWallet: BaseWallet) => {
|
|
51
51
|
const tAdaToSend = 5_000_000n;
|
|
52
52
|
const [{ address: receivingAddress }] = await firstValueFrom(receivingWallet.addresses$);
|
|
53
53
|
const txBuilder = sendingWallet.createTxBuilder();
|
|
@@ -77,8 +77,8 @@ const getPoolIds = async (stakePoolProvider: StakePoolProvider, count: number) =
|
|
|
77
77
|
|
|
78
78
|
describe('delegation rewards', () => {
|
|
79
79
|
let providers: TestWallet['providers'];
|
|
80
|
-
let wallet1:
|
|
81
|
-
let wallet2:
|
|
80
|
+
let wallet1: BaseWallet;
|
|
81
|
+
let wallet2: BaseWallet;
|
|
82
82
|
|
|
83
83
|
const initializeWallets = async () => {
|
|
84
84
|
({ wallet: wallet1, providers } = await getWallet({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as Crypto from '@cardano-sdk/crypto';
|
|
2
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
2
3
|
import { Cardano, EraSummary, StakePoolProvider, createSlotEpochCalc } from '@cardano-sdk/core';
|
|
3
4
|
import { InMemoryKeyAgent, KeyRole } from '@cardano-sdk/key-management';
|
|
4
5
|
import { MultiSigTx } from './MultiSigTx';
|
|
5
6
|
import { MultiSigWallet } from './MultiSigWallet';
|
|
6
7
|
import { Observable, filter, firstValueFrom, map, take } from 'rxjs';
|
|
7
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
8
8
|
import { TrackerSubject } from '@cardano-sdk/util-rxjs';
|
|
9
9
|
import {
|
|
10
10
|
bip32Ed25519Factory,
|
|
@@ -49,7 +49,7 @@ const getPoolIds = async (stakePoolProvider: StakePoolProvider, count: number) =
|
|
|
49
49
|
return poolIds;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
const fundMultiSigWallet = async (sendingWallet:
|
|
52
|
+
const fundMultiSigWallet = async (sendingWallet: BaseWallet, address: Cardano.PaymentAddress) => {
|
|
53
53
|
logger.info(`Funding multisig wallet with address: ${address}`);
|
|
54
54
|
|
|
55
55
|
const tAdaToSend = 5_000_000n;
|
|
@@ -60,7 +60,7 @@ const fundMultiSigWallet = async (sendingWallet: PersonalWallet, address: Cardan
|
|
|
60
60
|
await sendingWallet.submitTx(signedTx);
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
const getKeyAgent = async (mnemonics: string, faucetWallet:
|
|
63
|
+
const getKeyAgent = async (mnemonics: string, faucetWallet: BaseWallet, bip32Ed25519: Crypto.Bip32Ed25519) => {
|
|
64
64
|
const genesis = await firstValueFrom(faucetWallet.genesisParameters$);
|
|
65
65
|
|
|
66
66
|
const keyAgent = await createStandaloneKeyAgent(mnemonics.split(' '), genesis, bip32Ed25519);
|
|
@@ -70,7 +70,7 @@ const getKeyAgent = async (mnemonics: string, faucetWallet: PersonalWallet, bip3
|
|
|
70
70
|
return { keyAgent, pubKey };
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
const generateTxs = async (sendingWallet:
|
|
73
|
+
const generateTxs = async (sendingWallet: BaseWallet, receivingWallet: BaseWallet) => {
|
|
74
74
|
logger.info('Sending 100 txs to generate reward fees');
|
|
75
75
|
|
|
76
76
|
const tAdaToSend = 5_000_000n;
|
|
@@ -86,7 +86,7 @@ const generateTxs = async (sendingWallet: PersonalWallet, receivingWallet: Perso
|
|
|
86
86
|
|
|
87
87
|
const createMultiSignWallet = async (
|
|
88
88
|
keyAgent: InMemoryKeyAgent,
|
|
89
|
-
faucetWallet:
|
|
89
|
+
faucetWallet: BaseWallet,
|
|
90
90
|
participants: Array<Crypto.Ed25519PublicKeyHex>
|
|
91
91
|
) => {
|
|
92
92
|
const props = {
|
|
@@ -117,7 +117,7 @@ const getTxConfirmationEpoch = async (
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
describe('multi signature wallet', () => {
|
|
120
|
-
let faucetWallet:
|
|
120
|
+
let faucetWallet: BaseWallet;
|
|
121
121
|
let aliceKeyAgent: InMemoryKeyAgent;
|
|
122
122
|
let bobKeyAgent: InMemoryKeyAgent;
|
|
123
123
|
let charlotteKeyAgent: InMemoryKeyAgent;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
2
|
+
import { Cardano, StakePoolProvider } from '@cardano-sdk/core';
|
|
3
|
+
import { buildSharedWallets } from '../wallet/SharedWallet/ultils';
|
|
4
|
+
import { filter, firstValueFrom, map, take } from 'rxjs';
|
|
5
|
+
import {
|
|
6
|
+
getEnv,
|
|
7
|
+
getTxConfirmationEpoch,
|
|
8
|
+
getWallet,
|
|
9
|
+
runningAgainstLocalNetwork,
|
|
10
|
+
submitAndConfirm,
|
|
11
|
+
waitForEpoch,
|
|
12
|
+
walletReady,
|
|
13
|
+
walletVariables
|
|
14
|
+
} from '../../src';
|
|
15
|
+
import { isNotNil } from '@cardano-sdk/util';
|
|
16
|
+
import { logger } from '@cardano-sdk/util-dev';
|
|
17
|
+
import { waitForWalletStateSettle } from '../../../wallet/test/util';
|
|
18
|
+
|
|
19
|
+
const env = getEnv(walletVariables);
|
|
20
|
+
|
|
21
|
+
const submitDelegationTx = async (alice: BaseWallet, bob: BaseWallet, charlotte: BaseWallet, pool: Cardano.PoolId) => {
|
|
22
|
+
logger.info(`Creating delegation tx at epoch #${(await firstValueFrom(alice.currentEpoch$)).epochNo}`);
|
|
23
|
+
let tx = (await alice.createTxBuilder().delegateFirstStakeCredential(pool).build().sign()).tx;
|
|
24
|
+
|
|
25
|
+
tx = await bob.updateWitness({ sender: { id: 'e2e' }, tx });
|
|
26
|
+
tx = await charlotte.updateWitness({ sender: { id: 'e2e' }, tx });
|
|
27
|
+
await alice.submitTx(tx);
|
|
28
|
+
|
|
29
|
+
const { epochNo } = await firstValueFrom(alice.currentEpoch$);
|
|
30
|
+
logger.info(`Delegation tx ${tx.id} submitted at epoch #${epochNo}`);
|
|
31
|
+
|
|
32
|
+
return tx;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const generateTxs = async (sendingWallet: BaseWallet, receivingWallet: BaseWallet) => {
|
|
36
|
+
logger.info('Sending 100 txs to generate reward fees');
|
|
37
|
+
|
|
38
|
+
const tAdaToSend = 5_000_000n;
|
|
39
|
+
const [{ address: receivingAddress }] = await firstValueFrom(receivingWallet.addresses$);
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < 100; i++) {
|
|
42
|
+
const txBuilder = sendingWallet.createTxBuilder();
|
|
43
|
+
const txOut = await txBuilder.buildOutput().address(receivingAddress).coin(tAdaToSend).build();
|
|
44
|
+
const { tx: signedTx } = await txBuilder.addOutput(txOut).build().sign();
|
|
45
|
+
await sendingWallet.submitTx(signedTx);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const buildSpendRewardTx = async (
|
|
50
|
+
alice: BaseWallet,
|
|
51
|
+
bob: BaseWallet,
|
|
52
|
+
charlotte: BaseWallet,
|
|
53
|
+
receivingWallet: BaseWallet
|
|
54
|
+
) => {
|
|
55
|
+
const tAdaToSend = 5_000_000n;
|
|
56
|
+
const [{ address: receivingAddress }] = await firstValueFrom(receivingWallet.addresses$);
|
|
57
|
+
const txBuilder = alice.createTxBuilder();
|
|
58
|
+
const txOut = await txBuilder.buildOutput().address(receivingAddress).coin(tAdaToSend).build();
|
|
59
|
+
const tx = txBuilder.addOutput(txOut).build();
|
|
60
|
+
|
|
61
|
+
const { body } = await tx.inspect();
|
|
62
|
+
logger.debug('Body of tx before sign');
|
|
63
|
+
logger.debug(body);
|
|
64
|
+
let signedTx = (await tx.sign()).tx;
|
|
65
|
+
|
|
66
|
+
signedTx = await bob.updateWitness({ sender: { id: 'e2e' }, tx: signedTx });
|
|
67
|
+
signedTx = await charlotte.updateWitness({ sender: { id: 'e2e' }, tx: signedTx });
|
|
68
|
+
|
|
69
|
+
logger.debug('Body of tx after sign');
|
|
70
|
+
logger.debug(signedTx.body);
|
|
71
|
+
|
|
72
|
+
return signedTx;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const getPoolIds = async (stakePoolProvider: StakePoolProvider, count: number) => {
|
|
76
|
+
const activePools = await stakePoolProvider.queryStakePools({
|
|
77
|
+
filters: { pledgeMet: true, status: [Cardano.StakePoolStatus.Active] },
|
|
78
|
+
pagination: { limit: count, startAt: 0 }
|
|
79
|
+
});
|
|
80
|
+
expect(activePools.totalResultCount).toBeGreaterThanOrEqual(count);
|
|
81
|
+
const poolIds = activePools.pageResults.map(({ id }) => id);
|
|
82
|
+
expect(poolIds.every((poolId) => poolId !== undefined)).toBeTruthy();
|
|
83
|
+
logger.info('Wallet funds will be staked to pools:', poolIds);
|
|
84
|
+
return poolIds;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
describe('delegation rewards', () => {
|
|
88
|
+
let fundingTx: Cardano.Tx<Cardano.TxBody>;
|
|
89
|
+
let faucetWallet: BaseWallet;
|
|
90
|
+
let faucetAddress: Cardano.PaymentAddress;
|
|
91
|
+
let aliceMultiSigWallet: BaseWallet;
|
|
92
|
+
let bobMultiSigWallet: BaseWallet;
|
|
93
|
+
let charlotteMultiSigWallet: BaseWallet;
|
|
94
|
+
let stakePoolProvider: StakePoolProvider;
|
|
95
|
+
|
|
96
|
+
const initialFunds = 10_000_000n;
|
|
97
|
+
|
|
98
|
+
beforeAll(async () => {
|
|
99
|
+
jest.setTimeout(180_000);
|
|
100
|
+
|
|
101
|
+
({
|
|
102
|
+
wallet: faucetWallet,
|
|
103
|
+
providers: { stakePoolProvider }
|
|
104
|
+
} = await getWallet({ env, logger, name: 'Sending Wallet', polling: { interval: 50 } }));
|
|
105
|
+
|
|
106
|
+
// Make sure the wallet has sufficient funds to run this test
|
|
107
|
+
await walletReady(faucetWallet, initialFunds);
|
|
108
|
+
|
|
109
|
+
faucetAddress = (await firstValueFrom(faucetWallet.addresses$))[0].address;
|
|
110
|
+
|
|
111
|
+
({ aliceMultiSigWallet, bobMultiSigWallet, charlotteMultiSigWallet } = await buildSharedWallets(
|
|
112
|
+
env,
|
|
113
|
+
await firstValueFrom(faucetWallet.genesisParameters$),
|
|
114
|
+
logger
|
|
115
|
+
));
|
|
116
|
+
|
|
117
|
+
await Promise.all([
|
|
118
|
+
waitForWalletStateSettle(aliceMultiSigWallet),
|
|
119
|
+
waitForWalletStateSettle(bobMultiSigWallet),
|
|
120
|
+
waitForWalletStateSettle(charlotteMultiSigWallet)
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
const [{ address: receivingAddress }] = await firstValueFrom(aliceMultiSigWallet.addresses$);
|
|
124
|
+
|
|
125
|
+
logger.info(`Address ${faucetAddress} will send ${initialFunds} lovelace to address ${receivingAddress}.`);
|
|
126
|
+
|
|
127
|
+
// Send 10 tADA to the shared wallet.
|
|
128
|
+
const txBuilder = faucetWallet.createTxBuilder();
|
|
129
|
+
const txOutput = await txBuilder.buildOutput().address(receivingAddress).coin(initialFunds).build();
|
|
130
|
+
fundingTx = (await txBuilder.addOutput(txOutput).build().sign()).tx;
|
|
131
|
+
await faucetWallet.submitTx(fundingTx);
|
|
132
|
+
|
|
133
|
+
logger.info(
|
|
134
|
+
`Submitted transaction id: ${fundingTx.id}, inputs: ${JSON.stringify(
|
|
135
|
+
fundingTx.body.inputs.map((txIn) => [txIn.txId, txIn.index])
|
|
136
|
+
)} and outputs:${JSON.stringify(
|
|
137
|
+
fundingTx.body.outputs.map((txOut) => [txOut.address, Number.parseInt(txOut.value.coins.toString())])
|
|
138
|
+
)}.`
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
afterAll(() => {
|
|
143
|
+
faucetWallet.shutdown();
|
|
144
|
+
aliceMultiSigWallet.shutdown();
|
|
145
|
+
bobMultiSigWallet.shutdown();
|
|
146
|
+
charlotteMultiSigWallet.shutdown();
|
|
147
|
+
faucetWallet.shutdown();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('will receive rewards for delegated tADA and can spend them', async () => {
|
|
151
|
+
if (!(await runningAgainstLocalNetwork())) {
|
|
152
|
+
return logger.fatal(
|
|
153
|
+
"Skipping test 'will receive rewards for delegated tADA' as it should only run with a fast test network"
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const txFoundInHistory = await firstValueFrom(
|
|
158
|
+
aliceMultiSigWallet.transactions.history$.pipe(
|
|
159
|
+
map((txs) => txs.find((tx) => tx.id === fundingTx.id)),
|
|
160
|
+
filter(isNotNil),
|
|
161
|
+
take(1)
|
|
162
|
+
)
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
expect(txFoundInHistory?.id).toEqual(fundingTx.id);
|
|
166
|
+
|
|
167
|
+
// Arrange
|
|
168
|
+
const [poolId] = await getPoolIds(stakePoolProvider, 1);
|
|
169
|
+
|
|
170
|
+
// Stake and wait for reward
|
|
171
|
+
const signedTx = await submitDelegationTx(aliceMultiSigWallet, bobMultiSigWallet, charlotteMultiSigWallet, poolId);
|
|
172
|
+
|
|
173
|
+
const delegationTxConfirmedAtEpoch = await getTxConfirmationEpoch(aliceMultiSigWallet, signedTx);
|
|
174
|
+
|
|
175
|
+
logger.info(`Delegation tx confirmed at epoch #${delegationTxConfirmedAtEpoch}`);
|
|
176
|
+
|
|
177
|
+
await waitForEpoch(aliceMultiSigWallet, delegationTxConfirmedAtEpoch + 2);
|
|
178
|
+
|
|
179
|
+
await generateTxs(faucetWallet, aliceMultiSigWallet);
|
|
180
|
+
await waitForEpoch(aliceMultiSigWallet, delegationTxConfirmedAtEpoch + 4);
|
|
181
|
+
|
|
182
|
+
// Check reward
|
|
183
|
+
await waitForWalletStateSettle(aliceMultiSigWallet);
|
|
184
|
+
const rewards = await firstValueFrom(aliceMultiSigWallet.balance.rewardAccounts.rewards$);
|
|
185
|
+
expect(rewards).toBeGreaterThan(0n);
|
|
186
|
+
|
|
187
|
+
logger.info(`Generated rewards: ${rewards} tLovelace`);
|
|
188
|
+
|
|
189
|
+
// Spend reward
|
|
190
|
+
const spendRewardTx = await buildSpendRewardTx(
|
|
191
|
+
aliceMultiSigWallet,
|
|
192
|
+
bobMultiSigWallet,
|
|
193
|
+
charlotteMultiSigWallet,
|
|
194
|
+
faucetWallet
|
|
195
|
+
);
|
|
196
|
+
expect(spendRewardTx.body.withdrawals?.length).toBeGreaterThan(0);
|
|
197
|
+
await submitAndConfirm(aliceMultiSigWallet, spendRewardTx);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
2
3
|
import { Cardano } from '@cardano-sdk/core';
|
|
3
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
4
4
|
import { createLogger } from '@cardano-sdk/util-dev';
|
|
5
5
|
import { filter, firstValueFrom, map, take } from 'rxjs';
|
|
6
6
|
import { getEnv, walletVariables } from '../../../src/environment';
|
|
@@ -11,7 +11,7 @@ const env = getEnv(walletVariables);
|
|
|
11
11
|
const logger = createLogger();
|
|
12
12
|
|
|
13
13
|
describe('PersonalWallet/byron', () => {
|
|
14
|
-
let wallet:
|
|
14
|
+
let wallet: BaseWallet;
|
|
15
15
|
|
|
16
16
|
beforeAll(async () => {
|
|
17
17
|
wallet = (await getWallet({ env, idx: 0, logger, name: 'Wallet', polling: { interval: 50 } })).wallet;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable max-statements */
|
|
2
2
|
import * as Crypto from '@cardano-sdk/crypto';
|
|
3
|
+
import { BaseWallet, ObservableWallet } from '@cardano-sdk/wallet';
|
|
3
4
|
import { BigIntMath } from '@cardano-sdk/util';
|
|
4
5
|
import { Cardano } from '@cardano-sdk/core';
|
|
5
|
-
import { ObservableWallet, PersonalWallet } from '@cardano-sdk/wallet';
|
|
6
6
|
import {
|
|
7
7
|
TX_TIMEOUT_DEFAULT,
|
|
8
8
|
TestWallet,
|
|
@@ -33,7 +33,7 @@ const getWalletStateSnapshot = async (wallet: ObservableWallet) => {
|
|
|
33
33
|
return {
|
|
34
34
|
balance: { available: balanceAvailable, deposit, total: balanceTotal },
|
|
35
35
|
epoch: epoch.epochNo,
|
|
36
|
-
isStakeKeyRegistered: rewardAccount.
|
|
36
|
+
isStakeKeyRegistered: rewardAccount.credentialStatus === Cardano.StakeCredentialStatus.Registered,
|
|
37
37
|
publicStakeKey,
|
|
38
38
|
rewardAccount,
|
|
39
39
|
rewardsBalance,
|
|
@@ -73,7 +73,7 @@ describe('PersonalWallet/delegation', () => {
|
|
|
73
73
|
wallet2.wallet.shutdown();
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
const chooseWallets = async (): Promise<[
|
|
76
|
+
const chooseWallets = async (): Promise<[BaseWallet, BaseWallet]> => {
|
|
77
77
|
const wallet1Balance = await firstValueFrom(wallet1.wallet.balance.utxo.available$);
|
|
78
78
|
const wallet2Balance = await firstValueFrom(wallet2.wallet.balance.utxo.available$);
|
|
79
79
|
return wallet1Balance.coins > wallet2Balance.coins
|
|
@@ -171,7 +171,7 @@ describe('PersonalWallet/delegation', () => {
|
|
|
171
171
|
|
|
172
172
|
const stakeKeyHash = await bip32Ed25519.getPubKeyHash(tx1ConfirmedState.publicStakeKey.publicStakeKey);
|
|
173
173
|
expect(stakeKeyHash).toEqual(Cardano.RewardAccount.toHash(tx1ConfirmedState.rewardAccount.address));
|
|
174
|
-
expect(tx1ConfirmedState.publicStakeKey.
|
|
174
|
+
expect(tx1ConfirmedState.publicStakeKey.credentialStatus).toBe(Cardano.StakeCredentialStatus.Registered);
|
|
175
175
|
|
|
176
176
|
// Make a 2nd tx with key de-registration
|
|
177
177
|
const { tx: txDeregisterSigned } = await sourceWallet.createTxBuilder().delegatePortfolio(null).build().sign();
|
|
@@ -181,7 +181,7 @@ describe('PersonalWallet/delegation', () => {
|
|
|
181
181
|
|
|
182
182
|
// No longer delegating
|
|
183
183
|
expect(tx2ConfirmedState.rewardAccount.delegatee?.nextNextEpoch?.id).toBeUndefined();
|
|
184
|
-
expect(tx2ConfirmedState.publicStakeKey.
|
|
184
|
+
expect(tx2ConfirmedState.publicStakeKey.credentialStatus).toBe(Cardano.StakeCredentialStatus.Unregistered);
|
|
185
185
|
|
|
186
186
|
// Deposit is returned to wallet balance
|
|
187
187
|
const expectedCoinsAfterTx2 = expectedCoinsAfterTx1 + stakeKeyDeposit - txDeregisterSigned.body.fee;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { BaseWallet, DelegatedStake, createUtxoBalanceByAddressTracker } from '@cardano-sdk/wallet';
|
|
1
2
|
import { Cardano } from '@cardano-sdk/core';
|
|
2
|
-
import { DelegatedStake, PersonalWallet, createUtxoBalanceByAddressTracker } from '@cardano-sdk/wallet';
|
|
3
3
|
import { MINUTE, firstValueFromTimed, getWallet, submitAndConfirm, walletReady } from '../../../src';
|
|
4
4
|
import { Observable, filter, firstValueFrom, map, tap } from 'rxjs';
|
|
5
5
|
import { Percent } from '@cardano-sdk/util';
|
|
@@ -13,7 +13,7 @@ const POOLS_COUNT = 5;
|
|
|
13
13
|
const distributionMessage = 'ObservableWallet.delegation.distribution$:';
|
|
14
14
|
|
|
15
15
|
/** Distribute the wallet funds evenly across all its addresses */
|
|
16
|
-
const fundWallet = async (wallet:
|
|
16
|
+
const fundWallet = async (wallet: BaseWallet) => {
|
|
17
17
|
await walletReady(wallet, 0n);
|
|
18
18
|
const addresses = await firstValueFrom(wallet.addresses$);
|
|
19
19
|
|
|
@@ -42,13 +42,13 @@ const fundWallet = async (wallet: PersonalWallet) => {
|
|
|
42
42
|
/** await for rewardAccounts$ to be registered, unregistered, as defined in states */
|
|
43
43
|
const rewardAccountStatuses = async (
|
|
44
44
|
rewardAccounts$: Observable<Cardano.RewardAccountInfo[]>,
|
|
45
|
-
statuses: Cardano.
|
|
45
|
+
statuses: Cardano.StakeCredentialStatus[],
|
|
46
46
|
timeout = MINUTE
|
|
47
47
|
) =>
|
|
48
48
|
firstValueFromTimed(
|
|
49
49
|
rewardAccounts$.pipe(
|
|
50
|
-
tap((accts) => accts.map(({ address,
|
|
51
|
-
map((accts) => accts.map(({
|
|
50
|
+
tap((accts) => accts.map(({ address, credentialStatus }) => logger.debug(address, credentialStatus))),
|
|
51
|
+
map((accts) => accts.map(({ credentialStatus }) => credentialStatus)),
|
|
52
52
|
filter((statusArr) => statusArr.every((s) => statuses.includes(s)))
|
|
53
53
|
),
|
|
54
54
|
`Timeout waiting for all reward accounts stake keys to be one of ${statuses.join('|')}`,
|
|
@@ -56,12 +56,12 @@ const rewardAccountStatuses = async (
|
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
/** Create stakeKey deregistration transaction for all reward accounts */
|
|
59
|
-
const deregisterAllStakeKeys = async (wallet:
|
|
59
|
+
const deregisterAllStakeKeys = async (wallet: BaseWallet): Promise<void> => {
|
|
60
60
|
await walletReady(wallet, 0n);
|
|
61
61
|
try {
|
|
62
62
|
await rewardAccountStatuses(
|
|
63
63
|
wallet.delegation.rewardAccounts$,
|
|
64
|
-
[Cardano.
|
|
64
|
+
[Cardano.StakeCredentialStatus.Unregistered, Cardano.StakeCredentialStatus.Unregistering],
|
|
65
65
|
0
|
|
66
66
|
);
|
|
67
67
|
logger.info('Stake keys are already deregistered');
|
|
@@ -73,14 +73,14 @@ const deregisterAllStakeKeys = async (wallet: PersonalWallet): Promise<void> =>
|
|
|
73
73
|
await submitAndConfirm(wallet, deregTx);
|
|
74
74
|
|
|
75
75
|
await rewardAccountStatuses(wallet.delegation.rewardAccounts$, [
|
|
76
|
-
Cardano.
|
|
77
|
-
Cardano.
|
|
76
|
+
Cardano.StakeCredentialStatus.Unregistered,
|
|
77
|
+
Cardano.StakeCredentialStatus.Unregistering
|
|
78
78
|
]);
|
|
79
79
|
logger.info('Deregistered all stake keys');
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
const getPoolIds = async (wallet:
|
|
83
|
+
const getPoolIds = async (wallet: BaseWallet): Promise<Cardano.StakePool[]> => {
|
|
84
84
|
const activePools = await wallet.stakePoolProvider.queryStakePools({
|
|
85
85
|
filters: { status: [Cardano.StakePoolStatus.Active] },
|
|
86
86
|
pagination: { limit: POOLS_COUNT, startAt: 0 }
|
|
@@ -91,7 +91,7 @@ const getPoolIds = async (wallet: PersonalWallet): Promise<Cardano.StakePool[]>
|
|
|
91
91
|
|
|
92
92
|
/** Delegate to unique POOLS_COUNT pools. Use even distribution as default. */
|
|
93
93
|
const delegateToMultiplePools = async (
|
|
94
|
-
wallet:
|
|
94
|
+
wallet: BaseWallet,
|
|
95
95
|
weights = Array.from({ length: POOLS_COUNT }).map(() => 1)
|
|
96
96
|
) => {
|
|
97
97
|
const poolIds = await getPoolIds(wallet);
|
|
@@ -106,7 +106,7 @@ const delegateToMultiplePools = async (
|
|
|
106
106
|
return { poolIds, portfolio };
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
const delegateAllToSinglePool = async (wallet:
|
|
109
|
+
const delegateAllToSinglePool = async (wallet: BaseWallet): Promise<void> => {
|
|
110
110
|
// This is a negative testcase, simulating an HD wallet that has multiple stake keys delegated
|
|
111
111
|
// to the same stake pool. txBuilder.delegatePortfolio does not support this scenario.
|
|
112
112
|
const [{ id: poolId }] = await getPoolIds(wallet);
|
|
@@ -122,7 +122,7 @@ const delegateAllToSinglePool = async (wallet: PersonalWallet): Promise<void> =>
|
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
describe('PersonalWallet/delegationDistribution', () => {
|
|
125
|
-
let wallet:
|
|
125
|
+
let wallet: BaseWallet;
|
|
126
126
|
|
|
127
127
|
beforeAll(async () => {
|
|
128
128
|
wallet = (await getWallet({ env, idx: 3, logger, name: 'Wallet', polling: { interval: 50 } })).wallet;
|
|
@@ -153,8 +153,8 @@ describe('PersonalWallet/delegationDistribution', () => {
|
|
|
153
153
|
// Check that reward addresses were delegated
|
|
154
154
|
await walletReady(wallet);
|
|
155
155
|
await rewardAccountStatuses(wallet.delegation.rewardAccounts$, [
|
|
156
|
-
Cardano.
|
|
157
|
-
Cardano.
|
|
156
|
+
Cardano.StakeCredentialStatus.Registering,
|
|
157
|
+
Cardano.StakeCredentialStatus.Registered
|
|
158
158
|
]);
|
|
159
159
|
logger.debug('Delegations successfully done');
|
|
160
160
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
2
3
|
import { Cardano, metadatum } from '@cardano-sdk/core';
|
|
3
4
|
import { KeyAgent, TransactionSigner } from '@cardano-sdk/key-management';
|
|
4
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
5
5
|
import {
|
|
6
6
|
bip32Ed25519Factory,
|
|
7
7
|
burnTokens,
|
|
@@ -33,9 +33,9 @@ const toHex = (value: string) =>
|
|
|
33
33
|
.join('');
|
|
34
34
|
|
|
35
35
|
describe('Ada handle', () => {
|
|
36
|
-
let wallet:
|
|
36
|
+
let wallet: BaseWallet;
|
|
37
37
|
let keyAgent: KeyAgent;
|
|
38
|
-
let receivingWallet:
|
|
38
|
+
let receivingWallet: BaseWallet;
|
|
39
39
|
let policySigner: TransactionSigner;
|
|
40
40
|
let policyId: Cardano.PolicyId;
|
|
41
41
|
let policyScript: Cardano.NativeScript;
|
|
@@ -123,7 +123,7 @@ describe('Ada handle', () => {
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
// eslint-disable-next-line max-statements
|
|
126
|
-
it("
|
|
126
|
+
it("BaseWallet discovers it's own cip25 and cip68 handles", async () => {
|
|
127
127
|
await mintCIP25andCIP68Handles(wallet, keyAgent, policyId);
|
|
128
128
|
let utxo = await firstValueFrom(wallet.balance.utxo.available$);
|
|
129
129
|
let receivingUtxo = await firstValueFrom(receivingWallet.balance.utxo.available$);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { BaseWallet, createWalletUtil } from '@cardano-sdk/wallet';
|
|
1
2
|
import { Cardano } from '@cardano-sdk/core';
|
|
2
|
-
import { PersonalWallet, createWalletUtil } from '@cardano-sdk/wallet';
|
|
3
3
|
import { filter, firstValueFrom, map } from 'rxjs';
|
|
4
4
|
import { getEnv, getWallet, walletReady, walletVariables } from '../../../src';
|
|
5
5
|
import { isNotNil } from '@cardano-sdk/util';
|
|
@@ -8,7 +8,7 @@ import { logger } from '@cardano-sdk/util-dev';
|
|
|
8
8
|
const env = getEnv(walletVariables);
|
|
9
9
|
|
|
10
10
|
describe('PersonalWallet/metadata', () => {
|
|
11
|
-
let wallet:
|
|
11
|
+
let wallet: BaseWallet;
|
|
12
12
|
let ownAddress: Cardano.PaymentAddress;
|
|
13
13
|
|
|
14
14
|
beforeAll(async () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { BaseWallet, FinalizeTxProps } from '@cardano-sdk/wallet';
|
|
1
2
|
import { Cardano, nativeScriptPolicyId } from '@cardano-sdk/core';
|
|
2
|
-
import { FinalizeTxProps, PersonalWallet } from '@cardano-sdk/wallet';
|
|
3
3
|
import { InitializeTxProps } from '@cardano-sdk/tx-construction';
|
|
4
4
|
import { KeyRole, util } from '@cardano-sdk/key-management';
|
|
5
5
|
import {
|
|
@@ -20,7 +20,7 @@ const env = getEnv(walletVariables);
|
|
|
20
20
|
const logger = createLogger();
|
|
21
21
|
|
|
22
22
|
describe('PersonalWallet/mint', () => {
|
|
23
|
-
let wallet:
|
|
23
|
+
let wallet: BaseWallet;
|
|
24
24
|
|
|
25
25
|
afterAll(() => {
|
|
26
26
|
wallet.shutdown();
|
|
@@ -79,14 +79,20 @@ describe('PersonalWallet/mint', () => {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
]),
|
|
82
|
-
|
|
82
|
+
signingOptions: {
|
|
83
|
+
extraSigners: [alicePolicySigner]
|
|
84
|
+
},
|
|
85
|
+
witness: { scripts: [policyScript] }
|
|
83
86
|
};
|
|
84
87
|
|
|
85
88
|
const unsignedTx = await wallet.initializeTx(txProps);
|
|
86
89
|
|
|
87
90
|
const finalizeProps: FinalizeTxProps = {
|
|
91
|
+
signingOptions: {
|
|
92
|
+
extraSigners: [alicePolicySigner]
|
|
93
|
+
},
|
|
88
94
|
tx: unsignedTx,
|
|
89
|
-
witness: {
|
|
95
|
+
witness: { scripts: [policyScript] }
|
|
90
96
|
};
|
|
91
97
|
|
|
92
98
|
const signedTx = await wallet.finalizeTx(finalizeProps);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
2
|
import { AddressType, GroupedAddress, util } from '@cardano-sdk/key-management';
|
|
3
|
+
import { BaseWallet } from '@cardano-sdk/wallet';
|
|
3
4
|
import { Cardano } from '@cardano-sdk/core';
|
|
4
5
|
import {
|
|
5
6
|
KeyAgentFactoryProps,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
normalizeTxBody,
|
|
11
12
|
walletReady
|
|
12
13
|
} from '../../../src';
|
|
13
|
-
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
14
14
|
import { createLogger } from '@cardano-sdk/util-dev';
|
|
15
15
|
import { filter, map, take } from 'rxjs';
|
|
16
16
|
import { getEnv, walletVariables } from '../../../src/environment';
|
|
@@ -23,7 +23,7 @@ const PAYMENT_ADDRESSES_TO_GENERATE = PAYMENT_INDICES_TO_GENERATE * 2; // Extern
|
|
|
23
23
|
const COINS_PER_ADDRESS = 3_000_000n;
|
|
24
24
|
|
|
25
25
|
describe('PersonalWallet/multiAddress', () => {
|
|
26
|
-
let wallet:
|
|
26
|
+
let wallet: BaseWallet;
|
|
27
27
|
|
|
28
28
|
beforeAll(async () => {
|
|
29
29
|
wallet = (await getWallet({ env, idx: 0, logger, name: 'Wallet', polling: { interval: 50 } })).wallet;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
|
+
import { BaseWallet, FinalizeTxProps } from '@cardano-sdk/wallet';
|
|
2
3
|
import { Cardano, nativeScriptPolicyId } from '@cardano-sdk/core';
|
|
3
|
-
import { FinalizeTxProps, PersonalWallet } from '@cardano-sdk/wallet';
|
|
4
4
|
import { InitializeTxProps } from '@cardano-sdk/tx-construction';
|
|
5
5
|
import { KeyRole, util } from '@cardano-sdk/key-management';
|
|
6
6
|
import {
|
|
@@ -20,7 +20,7 @@ const env = getEnv(walletVariables);
|
|
|
20
20
|
const logger = createLogger();
|
|
21
21
|
|
|
22
22
|
describe('PersonalWallet/multisignature', () => {
|
|
23
|
-
let wallet:
|
|
23
|
+
let wallet: BaseWallet;
|
|
24
24
|
const assetName = '3030303030';
|
|
25
25
|
|
|
26
26
|
afterAll(() => {
|
|
@@ -100,14 +100,20 @@ describe('PersonalWallet/multisignature', () => {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
]),
|
|
103
|
-
|
|
103
|
+
signingOptions: {
|
|
104
|
+
extraSigners: [alicePolicySigner, bobPolicySigner]
|
|
105
|
+
},
|
|
106
|
+
witness: { scripts: [policyScript] }
|
|
104
107
|
};
|
|
105
108
|
|
|
106
109
|
const unsignedTx = await wallet.initializeTx(txProps);
|
|
107
110
|
|
|
108
111
|
const finalizeProps: FinalizeTxProps = {
|
|
112
|
+
signingOptions: {
|
|
113
|
+
extraSigners: [alicePolicySigner, bobPolicySigner]
|
|
114
|
+
},
|
|
109
115
|
tx: unsignedTx,
|
|
110
|
-
witness: {
|
|
116
|
+
witness: { scripts: [policyScript] }
|
|
111
117
|
};
|
|
112
118
|
|
|
113
119
|
const signedTx = await wallet.finalizeTx(finalizeProps);
|