@dorafactory/maci-sdk 0.0.40 → 0.0.41
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/dist/index.js +3672 -3482
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2714 -2525
- package/dist/index.mjs.map +1 -1
- package/dist/libs/crypto/keys.d.ts +1 -0
- package/dist/libs/http/http.d.ts +1 -0
- package/dist/libs/indexer/indexer.d.ts +2 -1
- package/dist/libs/maci/maci.d.ts +3 -0
- package/dist/libs/query/event.d.ts +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/utils/index.d.ts +17 -0
- package/package.json +1 -1
- package/src/libs/crypto/keys.ts +23 -0
- package/src/libs/http/http.ts +30 -0
- package/src/libs/indexer/indexer.ts +7 -0
- package/src/libs/maci/maci.ts +124 -1
- package/src/libs/query/event.ts +44 -1
- package/src/maci.ts +3 -3
- package/src/types/index.ts +10 -0
- package/src/utils/index.ts +45 -22
- package/dist/index.d.mts +0 -2213
package/dist/libs/http/http.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ export declare class Http {
|
|
|
13
13
|
fetch(url: string, options?: any): Promise<Response>;
|
|
14
14
|
fetchGraphql<T>(query: string, after: string, limit?: number | null): Promise<T>;
|
|
15
15
|
fetchRest(path: string, options?: any): Promise<any>;
|
|
16
|
+
fetchAllGraphqlPages<T>(query: string, variables: any): Promise<T[]>;
|
|
16
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BalanceResponse, RoundResponse, RoundsResponse, OperatorResponse, OperatorsResponse, CircuitResponse, TransactionResponse, TransactionsResponse, CircuitsResponse, ProofResponse, SignUpEventsResponse, OperatorDelayOperationsResponse, MissRateResponse, SelectiveRoundResponse } from '../../types';
|
|
1
|
+
import { BalanceResponse, RoundResponse, RoundsResponse, OperatorResponse, OperatorsResponse, CircuitResponse, TransactionResponse, TransactionsResponse, CircuitsResponse, ProofResponse, SignUpEventsResponse, OperatorDelayOperationsResponse, MissRateResponse, SelectiveRoundResponse, DeactivateMessage } from '../../types';
|
|
2
2
|
import { IndexerParams } from './types';
|
|
3
3
|
import { Http } from '../http';
|
|
4
4
|
import { Round, UserAccount, Circuit, Operator, Proof, Transaction, Event } from '../query';
|
|
@@ -149,4 +149,5 @@ export declare class Indexer {
|
|
|
149
149
|
* @returns {Promise<SignUpEventsResponse>} The sign up events response.
|
|
150
150
|
*/
|
|
151
151
|
getSignUpEventByPubKey(contractAddress: string, pubKey: bigint[]): Promise<SignUpEventsResponse>;
|
|
152
|
+
fetchAllDeactivateLogs(contractAddress: string): Promise<DeactivateMessage[]>;
|
|
152
153
|
}
|
package/dist/libs/maci/maci.d.ts
CHANGED
|
@@ -152,6 +152,9 @@ export declare class MACI {
|
|
|
152
152
|
gasStation?: boolean;
|
|
153
153
|
fee?: StdFee;
|
|
154
154
|
}): Promise<import("@cosmjs/cosmwasm-stargate").ExecuteResult>;
|
|
155
|
+
fetchAllDeactivateLogs({ contractAddress, }: {
|
|
156
|
+
contractAddress: string;
|
|
157
|
+
}): Promise<import("../../types").DeactivateMessage[]>;
|
|
155
158
|
claimAMaciRound({ signer, contractAddress, fee, }: {
|
|
156
159
|
signer: OfflineSigner;
|
|
157
160
|
contractAddress: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -381,3 +381,12 @@ export type MissRateType = {
|
|
|
381
381
|
deactivateCount: number;
|
|
382
382
|
missRate: number;
|
|
383
383
|
};
|
|
384
|
+
export type DeactivateMessage = {
|
|
385
|
+
id: string;
|
|
386
|
+
blockHeight: string;
|
|
387
|
+
timestamp: string;
|
|
388
|
+
txHash: string;
|
|
389
|
+
deactivateMessage: string;
|
|
390
|
+
maciContractAddress: string;
|
|
391
|
+
maciOperator: string;
|
|
392
|
+
};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -5,3 +5,20 @@ export declare function isValidAddress(address: string): boolean;
|
|
|
5
5
|
* @returns The decimal string representation of the input.
|
|
6
6
|
*/
|
|
7
7
|
export declare function hexToDecimalString(hexString: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a hexadecimal string to a BigInt.
|
|
10
|
+
* @param hexString - The hexadecimal string to convert.
|
|
11
|
+
* @returns The BigInt representation of the input.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hexToBigInt(hexString: string): bigint;
|
|
14
|
+
/**
|
|
15
|
+
* Parses a public key string into its x and y coordinates.
|
|
16
|
+
* @param publickKey - The public key string to parse (128 characters long).
|
|
17
|
+
* @returns An object containing the x and y coordinates as decimal strings.
|
|
18
|
+
*/
|
|
19
|
+
export declare function decompressPublicKey(compressedPubkey: string): {
|
|
20
|
+
x: string;
|
|
21
|
+
y: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function compressPublicKey(decompressedPubkey: any[]): string;
|
|
24
|
+
export declare function transformPubkey(oldPubkey: string): bigint;
|
package/package.json
CHANGED
package/src/libs/crypto/keys.ts
CHANGED
|
@@ -296,3 +296,26 @@ export const genAddKeyProof = async (
|
|
|
296
296
|
|
|
297
297
|
return input;
|
|
298
298
|
};
|
|
299
|
+
|
|
300
|
+
// LIB
|
|
301
|
+
function randomUint256() {
|
|
302
|
+
const buffer = [];
|
|
303
|
+
for (let i = 0; i < 64; i++) {
|
|
304
|
+
buffer.push(
|
|
305
|
+
Math.floor(Math.random() * 256)
|
|
306
|
+
.toString(16)
|
|
307
|
+
.padStart(2, '0')
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
return buffer.join('');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export const genRandomKey = () => {
|
|
314
|
+
const key = [
|
|
315
|
+
randomUint256(),
|
|
316
|
+
randomUint256(),
|
|
317
|
+
randomUint256(),
|
|
318
|
+
randomUint256(),
|
|
319
|
+
].join('');
|
|
320
|
+
return ['-----BEGIN MACI KEY-----', key, '-----END MACI KEY-----'].join('\n');
|
|
321
|
+
};
|
package/src/libs/http/http.ts
CHANGED
|
@@ -146,4 +146,34 @@ export class Http {
|
|
|
146
146
|
);
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
+
|
|
150
|
+
async fetchAllGraphqlPages<T>(query: string, variables: any): Promise<T[]> {
|
|
151
|
+
let hasNextPage = true;
|
|
152
|
+
let offset = 0;
|
|
153
|
+
const limit = 100; // Adjust the limit as needed
|
|
154
|
+
const allData: T[] = [];
|
|
155
|
+
|
|
156
|
+
while (hasNextPage) {
|
|
157
|
+
const response = await this.fetch(this.apiEndpoint, {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: {
|
|
160
|
+
'Content-Type': 'application/json',
|
|
161
|
+
Accept: 'application/json',
|
|
162
|
+
},
|
|
163
|
+
body: JSON.stringify({
|
|
164
|
+
query,
|
|
165
|
+
variables: { ...variables, limit, offset },
|
|
166
|
+
}),
|
|
167
|
+
}).then((res) => res.json());
|
|
168
|
+
|
|
169
|
+
const key = Object.keys(response.data)[0];
|
|
170
|
+
|
|
171
|
+
const { nodes, pageInfo } = response.data[key];
|
|
172
|
+
allData.push(...nodes);
|
|
173
|
+
hasNextPage = pageInfo.hasNextPage;
|
|
174
|
+
offset += limit;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return allData;
|
|
178
|
+
}
|
|
149
179
|
}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
OperatorDelayOperationsResponse,
|
|
14
14
|
MissRateResponse,
|
|
15
15
|
SelectiveRoundResponse,
|
|
16
|
+
DeactivateMessage,
|
|
16
17
|
} from '../../types';
|
|
17
18
|
import { IndexerParams } from './types';
|
|
18
19
|
import { Http } from '../http';
|
|
@@ -291,4 +292,10 @@ export class Indexer {
|
|
|
291
292
|
): Promise<SignUpEventsResponse> {
|
|
292
293
|
return await this.event.getSignUpEventByPubKey(contractAddress, pubKey);
|
|
293
294
|
}
|
|
295
|
+
|
|
296
|
+
async fetchAllDeactivateLogs(
|
|
297
|
+
contractAddress: string
|
|
298
|
+
): Promise<DeactivateMessage[]> {
|
|
299
|
+
return await this.event.fetchAllDeactivateLogs(contractAddress);
|
|
300
|
+
}
|
|
294
301
|
}
|
package/src/libs/maci/maci.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { OfflineSigner } from '@cosmjs/proto-signing';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Keypair,
|
|
4
|
+
batchGenMessage,
|
|
5
|
+
PubKey,
|
|
6
|
+
stringizing,
|
|
7
|
+
genAddKeyProof,
|
|
8
|
+
} from '../crypto';
|
|
3
9
|
import { Contract } from '../contract';
|
|
4
10
|
import { Indexer } from '../indexer';
|
|
5
11
|
import { OracleCertificate } from '../oracle-certificate';
|
|
@@ -782,6 +788,123 @@ export class MACI {
|
|
|
782
788
|
);
|
|
783
789
|
}
|
|
784
790
|
|
|
791
|
+
// async submitDeactivate({
|
|
792
|
+
// signer,
|
|
793
|
+
// client,
|
|
794
|
+
// address,
|
|
795
|
+
// maciAccount,
|
|
796
|
+
// contractAddress,
|
|
797
|
+
// gasStation,
|
|
798
|
+
// fee,
|
|
799
|
+
// }: {
|
|
800
|
+
// signer: OfflineSigner;
|
|
801
|
+
// client: SigningCosmWasmClient;
|
|
802
|
+
// address?: string;
|
|
803
|
+
// maciAccount: Keypair;
|
|
804
|
+
// contractAddress: string;
|
|
805
|
+
// gasStation: boolean;
|
|
806
|
+
// fee?: StdFee;
|
|
807
|
+
// }) {
|
|
808
|
+
// try {
|
|
809
|
+
// address = address || (await signer.getAccounts())[0].address;
|
|
810
|
+
|
|
811
|
+
// const stateIdx = await this.getStateIdxInc({
|
|
812
|
+
// signer,
|
|
813
|
+
// address,
|
|
814
|
+
// contractAddress,
|
|
815
|
+
// });
|
|
816
|
+
|
|
817
|
+
// const operatorCoordPubKey = await this.getRoundInfo({
|
|
818
|
+
// contractAddress,
|
|
819
|
+
// });
|
|
820
|
+
|
|
821
|
+
// const payload = batchGenMessage(
|
|
822
|
+
// Number(stateIdx),
|
|
823
|
+
// maciAccount,
|
|
824
|
+
// [
|
|
825
|
+
// BigInt(operatorCoordPubKey.coordinatorPubkeyX),
|
|
826
|
+
// BigInt(operatorCoordPubKey.coordinatorPubkeyY),
|
|
827
|
+
// ],
|
|
828
|
+
// [[0, 0]]
|
|
829
|
+
// );
|
|
830
|
+
|
|
831
|
+
// const { msg, encPubkeys } = payload[0];
|
|
832
|
+
|
|
833
|
+
// const gasPrice = GasPrice.fromString('100000000000peaka');
|
|
834
|
+
// fee = fee || calculateFee(20000000, gasPrice);
|
|
835
|
+
|
|
836
|
+
// return client.execute(
|
|
837
|
+
// address,
|
|
838
|
+
// contractAddress,
|
|
839
|
+
// stringizing({
|
|
840
|
+
// publish_deactivate_message: {
|
|
841
|
+
// enc_pub_key: {
|
|
842
|
+
// x: encPubkeys[0],
|
|
843
|
+
// y: encPubkeys[1],
|
|
844
|
+
// },
|
|
845
|
+
// message: {
|
|
846
|
+
// data: msg,
|
|
847
|
+
// },
|
|
848
|
+
// },
|
|
849
|
+
// }),
|
|
850
|
+
// gasStation === true
|
|
851
|
+
// ? {
|
|
852
|
+
// amount: fee.amount,
|
|
853
|
+
// gas: fee.gas,
|
|
854
|
+
// granter: contractAddress,
|
|
855
|
+
// }
|
|
856
|
+
// : fee
|
|
857
|
+
// );
|
|
858
|
+
// } catch (error) {
|
|
859
|
+
// throw Error(`Submit deactivate failed! ${error}`);
|
|
860
|
+
// }
|
|
861
|
+
// }
|
|
862
|
+
|
|
863
|
+
async fetchAllDeactivateLogs({
|
|
864
|
+
contractAddress,
|
|
865
|
+
}: {
|
|
866
|
+
contractAddress: string;
|
|
867
|
+
}) {
|
|
868
|
+
const deactivates =
|
|
869
|
+
await this.indexer.fetchAllDeactivateLogs(contractAddress);
|
|
870
|
+
return deactivates;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// async addNewKey({
|
|
874
|
+
// signer,
|
|
875
|
+
// client,
|
|
876
|
+
// address,
|
|
877
|
+
// maciAccount,
|
|
878
|
+
// contractAddress,
|
|
879
|
+
// gasStation,
|
|
880
|
+
// fee,
|
|
881
|
+
// }: {
|
|
882
|
+
// signer: OfflineSigner;
|
|
883
|
+
// client: SigningCosmWasmClient;
|
|
884
|
+
// address?: string;
|
|
885
|
+
// maciAccount: Keypair;
|
|
886
|
+
// contractAddress: string;
|
|
887
|
+
// gasStation: boolean;
|
|
888
|
+
// fee?: StdFee;
|
|
889
|
+
// }) {
|
|
890
|
+
// const deactivates = await this.fetchAllDeactivateLogs({
|
|
891
|
+
// contractAddress,
|
|
892
|
+
// });
|
|
893
|
+
|
|
894
|
+
// const roundInfo = await this.getRoundInfo({
|
|
895
|
+
// contractAddress,
|
|
896
|
+
// });
|
|
897
|
+
|
|
898
|
+
// const inputObj = await genAddKeyProof(4, {
|
|
899
|
+
// coordPubKey: [
|
|
900
|
+
// BigInt(roundInfo.coordinatorPubkeyX),
|
|
901
|
+
// BigInt(roundInfo.coordinatorPubkeyY),
|
|
902
|
+
// ],
|
|
903
|
+
// oldKey: maciAccount,
|
|
904
|
+
// deactivates: deactivates.map((d: any) => d.map(BigInt)),
|
|
905
|
+
// });
|
|
906
|
+
// }
|
|
907
|
+
|
|
785
908
|
async claimAMaciRound({
|
|
786
909
|
signer,
|
|
787
910
|
contractAddress,
|
package/src/libs/query/event.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Http } from '../../libs';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DeactivateMessage,
|
|
4
|
+
SignUpEventsGraphqlResponse,
|
|
5
|
+
SignUpEventsResponse,
|
|
6
|
+
} from '../../types';
|
|
3
7
|
import { handleError, ErrorType } from '../errors';
|
|
4
8
|
import { ERROR } from '../errors/types';
|
|
5
9
|
|
|
@@ -75,4 +79,43 @@ query signUpEvents($limit: Int, $after: Cursor) {
|
|
|
75
79
|
return handleError(error as ErrorType);
|
|
76
80
|
}
|
|
77
81
|
}
|
|
82
|
+
|
|
83
|
+
async fetchAllDeactivateLogs(contractAddress: string) {
|
|
84
|
+
const DEACTIVATE_MESSAGE_QUERY = `query ($limit: Int, $offset: Int) {
|
|
85
|
+
deactivateMessages(
|
|
86
|
+
first: $limit,
|
|
87
|
+
offset: $offset,
|
|
88
|
+
orderBy: [BLOCK_HEIGHT_ASC],
|
|
89
|
+
filter: {
|
|
90
|
+
maciContractAddress: {
|
|
91
|
+
equalTo: "${contractAddress}"
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
) {
|
|
95
|
+
totalCount
|
|
96
|
+
pageInfo {
|
|
97
|
+
endCursor
|
|
98
|
+
hasNextPage
|
|
99
|
+
}
|
|
100
|
+
nodes {
|
|
101
|
+
id
|
|
102
|
+
blockHeight
|
|
103
|
+
timestamp
|
|
104
|
+
txHash
|
|
105
|
+
deactivateMessage
|
|
106
|
+
maciContractAddress
|
|
107
|
+
maciOperator
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}`;
|
|
111
|
+
const ds = await this.http.fetchAllGraphqlPages<DeactivateMessage>(
|
|
112
|
+
DEACTIVATE_MESSAGE_QUERY,
|
|
113
|
+
{}
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return ds.reduce(
|
|
117
|
+
(s, c) => [...s, ...JSON.parse(c.deactivateMessage)],
|
|
118
|
+
[] as string[][]
|
|
119
|
+
);
|
|
120
|
+
}
|
|
78
121
|
}
|
package/src/maci.ts
CHANGED
|
@@ -195,21 +195,21 @@ export class MaciClient {
|
|
|
195
195
|
|
|
196
196
|
async createAMaciRound(params: CreateAMaciRoundParams) {
|
|
197
197
|
return await this.contract.createAMaciRound({
|
|
198
|
-
signer: this.getSigner(),
|
|
198
|
+
signer: this.getSigner(params.signer),
|
|
199
199
|
...params,
|
|
200
200
|
});
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
async createMaciRound(params: CreateMaciRoundParams) {
|
|
204
204
|
return await this.contract.createMaciRound({
|
|
205
|
-
signer: this.getSigner(),
|
|
205
|
+
signer: this.getSigner(params.signer),
|
|
206
206
|
...params,
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
async createOracleMaciRound(params: CreateOracleMaciRoundParams) {
|
|
211
211
|
return await this.contract.createOracleMaciRound({
|
|
212
|
-
signer: this.getSigner(),
|
|
212
|
+
signer: this.getSigner(params.signer),
|
|
213
213
|
...params,
|
|
214
214
|
});
|
|
215
215
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -459,3 +459,13 @@ export type MissRateType = {
|
|
|
459
459
|
deactivateCount: number;
|
|
460
460
|
missRate: number;
|
|
461
461
|
};
|
|
462
|
+
|
|
463
|
+
export type DeactivateMessage = {
|
|
464
|
+
id: string;
|
|
465
|
+
blockHeight: string;
|
|
466
|
+
timestamp: string;
|
|
467
|
+
txHash: string;
|
|
468
|
+
deactivateMessage: string; // '[["0", "1", "2", "3", "4"]]'
|
|
469
|
+
maciContractAddress: string;
|
|
470
|
+
maciOperator: string;
|
|
471
|
+
};
|
package/src/utils/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { decode } from 'bech32';
|
|
2
|
+
import { packPubKey, PubKey } from 'src/libs/crypto';
|
|
2
3
|
|
|
3
4
|
function verifyIsBech32(address: string): Error | undefined {
|
|
4
5
|
try {
|
|
@@ -25,6 +26,16 @@ export function hexToDecimalString(hexString: string) {
|
|
|
25
26
|
return decimalString;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Converts a hexadecimal string to a BigInt.
|
|
31
|
+
* @param hexString - The hexadecimal string to convert.
|
|
32
|
+
* @returns The BigInt representation of the input.
|
|
33
|
+
*/
|
|
34
|
+
export function hexToBigInt(hexString: string) {
|
|
35
|
+
return BigInt('0x' + hexString);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
28
39
|
function padWithZerosIfNeeded(inputString: string) {
|
|
29
40
|
if (inputString.length === 64) {
|
|
30
41
|
return inputString;
|
|
@@ -36,25 +47,37 @@ function padWithZerosIfNeeded(inputString: string) {
|
|
|
36
47
|
throw new Error('Invalid input string length');
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Parses a public key string into its x and y coordinates.
|
|
52
|
+
* @param publickKey - The public key string to parse (128 characters long).
|
|
53
|
+
* @returns An object containing the x and y coordinates as decimal strings.
|
|
54
|
+
*/
|
|
55
|
+
export function decompressPublicKey(compressedPubkey: string) {
|
|
56
|
+
const x = compressedPubkey.slice(0, 64);
|
|
57
|
+
const y = compressedPubkey.slice(64);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
x: hexToDecimalString(x),
|
|
61
|
+
y: hexToDecimalString(y),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function compressPublicKey(decompressedPubkey: any[]) {
|
|
66
|
+
const x = decompressedPubkey[0];
|
|
67
|
+
const y = decompressedPubkey[1];
|
|
68
|
+
const compressedPubkey =
|
|
69
|
+
padWithZerosIfNeeded(x.toString(16)) + padWithZerosIfNeeded(y.toString(16));
|
|
70
|
+
return compressedPubkey;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
export function transformPubkey(oldPubkey: string) {
|
|
75
|
+
const x = oldPubkey.slice(0, 64);
|
|
76
|
+
const y = oldPubkey.slice(64);
|
|
77
|
+
|
|
78
|
+
const pubkey: PubKey = [hexToBigInt(x), hexToBigInt(y)];
|
|
79
|
+
console.log(pubkey)
|
|
80
|
+
console.log([hexToDecimalString(x), hexToDecimalString(y)])
|
|
81
|
+
const packedPubkey = packPubKey(pubkey);
|
|
82
|
+
return packedPubkey;
|
|
83
|
+
}
|