@cardano-sdk/e2e 0.25.0 → 0.26.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 +1 -7
- package/CHANGELOG.md +13 -0
- package/README.md +0 -29
- package/dist/cjs/environment.d.ts.map +1 -1
- package/dist/cjs/environment.js.map +1 -1
- package/dist/cjs/factories.d.ts.map +1 -1
- package/dist/cjs/factories.js +7 -1
- package/dist/cjs/factories.js.map +1 -1
- package/dist/cjs/measurement-util.d.ts.map +1 -1
- package/dist/cjs/measurement-util.js.map +1 -1
- package/dist/cjs/scripts/is-local-network-ready.js.map +1 -1
- package/dist/cjs/scripts/mnemonic.js.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/files.d.ts.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/files.js.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts.map +1 -1
- package/dist/cjs/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js.map +1 -1
- 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.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/environment.d.ts.map +1 -1
- package/dist/esm/environment.js.map +1 -1
- package/dist/esm/factories.d.ts.map +1 -1
- package/dist/esm/factories.js +7 -1
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/measurement-util.d.ts.map +1 -1
- package/dist/esm/measurement-util.js.map +1 -1
- package/dist/esm/scripts/is-local-network-ready.js.map +1 -1
- package/dist/esm/scripts/mnemonic.js.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/files.d.ts.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/files.js.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.d.ts.map +1 -1
- package/dist/esm/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.js.map +1 -1
- 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.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/docker-compose.yml +4 -0
- package/jest.config.js +0 -1
- package/local-network/scripts/common.sh +19 -0
- package/local-network/scripts/make-babbage.sh +2 -1
- package/local-network/scripts/mint-handles.sh +2 -18
- package/local-network/scripts/mint-tokens.sh +2 -18
- package/local-network/scripts/mnemonic_keys.sh +0 -0
- package/local-network/scripts/setup-wallets.sh +2 -17
- package/local-network/templates/babbage/submit-api-config.json +115 -0
- package/package.json +27 -29
- package/src/environment.ts +2 -6
- package/src/factories.ts +11 -5
- package/src/measurement-util.ts +1 -4
- package/src/scripts/is-local-network-ready.ts +1 -3
- package/src/scripts/mnemonic.ts +1 -3
- package/src/tools/multi-delegation-data-gen/utils/files.ts +1 -3
- package/src/tools/multi-delegation-data-gen/utils/terminal-progress-monitor.ts +2 -6
- package/src/tools/multi-delegation-data-gen/utils/utils.ts +1 -3
- package/test/artillery/StakePoolSearch.ts +5 -16
- package/test/artillery/artillery.ts +20 -61
- package/test/artillery/wallet-restoration/WalletRestoration.ts +1 -3
- package/test/artillery/wallet-restoration/queries.ts +1 -3
- package/test/artillery/wallet-restoration/types.ts +1 -3
- package/test/load-test-custom/stake-pool-search/stake-pool-search.test.ts +1 -3
- package/test/load-test-custom/wallet-init/wallet-init.test.ts +10 -1
- package/test/load-test-custom/wallet-restoration/wallet-restoration.test.ts +1 -4
- package/test/local-network/register-pool.test.ts +24 -14
- package/test/long-running/cache-invalidation.test.ts +7 -4
- package/test/long-running/multisig-wallet/MultiSigTx.ts +117 -0
- package/test/long-running/multisig-wallet/MultiSigWallet.ts +491 -0
- package/test/long-running/multisig-wallet/multisig-delegation-rewards.test.ts +318 -0
- package/test/projection/offline-fork.test.ts +6 -6
- package/test/projection/single-tenant-utxo.test.ts +1 -1
- package/test/providers/StakePoolProvider.test.ts +22 -17
- package/test/wallet/PersonalWallet/delegation.test.ts +6 -3
- package/test/wallet/PersonalWallet/handle.test.ts +2 -1
- package/test/wallet/PersonalWallet/mint.test.ts +2 -1
- package/test/wallet/PersonalWallet/multiAddress.test.ts +2 -1
- package/test/wallet/PersonalWallet/multisignature.test.ts +4 -2
- package/test/wallet/PersonalWallet/nft.test.ts +2 -1
- package/test/web-extension/extension/ui.ts +2 -8
- package/test/load-testing/tx-submit-load.test.ts +0 -341
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { Agent, IncomingMessage } from 'http';
|
|
2
2
|
import { Agent as HttpsAgent } from 'https';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Artillery context
|
|
6
|
-
*/
|
|
4
|
+
/** Artillery context */
|
|
7
5
|
export interface ArtilleryContext<T> {
|
|
8
|
-
/**
|
|
9
|
-
* The unique Id of the virtual user
|
|
10
|
-
*/
|
|
6
|
+
/** The unique Id of the virtual user */
|
|
11
7
|
_uid: string;
|
|
12
8
|
|
|
13
|
-
/**
|
|
14
|
-
* The variables of the virtual user session
|
|
15
|
-
*/
|
|
9
|
+
/** The variables of the virtual user session */
|
|
16
10
|
vars: T;
|
|
17
11
|
}
|
|
18
12
|
|
|
@@ -32,89 +26,54 @@ interface ArtilleryEventEmitter extends EventEmitter {
|
|
|
32
26
|
removeListener<Event extends keyof ArtilleryEvents>(event: Event, listener: ArtilleryEvents[Event]): this;
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
/**
|
|
36
|
-
* Parameters of an Artillery request
|
|
37
|
-
*/
|
|
29
|
+
/** Parameters of an Artillery request */
|
|
38
30
|
export interface Params {
|
|
39
|
-
/**
|
|
40
|
-
* Name of the afterResponse hook
|
|
41
|
-
*/
|
|
31
|
+
/** Name of the afterResponse hook */
|
|
42
32
|
afterResponse?: string;
|
|
43
33
|
|
|
44
|
-
/**
|
|
45
|
-
* The agent used to for the request
|
|
46
|
-
*/
|
|
34
|
+
/** The agent used to for the request */
|
|
47
35
|
agent?: { http: Agent; https: HttpsAgent };
|
|
48
36
|
|
|
49
|
-
/**
|
|
50
|
-
* Name of the beforeRequest hook
|
|
51
|
-
*/
|
|
37
|
+
/** Name of the beforeRequest hook */
|
|
52
38
|
beforeRequest?: string;
|
|
53
39
|
|
|
54
|
-
/**
|
|
55
|
-
* The variables to capture from the response
|
|
56
|
-
*/
|
|
40
|
+
/** The variables to capture from the response */
|
|
57
41
|
capture: { as: string; json: string }[];
|
|
58
42
|
|
|
59
|
-
/**
|
|
60
|
-
* Unknown
|
|
61
|
-
*/
|
|
43
|
+
/** Unknown */
|
|
62
44
|
decompress?: boolean;
|
|
63
45
|
|
|
64
|
-
/**
|
|
65
|
-
* Not yet tested in IOG
|
|
66
|
-
*/
|
|
46
|
+
/** Not yet tested in IOG */
|
|
67
47
|
followRedirect?: boolean;
|
|
68
48
|
|
|
69
|
-
/**
|
|
70
|
-
* Not yet tested in IOG
|
|
71
|
-
*/
|
|
49
|
+
/** Not yet tested in IOG */
|
|
72
50
|
followAllRedirects?: boolean;
|
|
73
51
|
|
|
74
|
-
/**
|
|
75
|
-
* The HTTP headers of the request
|
|
76
|
-
*/
|
|
52
|
+
/** The HTTP headers of the request */
|
|
77
53
|
headers?: Record<string, string>;
|
|
78
54
|
|
|
79
|
-
/**
|
|
80
|
-
* Unknown
|
|
81
|
-
*/
|
|
55
|
+
/** Unknown */
|
|
82
56
|
https?: unknown;
|
|
83
57
|
|
|
84
|
-
/**
|
|
85
|
-
* The json body for POST. Its value is the raw configured one in beforeRequest
|
|
86
|
-
* and the evaluated one in afterResponse
|
|
87
|
-
*/
|
|
58
|
+
/** The json body for POST. Its value is the raw configured one in beforeRequest and the evaluated one in afterResponse */
|
|
88
59
|
json?: unknown;
|
|
89
60
|
|
|
90
|
-
/**
|
|
91
|
-
* Unknown
|
|
92
|
-
*/
|
|
61
|
+
/** Unknown */
|
|
93
62
|
match?: unknown[];
|
|
94
63
|
|
|
95
|
-
/**
|
|
96
|
-
* The HTTP method of the request
|
|
97
|
-
*/
|
|
64
|
+
/** The HTTP method of the request */
|
|
98
65
|
method: 'DELETE' | 'GET' | 'POST' | 'PUT';
|
|
99
66
|
|
|
100
|
-
/**
|
|
101
|
-
* Unknown
|
|
102
|
-
*/
|
|
67
|
+
/** Unknown */
|
|
103
68
|
retry: number;
|
|
104
69
|
|
|
105
|
-
/**
|
|
106
|
-
* Unknown
|
|
107
|
-
*/
|
|
70
|
+
/** Unknown */
|
|
108
71
|
throwHttpErrors?: boolean;
|
|
109
72
|
|
|
110
|
-
/**
|
|
111
|
-
* The time out of the request in ms
|
|
112
|
-
*/
|
|
73
|
+
/** The time out of the request in ms */
|
|
113
74
|
timeout: number;
|
|
114
75
|
|
|
115
|
-
/**
|
|
116
|
-
* URL of the request
|
|
117
|
-
*/
|
|
76
|
+
/** URL of the request */
|
|
118
77
|
url: string;
|
|
119
78
|
}
|
|
120
79
|
|
|
@@ -79,9 +79,7 @@ export const getAddresses: FunctionHook<WalletVars> = async ({ vars }, _, done)
|
|
|
79
79
|
done();
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
/**
|
|
83
|
-
* The current index of found addresses list
|
|
84
|
-
*/
|
|
82
|
+
/** The current index of found addresses list */
|
|
85
83
|
let index = 0;
|
|
86
84
|
|
|
87
85
|
export const walletRestoration: FunctionHook<WalletVars> = async ({ vars, _uid }, ee, done) => {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query distinct addresses from db associated with users who are staking.
|
|
3
|
-
*/
|
|
1
|
+
/** Query distinct addresses from db associated with users who are staking. */
|
|
4
2
|
export const findAddressesWithRegisteredStakeKey = `
|
|
5
3
|
SELECT COUNT(*) AS tx_count, address, sa.view as stake_address
|
|
6
4
|
FROM tx_out
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { GroupedAddress } from '@cardano-sdk/key-management';
|
|
2
2
|
import { PersonalWallet } from '@cardano-sdk/wallet';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* The context variables shared between all the hooks.
|
|
6
|
-
*/
|
|
4
|
+
/** The context variables shared between all the hooks. */
|
|
7
5
|
export interface WalletVars {
|
|
8
6
|
walletLoads: number;
|
|
9
7
|
addresses: GroupedAddress[];
|
|
@@ -39,9 +39,7 @@ enum MeasureTarget {
|
|
|
39
39
|
|
|
40
40
|
const PAGE_SIZE = 20;
|
|
41
41
|
|
|
42
|
-
/**
|
|
43
|
-
* The set of pools id found while getting results
|
|
44
|
-
*/
|
|
42
|
+
/** The set of pools id found while getting results */
|
|
45
43
|
const poolIds: Cardano.PoolId[] = [];
|
|
46
44
|
|
|
47
45
|
const measurement = new MeasurementUtil<MeasureTarget | string>();
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
waitForWalletStateSettle,
|
|
27
27
|
walletVariables
|
|
28
28
|
} from '../../../src';
|
|
29
|
+
import { util } from '@cardano-sdk/key-management';
|
|
29
30
|
|
|
30
31
|
// Example call that creates 5000 wallets in 10 minutes:
|
|
31
32
|
// VIRTUAL_USERS_GENERATE_DURATION=600 VIRTUAL_USERS_COUNT=5000 yarn load-test-custom:wallet-init
|
|
@@ -84,7 +85,15 @@ const createWallet = async (accountIndex: number): Promise<PersonalWallet> => {
|
|
|
84
85
|
measurementUtil.addMeasureMarker(MeasureTarget.keyAgent, accountIndex);
|
|
85
86
|
|
|
86
87
|
measurementUtil.addStartMarker(MeasureTarget.wallet, accountIndex);
|
|
87
|
-
const wallet = new PersonalWallet(
|
|
88
|
+
const wallet = new PersonalWallet(
|
|
89
|
+
{ name: `Wallet ${accountIndex}` },
|
|
90
|
+
{
|
|
91
|
+
...providers,
|
|
92
|
+
addressManager: util.createBip32Ed25519AddressManager(keyAgent),
|
|
93
|
+
logger,
|
|
94
|
+
witnesser: util.createBip32Ed25519Witnesser(keyAgent)
|
|
95
|
+
}
|
|
96
|
+
);
|
|
88
97
|
walletUtil.initialize(wallet);
|
|
89
98
|
return wallet;
|
|
90
99
|
};
|
|
@@ -11,10 +11,7 @@ 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
|
|
|
14
|
-
/**
|
|
15
|
-
* Env var MAX_USERS sets the maximum number of concurrent users to measure
|
|
16
|
-
* default value 100
|
|
17
|
-
*/
|
|
14
|
+
/** Env var MAX_USERS sets the maximum number of concurrent users to measure default value 100 */
|
|
18
15
|
const RESTORATION_TIMEOUT = process.env.RESTORATION_TIMEOUT
|
|
19
16
|
? Number.parseInt(process.env.RESTORATION_TIMEOUT)
|
|
20
17
|
: 5 * MINUTE;
|
|
@@ -3,6 +3,7 @@ import { Cardano } from '@cardano-sdk/core';
|
|
|
3
3
|
import {
|
|
4
4
|
KeyAgentFactoryProps,
|
|
5
5
|
TestWallet,
|
|
6
|
+
bip32Ed25519Factory,
|
|
6
7
|
getEnv,
|
|
7
8
|
getWallet,
|
|
8
9
|
submitCertificate,
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
} from '../../src';
|
|
13
14
|
import { logger } from '@cardano-sdk/util-dev';
|
|
14
15
|
|
|
16
|
+
import * as Crypto from '@cardano-sdk/crypto';
|
|
15
17
|
import { AddressType, KeyRole } from '@cardano-sdk/key-management';
|
|
16
18
|
import { firstValueFrom } from 'rxjs';
|
|
17
19
|
|
|
@@ -40,6 +42,7 @@ const wallet2Params: KeyAgentFactoryProps = {
|
|
|
40
42
|
describe('local-network/register-pool', () => {
|
|
41
43
|
let wallet1: TestWallet;
|
|
42
44
|
let wallet2: TestWallet;
|
|
45
|
+
let bip32Ed25519: Crypto.Bip32Ed25519;
|
|
43
46
|
|
|
44
47
|
beforeAll(async () => {
|
|
45
48
|
jest.setTimeout(180_000);
|
|
@@ -63,6 +66,7 @@ describe('local-network/register-pool', () => {
|
|
|
63
66
|
|
|
64
67
|
await waitForWalletStateSettle(wallet1.wallet);
|
|
65
68
|
await waitForWalletStateSettle(wallet2.wallet);
|
|
69
|
+
bip32Ed25519 = await bip32Ed25519Factory.create(env.KEY_MANAGEMENT_PARAMS.bip32Ed25519, null, logger);
|
|
66
70
|
});
|
|
67
71
|
|
|
68
72
|
afterAll(() => {
|
|
@@ -75,18 +79,17 @@ describe('local-network/register-pool', () => {
|
|
|
75
79
|
|
|
76
80
|
await walletReady(wallet);
|
|
77
81
|
|
|
78
|
-
const
|
|
82
|
+
const poolAddressManager = wallet.addressManager;
|
|
79
83
|
|
|
80
|
-
const poolPubKey = await
|
|
84
|
+
const poolPubKey = await poolAddressManager.derivePublicKey({
|
|
81
85
|
index: 0,
|
|
82
86
|
role: KeyRole.External
|
|
83
87
|
});
|
|
84
88
|
|
|
85
|
-
const bip32Ed25519 = await poolKeyAgent.getBip32Ed25519();
|
|
86
89
|
const poolKeyHash = await bip32Ed25519.getPubKeyHash(poolPubKey);
|
|
87
90
|
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
|
|
88
91
|
const poolRewardAccount = (
|
|
89
|
-
await
|
|
92
|
+
await poolAddressManager.deriveAddress(
|
|
90
93
|
{
|
|
91
94
|
index: 0,
|
|
92
95
|
type: AddressType.External
|
|
@@ -117,13 +120,17 @@ describe('local-network/register-pool', () => {
|
|
|
117
120
|
|
|
118
121
|
const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
|
|
119
122
|
const stakeKeyHash = Cardano.RewardAccount.toHash(rewardAccounts[0].address);
|
|
123
|
+
const stakeCredential = {
|
|
124
|
+
hash: stakeKeyHash as unknown as Crypto.Hash28ByteBase16,
|
|
125
|
+
type: Cardano.CredentialType.KeyHash
|
|
126
|
+
};
|
|
120
127
|
|
|
121
128
|
await submitCertificate(registrationCert, wallet1);
|
|
122
129
|
|
|
123
130
|
// Register stake key.
|
|
124
131
|
const registerStakeKey: Cardano.StakeAddressCertificate = {
|
|
125
|
-
__typename: Cardano.CertificateType.
|
|
126
|
-
|
|
132
|
+
__typename: Cardano.CertificateType.StakeRegistration,
|
|
133
|
+
stakeCredential
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
await submitCertificate(registerStakeKey, wallet1);
|
|
@@ -132,7 +139,7 @@ describe('local-network/register-pool', () => {
|
|
|
132
139
|
const delegationCert: Cardano.StakeDelegationCertificate = {
|
|
133
140
|
__typename: Cardano.CertificateType.StakeDelegation,
|
|
134
141
|
poolId,
|
|
135
|
-
|
|
142
|
+
stakeCredential
|
|
136
143
|
};
|
|
137
144
|
|
|
138
145
|
await submitCertificate(delegationCert, wallet1);
|
|
@@ -160,18 +167,17 @@ describe('local-network/register-pool', () => {
|
|
|
160
167
|
|
|
161
168
|
await walletReady(wallet);
|
|
162
169
|
|
|
163
|
-
const
|
|
170
|
+
const poolAddressManager = wallet.addressManager;
|
|
164
171
|
|
|
165
|
-
const poolPubKey = await
|
|
172
|
+
const poolPubKey = await poolAddressManager.derivePublicKey({
|
|
166
173
|
index: 0,
|
|
167
174
|
role: KeyRole.External
|
|
168
175
|
});
|
|
169
176
|
|
|
170
|
-
const bip32Ed25519 = await poolKeyAgent.getBip32Ed25519();
|
|
171
177
|
const poolKeyHash = await bip32Ed25519.getPubKeyHash(poolPubKey);
|
|
172
178
|
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
|
|
173
179
|
const poolRewardAccount = (
|
|
174
|
-
await
|
|
180
|
+
await poolAddressManager.deriveAddress(
|
|
175
181
|
{
|
|
176
182
|
index: 0,
|
|
177
183
|
type: AddressType.External
|
|
@@ -202,13 +208,17 @@ describe('local-network/register-pool', () => {
|
|
|
202
208
|
|
|
203
209
|
const rewardAccounts = await firstValueFrom(wallet.delegation.rewardAccounts$);
|
|
204
210
|
const stakeKeyHash = Cardano.RewardAccount.toHash(rewardAccounts[0].address);
|
|
211
|
+
const stakeCredential = {
|
|
212
|
+
hash: stakeKeyHash as unknown as Crypto.Hash28ByteBase16,
|
|
213
|
+
type: Cardano.CredentialType.KeyHash
|
|
214
|
+
};
|
|
205
215
|
|
|
206
216
|
await submitCertificate(registrationCert, wallet2);
|
|
207
217
|
|
|
208
218
|
// Register stake key.
|
|
209
219
|
const registerStakeKey: Cardano.StakeAddressCertificate = {
|
|
210
|
-
__typename: Cardano.CertificateType.
|
|
211
|
-
|
|
220
|
+
__typename: Cardano.CertificateType.StakeRegistration,
|
|
221
|
+
stakeCredential
|
|
212
222
|
};
|
|
213
223
|
|
|
214
224
|
await submitCertificate(registerStakeKey, wallet2);
|
|
@@ -217,7 +227,7 @@ describe('local-network/register-pool', () => {
|
|
|
217
227
|
const delegationCert: Cardano.StakeDelegationCertificate = {
|
|
218
228
|
__typename: Cardano.CertificateType.StakeDelegation,
|
|
219
229
|
poolId,
|
|
220
|
-
|
|
230
|
+
stakeCredential
|
|
221
231
|
};
|
|
222
232
|
|
|
223
233
|
await submitCertificate(delegationCert, wallet2);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import * as Crypto from '@cardano-sdk/crypto';
|
|
1
2
|
import { AddressType, KeyRole } from '@cardano-sdk/key-management';
|
|
2
3
|
import { Cardano } from '@cardano-sdk/core';
|
|
3
4
|
import {
|
|
4
5
|
KeyAgentFactoryProps,
|
|
5
6
|
TestWallet,
|
|
7
|
+
bip32Ed25519Factory,
|
|
6
8
|
getEnv,
|
|
7
9
|
getTxConfirmationEpoch,
|
|
8
10
|
getWallet,
|
|
@@ -23,6 +25,7 @@ const vrf = Cardano.VrfVkHex('2ee5a4c423224bb9c42107fc18a60556d6a83cec1d9dd37a71
|
|
|
23
25
|
describe('cache invalidation', () => {
|
|
24
26
|
let testProviderServer: Docker.Container;
|
|
25
27
|
let wallet1: TestWallet;
|
|
28
|
+
let bip32Ed25519: Crypto.Bip32Ed25519;
|
|
26
29
|
|
|
27
30
|
beforeAll(async () => {
|
|
28
31
|
const port = await getRandomPort();
|
|
@@ -90,6 +93,7 @@ describe('cache invalidation', () => {
|
|
|
90
93
|
});
|
|
91
94
|
|
|
92
95
|
await waitForWalletStateSettle(wallet1.wallet);
|
|
96
|
+
bip32Ed25519 = await bip32Ed25519Factory.create(env.KEY_MANAGEMENT_PARAMS.bip32Ed25519, null, logger);
|
|
93
97
|
});
|
|
94
98
|
|
|
95
99
|
afterAll(async () => {
|
|
@@ -103,18 +107,17 @@ describe('cache invalidation', () => {
|
|
|
103
107
|
|
|
104
108
|
await walletReady(wallet);
|
|
105
109
|
|
|
106
|
-
const
|
|
110
|
+
const poolAddressManager = wallet.addressManager;
|
|
107
111
|
|
|
108
|
-
const poolPubKey = await
|
|
112
|
+
const poolPubKey = await poolAddressManager.derivePublicKey({
|
|
109
113
|
index: 0,
|
|
110
114
|
role: KeyRole.External
|
|
111
115
|
});
|
|
112
116
|
|
|
113
|
-
const bip32Ed25519 = await poolKeyAgent.getBip32Ed25519();
|
|
114
117
|
const poolKeyHash = await bip32Ed25519.getPubKeyHash(poolPubKey);
|
|
115
118
|
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
|
|
116
119
|
const poolRewardAccount = (
|
|
117
|
-
await
|
|
120
|
+
await poolAddressManager.deriveAddress(
|
|
118
121
|
{
|
|
119
122
|
index: 0,
|
|
120
123
|
type: AddressType.External
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as Crypto from '@cardano-sdk/crypto';
|
|
2
|
+
import { Cardano, Serialization, deserializeTx } from '@cardano-sdk/core';
|
|
3
|
+
import { HexBlob } from '@cardano-sdk/util';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a multi-signature transaction for the Cardano blockchain.
|
|
7
|
+
* This transaction can be serialized and transfer between participants of the multisig wallet.
|
|
8
|
+
* The transaction carries a bit of extra context, such as the expected signers and the signatures
|
|
9
|
+
* of the signers who have already signed. this way the participants will know if the transaction is ready to be sent,
|
|
10
|
+
* or they need to relay the transaction to additional participants (and to whom) for additional signing.
|
|
11
|
+
*/
|
|
12
|
+
export class MultiSigTx {
|
|
13
|
+
#transaction: Cardano.Tx;
|
|
14
|
+
#expectedSigners: Array<Crypto.Ed25519PublicKeyHex> = [];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Initializes a new instance of the MultiSigTx class.
|
|
18
|
+
*
|
|
19
|
+
* @param {Cardano.Tx} transaction - The underlying Cardano transaction.
|
|
20
|
+
* @param {Array<Crypto.Ed25519PublicKeyHex>} expectedSigners - An array of expected signers' public keys.
|
|
21
|
+
*/
|
|
22
|
+
constructor(transaction: Cardano.Tx, expectedSigners: Array<Crypto.Ed25519PublicKeyHex>) {
|
|
23
|
+
this.#transaction = transaction;
|
|
24
|
+
this.#expectedSigners = expectedSigners;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Serializes the multi-signature transaction to a CBOR hex blob.
|
|
29
|
+
*
|
|
30
|
+
* @returns {HexBlob} The serialized transaction as a hex-encoded string.
|
|
31
|
+
*/
|
|
32
|
+
toCbor(): HexBlob {
|
|
33
|
+
const writer = new Serialization.CborWriter();
|
|
34
|
+
|
|
35
|
+
writer.writeStartArray(2);
|
|
36
|
+
writer.writeStartArray(this.#expectedSigners.length);
|
|
37
|
+
|
|
38
|
+
for (const signer of this.#expectedSigners) {
|
|
39
|
+
writer.writeByteString(Buffer.from(signer, 'hex'));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
writer.writeEncodedValue(Buffer.from(Serialization.Transaction.fromCore(this.#transaction).toCbor(), 'hex'));
|
|
43
|
+
return writer.encodeAsHex();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Deserializes a CBOR hex blob into a MultiSigTx instance.
|
|
48
|
+
*
|
|
49
|
+
* @param {HexBlob} cbor - The CBOR hex blob representing the transaction.
|
|
50
|
+
* @returns {MultiSigTx} The deserialized MultiSigTx instance.
|
|
51
|
+
*/
|
|
52
|
+
static fromCbor(cbor: HexBlob): MultiSigTx {
|
|
53
|
+
const reader = new Serialization.CborReader(cbor);
|
|
54
|
+
|
|
55
|
+
reader.readStartArray();
|
|
56
|
+
const length = reader.readStartArray();
|
|
57
|
+
const expectedSigners: Array<Crypto.Ed25519PublicKeyHex> = [];
|
|
58
|
+
|
|
59
|
+
if (length === null || length <= 0) throw new Error('Expected at least one signer');
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < length; i++)
|
|
62
|
+
expectedSigners.push(Crypto.Ed25519PublicKeyHex(Buffer.from(reader.readByteString()).toString('hex')));
|
|
63
|
+
|
|
64
|
+
reader.readEndArray();
|
|
65
|
+
|
|
66
|
+
const transaction = deserializeTx(reader.readEncodedValue());
|
|
67
|
+
reader.readEndArray();
|
|
68
|
+
|
|
69
|
+
return new MultiSigTx(transaction, expectedSigners);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Checks whether the transaction has been fully signed.
|
|
74
|
+
*
|
|
75
|
+
* @returns {boolean} True if the transaction is fully signed, otherwise false.
|
|
76
|
+
*/
|
|
77
|
+
isFullySigned(): boolean {
|
|
78
|
+
return this.#expectedSigners.every((signer) => this.#transaction.witness.signatures.has(signer));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Retrieves the original Cardano transaction.
|
|
83
|
+
*
|
|
84
|
+
* @returns {Cardano.Tx} The Cardano transaction.
|
|
85
|
+
*/
|
|
86
|
+
getTransaction(): Cardano.Tx {
|
|
87
|
+
return this.#transaction;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Identifies and returns the public keys of signers who have not yet signed the transaction.
|
|
92
|
+
*
|
|
93
|
+
* @returns {Array<Crypto.Ed25519PublicKeyHex>} An array of public keys of the missing signers.
|
|
94
|
+
*/
|
|
95
|
+
getMissingSigners(): Array<Crypto.Ed25519PublicKeyHex> {
|
|
96
|
+
const missingSigners: Array<Crypto.Ed25519PublicKeyHex> = [];
|
|
97
|
+
|
|
98
|
+
for (const signer of this.#expectedSigners)
|
|
99
|
+
if (!this.#transaction.witness.signatures.has(signer)) missingSigners.push(signer);
|
|
100
|
+
|
|
101
|
+
return missingSigners;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Identifies and returns the public keys of signers who have signed the transaction.
|
|
106
|
+
*
|
|
107
|
+
* @returns {Array<Crypto.Ed25519PublicKeyHex>} An array of public keys of the signers who have already signed.
|
|
108
|
+
*/
|
|
109
|
+
getAccountedForSigners(): Array<Crypto.Ed25519PublicKeyHex> {
|
|
110
|
+
const accountedSigners: Array<Crypto.Ed25519PublicKeyHex> = [];
|
|
111
|
+
|
|
112
|
+
for (const signer of this.#expectedSigners)
|
|
113
|
+
if (this.#transaction.witness.signatures.has(signer)) accountedSigners.push(signer);
|
|
114
|
+
|
|
115
|
+
return accountedSigners;
|
|
116
|
+
}
|
|
117
|
+
}
|