@arcium-hq/client 0.10.4 → 0.11.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/README.md +1 -2
- package/build/index.cjs +1493 -279
- package/build/index.mjs +1492 -282
- package/build/types/constants.d.ts +55 -0
- package/build/types/constants.d.ts.map +1 -1
- package/build/types/idl/arcium.d.ts +1338 -209
- package/build/types/idl/arcium.d.ts.map +1 -1
- package/build/types/idl/arcium_staking.d.ts +4583 -2032
- package/build/types/idl/arcium_staking.d.ts.map +1 -1
- package/build/types/idlAccounts.d.ts +14 -0
- package/build/types/idlAccounts.d.ts.map +1 -0
- package/build/types/onchain.d.ts +17 -4
- package/build/types/onchain.d.ts.map +1 -1
- package/build/types/pda.d.ts +29 -1
- package/build/types/pda.d.ts.map +1 -1
- package/build/types/rawCircuit.d.ts +5 -0
- package/build/types/rawCircuit.d.ts.map +1 -0
- package/build/types/recoveryPeers.d.ts +8 -0
- package/build/types/recoveryPeers.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/constants.ts +55 -0
- package/src/idl/arcium.json +1340 -211
- package/src/idl/arcium.ts +1340 -211
- package/src/idl/arcium_staking.json +4411 -1820
- package/src/idl/arcium_staking.ts +4375 -1824
- package/src/idlAccounts.ts +79 -0
- package/src/onchain.ts +62 -177
- package/src/pda.ts +103 -64
- package/src/rawCircuit.ts +41 -0
- package/src/recoveryPeers.ts +46 -0
package/src/pda.ts
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { PublicKey, AddressLookupTableProgram } from '@solana/web3.js';
|
|
2
2
|
import * as anchor from '@anchor-lang/core';
|
|
3
3
|
import {
|
|
4
|
+
ARCIUM_SIGNER_ACC_SEED,
|
|
4
5
|
ARX_NODE_ACC_SEED,
|
|
5
6
|
CLOCK_ACC_SEED,
|
|
6
7
|
CLUSTER_ACC_SEED,
|
|
7
8
|
COMP_DEF_ACC_SEED,
|
|
8
9
|
COMPUTATION_ACC_SEED,
|
|
9
10
|
EXEC_POOL_ACC_SEED,
|
|
11
|
+
FAILURE_CLAIM_ACC_SEED,
|
|
10
12
|
MEMPOOL_ACC_SEED,
|
|
11
13
|
MXE_ACCOUNT_SEED,
|
|
12
14
|
MXE_RECOVERY_ACC_SEED,
|
|
15
|
+
OPERATOR_ACC_SEED,
|
|
13
16
|
OFFSET_BUFFER_SIZE,
|
|
14
17
|
POOL_ACC_SEED,
|
|
15
18
|
RAW_CIRCUIT_ACC_SEED,
|
|
16
19
|
RECOVERY_CLUSTER_ACC_SEED,
|
|
20
|
+
RECOVERY_PEER_ACC_SEED,
|
|
17
21
|
} from './constants.js';
|
|
18
22
|
import { ARCIUM_ADDR } from './idl/index.js';
|
|
19
23
|
|
|
24
|
+
const U64_SEED_SIZE = 8;
|
|
25
|
+
const MAX_U8 = 0xff;
|
|
26
|
+
const MAX_U32 = 0xffffffff;
|
|
27
|
+
|
|
20
28
|
/**
|
|
21
29
|
* Return the public key of the deployed Arcium program on Solana.
|
|
22
30
|
* @returns Arcium program's public key.
|
|
@@ -32,11 +40,7 @@ export function getArciumProgramId(): PublicKey {
|
|
|
32
40
|
* @returns Derived computation account public key.
|
|
33
41
|
*/
|
|
34
42
|
export function getComputationAccAddress(clusterOffset: number, computationOffset: anchor.BN): PublicKey {
|
|
35
|
-
|
|
36
|
-
clOffsetBuffer.writeUInt32LE(clusterOffset, 0);
|
|
37
|
-
|
|
38
|
-
const seeds = [Buffer.from(COMPUTATION_ACC_SEED), clOffsetBuffer, computationOffset.toArrayLike(Buffer, 'le', 8)];
|
|
39
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
43
|
+
return findArciumPda([stringSeed(COMPUTATION_ACC_SEED), u32Seed(clusterOffset), u64Seed(computationOffset)]);
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
/**
|
|
@@ -45,11 +49,7 @@ export function getComputationAccAddress(clusterOffset: number, computationOffse
|
|
|
45
49
|
* @returns Derived mempool account public key.
|
|
46
50
|
*/
|
|
47
51
|
export function getMempoolAccAddress(clusterOffset: number): PublicKey {
|
|
48
|
-
|
|
49
|
-
clOffsetBuffer.writeUInt32LE(clusterOffset, 0);
|
|
50
|
-
|
|
51
|
-
const seeds = [Buffer.from(MEMPOOL_ACC_SEED), clOffsetBuffer];
|
|
52
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
52
|
+
return findArciumPda([stringSeed(MEMPOOL_ACC_SEED), u32Seed(clusterOffset)]);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -58,12 +58,7 @@ export function getMempoolAccAddress(clusterOffset: number): PublicKey {
|
|
|
58
58
|
* @returns Derived executing pool account public key.
|
|
59
59
|
*/
|
|
60
60
|
export function getExecutingPoolAccAddress(clusterOffset: number): PublicKey {
|
|
61
|
-
|
|
62
|
-
clOffsetBuffer.writeUInt32LE(clusterOffset, 0);
|
|
63
|
-
|
|
64
|
-
const seeds = [Buffer.from(EXEC_POOL_ACC_SEED), clOffsetBuffer];
|
|
65
|
-
|
|
66
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
61
|
+
return findArciumPda([stringSeed(EXEC_POOL_ACC_SEED), u32Seed(clusterOffset)]);
|
|
67
62
|
}
|
|
68
63
|
|
|
69
64
|
/**
|
|
@@ -71,9 +66,7 @@ export function getExecutingPoolAccAddress(clusterOffset: number): PublicKey {
|
|
|
71
66
|
* @returns Derived fee pool account public key.
|
|
72
67
|
*/
|
|
73
68
|
export function getFeePoolAccAddress(): PublicKey {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
69
|
+
return findArciumPda([stringSeed(POOL_ACC_SEED)]);
|
|
77
70
|
}
|
|
78
71
|
|
|
79
72
|
/**
|
|
@@ -81,9 +74,7 @@ export function getFeePoolAccAddress(): PublicKey {
|
|
|
81
74
|
* @returns Derived clock account public key.
|
|
82
75
|
*/
|
|
83
76
|
export function getClockAccAddress(): PublicKey {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
77
|
+
return findArciumPda([stringSeed(CLOCK_ACC_SEED)]);
|
|
87
78
|
}
|
|
88
79
|
|
|
89
80
|
/**
|
|
@@ -92,11 +83,7 @@ export function getClockAccAddress(): PublicKey {
|
|
|
92
83
|
* @returns Derived cluster account public key.
|
|
93
84
|
*/
|
|
94
85
|
export function getClusterAccAddress(clusterOffset: number): PublicKey {
|
|
95
|
-
|
|
96
|
-
offsetBuffer.writeUInt32LE(clusterOffset, 0);
|
|
97
|
-
const seeds = [Buffer.from(CLUSTER_ACC_SEED), offsetBuffer];
|
|
98
|
-
|
|
99
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
86
|
+
return findArciumPda([stringSeed(CLUSTER_ACC_SEED), u32Seed(clusterOffset)]);
|
|
100
87
|
}
|
|
101
88
|
|
|
102
89
|
/**
|
|
@@ -105,11 +92,7 @@ export function getClusterAccAddress(clusterOffset: number): PublicKey {
|
|
|
105
92
|
* @returns Derived ArxNode account public key.
|
|
106
93
|
*/
|
|
107
94
|
export function getArxNodeAccAddress(nodeOffset: number): PublicKey {
|
|
108
|
-
|
|
109
|
-
offsetBuffer.writeUInt32LE(nodeOffset, 0);
|
|
110
|
-
const seeds = [Buffer.from(ARX_NODE_ACC_SEED), offsetBuffer];
|
|
111
|
-
|
|
112
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
95
|
+
return findArciumPda([stringSeed(ARX_NODE_ACC_SEED), u32Seed(nodeOffset)]);
|
|
113
96
|
}
|
|
114
97
|
|
|
115
98
|
/**
|
|
@@ -118,9 +101,7 @@ export function getArxNodeAccAddress(nodeOffset: number): PublicKey {
|
|
|
118
101
|
* @returns Derived MXE account public key.
|
|
119
102
|
*/
|
|
120
103
|
export function getMXEAccAddress(mxeProgramId: PublicKey): PublicKey {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
104
|
+
return findArciumPda([stringSeed(MXE_ACCOUNT_SEED), pubkeySeed(mxeProgramId)]);
|
|
124
105
|
}
|
|
125
106
|
|
|
126
107
|
/**
|
|
@@ -130,11 +111,7 @@ export function getMXEAccAddress(mxeProgramId: PublicKey): PublicKey {
|
|
|
130
111
|
* @returns Derived computation definition account public key.
|
|
131
112
|
*/
|
|
132
113
|
export function getCompDefAccAddress(mxeProgramId: PublicKey, compDefOffset: number): PublicKey {
|
|
133
|
-
|
|
134
|
-
offsetBuffer.writeUInt32LE(compDefOffset, 0);
|
|
135
|
-
const seeds = [Buffer.from(COMP_DEF_ACC_SEED), mxeProgramId.toBuffer(), offsetBuffer];
|
|
136
|
-
|
|
137
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
114
|
+
return findArciumPda([stringSeed(COMP_DEF_ACC_SEED), pubkeySeed(mxeProgramId), u32Seed(compDefOffset)]);
|
|
138
115
|
}
|
|
139
116
|
|
|
140
117
|
/**
|
|
@@ -143,8 +120,7 @@ export function getCompDefAccAddress(mxeProgramId: PublicKey, compDefOffset: num
|
|
|
143
120
|
* @returns Derived recovery cluster account public key.
|
|
144
121
|
*/
|
|
145
122
|
export function getRecoveryClusterAccAddress(mxeProgramId: PublicKey): PublicKey {
|
|
146
|
-
|
|
147
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
123
|
+
return findArciumPda([stringSeed(RECOVERY_CLUSTER_ACC_SEED), pubkeySeed(mxeProgramId)]);
|
|
148
124
|
}
|
|
149
125
|
|
|
150
126
|
/**
|
|
@@ -153,23 +129,57 @@ export function getRecoveryClusterAccAddress(mxeProgramId: PublicKey): PublicKey
|
|
|
153
129
|
* @returns Derived MXE recovery account public key.
|
|
154
130
|
*/
|
|
155
131
|
export function getMxeRecoveryAccAddress(originalMxeProgramId: PublicKey): PublicKey {
|
|
156
|
-
|
|
157
|
-
|
|
132
|
+
return findArciumPda([stringSeed(MXE_RECOVERY_ACC_SEED), pubkeySeed(originalMxeProgramId)]);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Derive the recovery peer account address for a given recovery peer offset.
|
|
137
|
+
* @param peerOffset - Recovery peer offset as a u32 in `[0, 2^32 - 1]`.
|
|
138
|
+
* @returns Derived recovery peer account public key.
|
|
139
|
+
*/
|
|
140
|
+
export function getRecoveryPeerAccAddress(peerOffset: number): PublicKey {
|
|
141
|
+
return findArciumPda([stringSeed(RECOVERY_PEER_ACC_SEED), u32Seed(peerOffset)]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Derive the operator account address for a given operator signer.
|
|
146
|
+
* @param operatorSigner - Public key of the operator signer.
|
|
147
|
+
* @returns Derived operator account public key.
|
|
148
|
+
*/
|
|
149
|
+
export function getOperatorAccAddress(operatorSigner: PublicKey): PublicKey {
|
|
150
|
+
return findArciumPda([stringSeed(OPERATOR_ACC_SEED), pubkeySeed(operatorSigner)]);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Derive the failure claim account address for a given MXE program and computation offset.
|
|
155
|
+
* @param mxeProgramId - Public key of the MXE program.
|
|
156
|
+
* @param computationOffset - Computation offset as an anchor.BN in `[0, 2^64 - 1]`.
|
|
157
|
+
* @returns Derived failure claim account public key.
|
|
158
|
+
*/
|
|
159
|
+
export function getFailureClaimAccAddress(mxeProgramId: PublicKey, computationOffset: anchor.BN): PublicKey {
|
|
160
|
+
return findArciumPda([stringSeed(FAILURE_CLAIM_ACC_SEED), pubkeySeed(mxeProgramId), u64Seed(computationOffset)]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Derive the Arcium signer account address used by an MXE program when invoking the Arcium
|
|
165
|
+
* program. Unlike most other helpers in this module, this PDA is derived under the MXE
|
|
166
|
+
* program ID (the caller), not the Arcium program ID - Arcium verifies the seed via
|
|
167
|
+
* `seeds::program = _mxe_program`.
|
|
168
|
+
* @param mxeProgramId - Public key of the MXE program that owns the signer PDA.
|
|
169
|
+
* @returns Derived Arcium signer account public key.
|
|
170
|
+
*/
|
|
171
|
+
export function getArciumSignerAccAddress(mxeProgramId: PublicKey): PublicKey {
|
|
172
|
+
return findPda(mxeProgramId, [stringSeed(ARCIUM_SIGNER_ACC_SEED)]);
|
|
158
173
|
}
|
|
159
174
|
|
|
160
175
|
/**
|
|
161
176
|
* Derive the raw circuit account address for a given computation definition and index.
|
|
162
177
|
* @param compDefPubkey - Public key of the computation definition account.
|
|
163
|
-
* @param rawCircuitIndex - Index of the raw circuit account
|
|
178
|
+
* @param rawCircuitIndex - Index of the raw circuit account as a u8 in `[0, 255]`.
|
|
164
179
|
* @returns Derived raw circuit account public key.
|
|
165
180
|
*/
|
|
166
181
|
export function getRawCircuitAccAddress(compDefPubkey: PublicKey, rawCircuitIndex: number): PublicKey {
|
|
167
|
-
|
|
168
|
-
Buffer.from(RAW_CIRCUIT_ACC_SEED),
|
|
169
|
-
compDefPubkey.toBuffer(),
|
|
170
|
-
Buffer.from([rawCircuitIndex]),
|
|
171
|
-
];
|
|
172
|
-
return generateArciumPDAFrom(seeds)[0];
|
|
182
|
+
return findArciumPda([stringSeed(RAW_CIRCUIT_ACC_SEED), pubkeySeed(compDefPubkey), u8Seed(rawCircuitIndex)]);
|
|
173
183
|
}
|
|
174
184
|
|
|
175
185
|
/**
|
|
@@ -180,19 +190,48 @@ export function getRawCircuitAccAddress(compDefPubkey: PublicKey, rawCircuitInde
|
|
|
180
190
|
*/
|
|
181
191
|
export function getLookupTableAddress(mxeProgramId: PublicKey, lutOffset: anchor.BN): PublicKey {
|
|
182
192
|
const mxeAccount = getMXEAccAddress(mxeProgramId);
|
|
183
|
-
|
|
184
|
-
const seeds = [mxeAccount.toBuffer(), lutIndexBuffer];
|
|
185
|
-
return PublicKey.findProgramAddressSync(seeds, AddressLookupTableProgram.programId)[0];
|
|
193
|
+
return findPda(AddressLookupTableProgram.programId, [pubkeySeed(mxeAccount), u64Seed(lutOffset)]);
|
|
186
194
|
}
|
|
187
195
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
function stringSeed(value: string): Buffer {
|
|
197
|
+
return Buffer.from(value);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function u8Seed(value: number): Buffer {
|
|
201
|
+
assertIntegerInRange(value, 0, MAX_U8, 'u8 seed');
|
|
202
|
+
return Buffer.from([value]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function u32Seed(value: number): Buffer {
|
|
206
|
+
assertIntegerInRange(value, 0, MAX_U32, 'u32 seed');
|
|
207
|
+
const buffer = Buffer.alloc(OFFSET_BUFFER_SIZE);
|
|
208
|
+
buffer.writeUInt32LE(value, 0);
|
|
209
|
+
return buffer;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function u64Seed(value: anchor.BN): Buffer {
|
|
213
|
+
if (value.isNeg() || value.byteLength() > U64_SEED_SIZE) {
|
|
214
|
+
throw new RangeError(
|
|
215
|
+
`u64 seed must be between 0 and 18446744073709551615 (got ${value.toString()})`,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
return value.toArrayLike(Buffer, 'le', U64_SEED_SIZE);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function pubkeySeed(value: PublicKey): Buffer {
|
|
222
|
+
return value.toBuffer();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function findArciumPda(seeds: Buffer[]): PublicKey {
|
|
226
|
+
return findPda(getArciumProgramId(), seeds);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function findPda(programId: PublicKey, seeds: Buffer[]): PublicKey {
|
|
230
|
+
return PublicKey.findProgramAddressSync(seeds, programId)[0];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function assertIntegerInRange(value: number, min: number, max: number, label: string): void {
|
|
234
|
+
if (!Number.isInteger(value) || value < min || value > max) {
|
|
235
|
+
throw new RangeError(`${label} must be an integer between ${min} and ${max} (got ${value})`);
|
|
236
|
+
}
|
|
198
237
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_RAW_CIRCUIT_ACCOUNTS,
|
|
3
|
+
MAX_RAW_CIRCUIT_BYTES_PER_ACC,
|
|
4
|
+
} from './constants.js';
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
export function getRawCircuitAccountCount(rawCircuitByteLength: number): number {
|
|
8
|
+
if (!Number.isInteger(rawCircuitByteLength) || rawCircuitByteLength < 0) {
|
|
9
|
+
throw new RangeError(`rawCircuit byte length must be a non-negative integer (got ${rawCircuitByteLength})`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const accountCount = Math.ceil(rawCircuitByteLength / MAX_RAW_CIRCUIT_BYTES_PER_ACC);
|
|
13
|
+
if (accountCount > MAX_RAW_CIRCUIT_ACCOUNTS) {
|
|
14
|
+
throw new RangeError(
|
|
15
|
+
`Raw circuit is too large for on-chain upload: requires ${accountCount} raw circuit accounts, maximum is ${MAX_RAW_CIRCUIT_ACCOUNTS}`,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return accountCount;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @internal */
|
|
23
|
+
export function assertRawCircuitUploadLength(
|
|
24
|
+
rawCircuitByteLength: number,
|
|
25
|
+
declaredCircuitByteLength: number,
|
|
26
|
+
circuitName: string,
|
|
27
|
+
): void {
|
|
28
|
+
if (!Number.isInteger(rawCircuitByteLength) || rawCircuitByteLength < 0) {
|
|
29
|
+
throw new RangeError(`rawCircuit byte length must be a non-negative integer (got ${rawCircuitByteLength})`);
|
|
30
|
+
}
|
|
31
|
+
if (!Number.isInteger(declaredCircuitByteLength) || declaredCircuitByteLength <= 0) {
|
|
32
|
+
throw new RangeError(
|
|
33
|
+
`Declared circuit byte length for ${circuitName} must be a positive integer (got ${declaredCircuitByteLength})`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (rawCircuitByteLength !== declaredCircuitByteLength) {
|
|
37
|
+
throw new RangeError(
|
|
38
|
+
`Raw circuit byte length for ${circuitName} must match the computation definition: got ${rawCircuitByteLength}, expected ${declaredCircuitByteLength}`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MAX_RECOVERY_PEERS, MIN_RECOVERY_PEERS } from './constants.js';
|
|
2
|
+
|
|
3
|
+
const MAX_U32 = 0xffffffff;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Mirrors the on-chain `init_mxe_part2` recovery-peer bounds before building the instruction.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function assertValidRecoveryPeers(recoveryPeers: readonly number[]): void {
|
|
10
|
+
if (recoveryPeers.length > MAX_RECOVERY_PEERS) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`recoveryPeers must have at most ${MAX_RECOVERY_PEERS} elements (got ${recoveryPeers.length})`,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let nonZeroPeers = 0;
|
|
17
|
+
for (let index = 0; index < recoveryPeers.length; index += 1) {
|
|
18
|
+
const peer = recoveryPeers[index];
|
|
19
|
+
if (!Number.isInteger(peer) || peer < 0 || peer > MAX_U32) {
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
`recoveryPeers[${index}] must be an integer in [0, ${MAX_U32}] (got ${peer})`,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
if (peer !== 0) {
|
|
25
|
+
nonZeroPeers += 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (nonZeroPeers > 0 && nonZeroPeers < MIN_RECOVERY_PEERS) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`recoveryPeers must have 0 or at least ${MIN_RECOVERY_PEERS} non-zero offsets (found ${nonZeroPeers})`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** @internal */
|
|
37
|
+
export function normalizeRecoveryPeers(recoveryPeers: readonly number[]): number[] {
|
|
38
|
+
assertValidRecoveryPeers(recoveryPeers);
|
|
39
|
+
|
|
40
|
+
const paddedRecoveryPeers = [...recoveryPeers];
|
|
41
|
+
while (paddedRecoveryPeers.length < MAX_RECOVERY_PEERS) {
|
|
42
|
+
paddedRecoveryPeers.push(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return paddedRecoveryPeers;
|
|
46
|
+
}
|