@dorafactory/maci-sdk 0.0.3 → 0.0.5
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 +128 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +54 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -22
- package/dist/index.mjs.map +1 -1
- package/dist/libs/contract/contract.d.ts +4 -2
- package/dist/libs/contract/types.d.ts +2 -4
- package/dist/libs/contract/utils.d.ts +0 -9
- package/dist/maci.d.ts +3 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/utils/index.d.ts +16 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/libs/contract/contract.ts +12 -7
- package/src/libs/contract/types.ts +4 -4
- package/src/libs/contract/utils.ts +0 -25
- package/src/maci.ts +11 -0
- package/src/types/index.ts +4 -0
- package/src/utils/index.ts +43 -27
package/README.md
CHANGED
|
@@ -1 +1,128 @@
|
|
|
1
|
-
# Maci
|
|
1
|
+
# Maci Client
|
|
2
|
+
|
|
3
|
+
MACI (Minimal Anti-Collusion Infrastructure) client SDK for interacting with MACI contracts.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @dorafactory/maci-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Initialize Client
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { MaciClient } from '@dorafactory/maci-sdk';
|
|
17
|
+
|
|
18
|
+
const client = new MaciClient({
|
|
19
|
+
network: 'testnet', // or 'mainnet'
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Query Functions
|
|
24
|
+
|
|
25
|
+
#### Query Account Balance
|
|
26
|
+
```typescript
|
|
27
|
+
const balance = await client.balanceOf('dora1...');
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
#### Query Round Information
|
|
31
|
+
```typescript
|
|
32
|
+
// Query round by ID
|
|
33
|
+
const round = await client.getRoundById('dora1...');
|
|
34
|
+
|
|
35
|
+
// Get list of rounds
|
|
36
|
+
const rounds = await client.getRounds('first', 10);
|
|
37
|
+
|
|
38
|
+
// Query rounds by status
|
|
39
|
+
const roundsByStatus = await client.getRoundsByStatus('Created', 'first', 10);
|
|
40
|
+
|
|
41
|
+
// Query rounds by circuit name
|
|
42
|
+
const roundsByCircuit = await client.getRoundsByCircuitName('amaci-qv', 'first', 10);
|
|
43
|
+
|
|
44
|
+
// Query rounds by operator address
|
|
45
|
+
const roundsByOperator = await client.getRoundsByOperator('dora1...', 'first', 10);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Query Operator Information
|
|
49
|
+
```typescript
|
|
50
|
+
// Query operator by address
|
|
51
|
+
const operator = await client.getOperatorByAddress('dora1...');
|
|
52
|
+
|
|
53
|
+
// Get list of operators
|
|
54
|
+
const operators = await client.getOperators('first', 10);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Query Circuit Information
|
|
58
|
+
```typescript
|
|
59
|
+
// Query circuit by name
|
|
60
|
+
const circuit = await client.getCircuitByName('amaci-qv');
|
|
61
|
+
|
|
62
|
+
// Get all circuits
|
|
63
|
+
const circuits = await client.getCircuits();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Query Transaction Information
|
|
67
|
+
```typescript
|
|
68
|
+
// Query transaction by hash
|
|
69
|
+
const transaction = await client.getTransactionByHash('HASH...');
|
|
70
|
+
|
|
71
|
+
// Get list of transactions
|
|
72
|
+
const transactions = await client.getTransactions('first', 10);
|
|
73
|
+
|
|
74
|
+
// Query transactions by contract address
|
|
75
|
+
const txByContract = await client.getTransactionsByContractAddress('dora1...', 'first', 10);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Query Proof Information
|
|
79
|
+
```typescript
|
|
80
|
+
const proof = await client.getProofByContractAddress('dora1...');
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Contract Interactions
|
|
84
|
+
|
|
85
|
+
#### Create New Oracle Maci Round
|
|
86
|
+
```typescript
|
|
87
|
+
const wallet = await DirectSecp256k1Wallet.fromKey(
|
|
88
|
+
Buffer.from(privateKey, 'hex'),
|
|
89
|
+
'dora'
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const newRound = await client.createOracleMaciRound({
|
|
93
|
+
signer: wallet,
|
|
94
|
+
operatorPubkey: '0e752c...',
|
|
95
|
+
startVoting: new Date(),
|
|
96
|
+
endVoting: new Date(new Date().getTime() + 10 * 60 * 1000),
|
|
97
|
+
title: 'Just for fun',
|
|
98
|
+
description: 'some description',
|
|
99
|
+
link: 'https://www.dorafactory.org',
|
|
100
|
+
maxVoter: '5',
|
|
101
|
+
maxOption: '5',
|
|
102
|
+
circuitType: MaciCircuitType.IP1V,
|
|
103
|
+
whitelistEcosystem: 'cosmoshub',
|
|
104
|
+
whitelistSnapshotHeight: '0',
|
|
105
|
+
whitelistVotingPowerArgs: {
|
|
106
|
+
mode: 'slope',
|
|
107
|
+
slope: '1000000',
|
|
108
|
+
threshold: '1000000',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Note:**
|
|
114
|
+
- The `operatorPubkey` is the public key of the operator. It is the compressed public key of the operator's private key.
|
|
115
|
+
- The `whitelistEcosystem` is the ecosystem of the whitelist (e.g. 'cosmoshub'). Only wallet addresses that have staked tokens in the specified ecosystem before the snapshot block height will be eligible to become voters.
|
|
116
|
+
- The `whitelistSnapshotHeight` is the snapshot block height for checking voter eligibility. The minimum valid height is 23,342,001. If set to "0", the round will evaluate the voter's stake at the time of signup.
|
|
117
|
+
- The `whitelistVotingPowerArgs` configures how voting power is calculated:
|
|
118
|
+
- `mode`: Can be either 'slope' or 'threshold'
|
|
119
|
+
- 'slope' mode: Calculates voice credits based on each voter's stake amount using the formula: voice credits = staked tokens / slope value
|
|
120
|
+
- 'threshold' mode: Equally assigns 1 voice credit to voters whose stake exceeds the specified threshold
|
|
121
|
+
- `slope`: The slope value for calculating voice credits in slope mode (e.g. 1000000)
|
|
122
|
+
- `threshold`: The minimum stake threshold in threshold mode (e.g. 1000000)
|
|
123
|
+
|
|
124
|
+
For example, if a voter stakes 100000000 tokens and the slope value is 2500000, the voter will be assigned 40 voice credits.
|
|
125
|
+
|
|
126
|
+
> The 1,000,000 reference value here is the precision of cosmoshub, which is 6 bits, and doravota, which is 18 bits, so when you want to pick doravota's staker as a whitelist and ask them to pledge 1DORA to convert 1vote, you need to set the scope to 1000000000000000000 (10**18). Note that currently only cosmoshub and doravota are supported as ecosystem options.
|
|
127
|
+
>
|
|
128
|
+
> One detail, here the slope is calculated by rounding down.
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -34,7 +34,11 @@ __export(src_exports, {
|
|
|
34
34
|
Round: () => Round,
|
|
35
35
|
Transaction: () => Transaction,
|
|
36
36
|
circuits: () => circuits,
|
|
37
|
+
compressPublicKey: () => compressPublicKey,
|
|
38
|
+
decompressPublicKey: () => decompressPublicKey,
|
|
37
39
|
getDefaultParams: () => getDefaultParams,
|
|
40
|
+
hexToDecimalString: () => hexToDecimalString,
|
|
41
|
+
isValidAddress: () => isValidAddress,
|
|
38
42
|
validator_operator_set: () => validator_operator_set
|
|
39
43
|
});
|
|
40
44
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -557,6 +561,34 @@ function verifyIsBech32(address) {
|
|
|
557
561
|
function isValidAddress(address) {
|
|
558
562
|
return address.startsWith("dora") && verifyIsBech32(address) === void 0;
|
|
559
563
|
}
|
|
564
|
+
function hexToDecimalString(hexString) {
|
|
565
|
+
const decimalString = BigInt("0x" + hexString).toString(10);
|
|
566
|
+
return decimalString;
|
|
567
|
+
}
|
|
568
|
+
function padWithZerosIfNeeded(inputString) {
|
|
569
|
+
if (inputString.length === 64) {
|
|
570
|
+
return inputString;
|
|
571
|
+
} else if (inputString.length < 64) {
|
|
572
|
+
const zerosToAdd = 64 - inputString.length;
|
|
573
|
+
const zeroPadding = "0".repeat(zerosToAdd);
|
|
574
|
+
return zeroPadding + inputString;
|
|
575
|
+
}
|
|
576
|
+
throw new Error("Invalid input string length");
|
|
577
|
+
}
|
|
578
|
+
function decompressPublicKey(compressedPubkey) {
|
|
579
|
+
const x = compressedPubkey.slice(0, 64);
|
|
580
|
+
const y = compressedPubkey.slice(64);
|
|
581
|
+
return {
|
|
582
|
+
x: hexToDecimalString(x),
|
|
583
|
+
y: hexToDecimalString(y)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function compressPublicKey(decompressedPubkey) {
|
|
587
|
+
const x = decompressedPubkey[0];
|
|
588
|
+
const y = decompressedPubkey[1];
|
|
589
|
+
const compressedPubkey = padWithZerosIfNeeded(x.toString(16)) + padWithZerosIfNeeded(y.toString(16));
|
|
590
|
+
return compressedPubkey;
|
|
591
|
+
}
|
|
560
592
|
|
|
561
593
|
// src/libs/query/operator.ts
|
|
562
594
|
var Operator = class {
|
|
@@ -3669,18 +3701,6 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
|
|
|
3669
3701
|
};
|
|
3670
3702
|
}
|
|
3671
3703
|
}
|
|
3672
|
-
function hexToDecimalString(hexString) {
|
|
3673
|
-
const decimalString = BigInt("0x" + hexString).toString(10);
|
|
3674
|
-
return decimalString;
|
|
3675
|
-
}
|
|
3676
|
-
function parsePubkey(publickKey) {
|
|
3677
|
-
const x = publickKey.slice(0, 64);
|
|
3678
|
-
const y = publickKey.slice(64);
|
|
3679
|
-
return {
|
|
3680
|
-
x: hexToDecimalString(x),
|
|
3681
|
-
y: hexToDecimalString(y)
|
|
3682
|
-
};
|
|
3683
|
-
}
|
|
3684
3704
|
|
|
3685
3705
|
// src/libs/contract/contract.ts
|
|
3686
3706
|
var Contract = class {
|
|
@@ -3688,12 +3708,16 @@ var Contract = class {
|
|
|
3688
3708
|
rpcEndpoint,
|
|
3689
3709
|
registryAddress,
|
|
3690
3710
|
maciCodeId,
|
|
3691
|
-
oracleCodeId
|
|
3711
|
+
oracleCodeId,
|
|
3712
|
+
feegrantOperator,
|
|
3713
|
+
whitelistBackendPubkey
|
|
3692
3714
|
}) {
|
|
3693
3715
|
this.rpcEndpoint = rpcEndpoint;
|
|
3694
3716
|
this.registryAddress = registryAddress;
|
|
3695
3717
|
this.maciCodeId = maciCodeId;
|
|
3696
3718
|
this.oracleCodeId = oracleCodeId;
|
|
3719
|
+
this.feegrantOperator = feegrantOperator;
|
|
3720
|
+
this.whitelistBackendPubkey = whitelistBackendPubkey;
|
|
3697
3721
|
}
|
|
3698
3722
|
async createAMaciRound({
|
|
3699
3723
|
signer,
|
|
@@ -3769,7 +3793,7 @@ var Contract = class {
|
|
|
3769
3793
|
const end_time = (endVoting.getTime() * 10 ** 6).toString();
|
|
3770
3794
|
const [{ address }] = await signer.getAccounts();
|
|
3771
3795
|
const client = await createContractClientByWallet(this.rpcEndpoint, signer);
|
|
3772
|
-
const { x: operatorPubkeyX, y: operatorPubkeyY } =
|
|
3796
|
+
const { x: operatorPubkeyX, y: operatorPubkeyY } = decompressPublicKey(operatorPubkey);
|
|
3773
3797
|
const {
|
|
3774
3798
|
parameters,
|
|
3775
3799
|
groth16ProcessVkey,
|
|
@@ -3825,17 +3849,15 @@ var Contract = class {
|
|
|
3825
3849
|
maxVoter,
|
|
3826
3850
|
maxOption,
|
|
3827
3851
|
circuitType,
|
|
3828
|
-
whitelistBackendPubkey,
|
|
3829
3852
|
whitelistEcosystem,
|
|
3830
3853
|
whitelistSnapshotHeight,
|
|
3831
|
-
whitelistVotingPowerArgs
|
|
3832
|
-
feegrantOperator
|
|
3854
|
+
whitelistVotingPowerArgs
|
|
3833
3855
|
}) {
|
|
3834
3856
|
const start_time = (startVoting.getTime() * 1e6).toString();
|
|
3835
3857
|
const end_time = (endVoting.getTime() * 1e6).toString();
|
|
3836
3858
|
const [{ address }] = await signer.getAccounts();
|
|
3837
3859
|
const client = await createContractClientByWallet(this.rpcEndpoint, signer);
|
|
3838
|
-
const { x: operatorPubkeyX, y: operatorPubkeyY } =
|
|
3860
|
+
const { x: operatorPubkeyX, y: operatorPubkeyY } = decompressPublicKey(operatorPubkey);
|
|
3839
3861
|
const {
|
|
3840
3862
|
parameters,
|
|
3841
3863
|
groth16ProcessVkey,
|
|
@@ -3870,14 +3892,14 @@ var Contract = class {
|
|
|
3870
3892
|
plonk_process_vkey: plonkProcessVkey,
|
|
3871
3893
|
plonk_tally_vkey: plonkTallyVkey,
|
|
3872
3894
|
max_vote_options: maxOption,
|
|
3873
|
-
whitelist_backend_pubkey: whitelistBackendPubkey,
|
|
3895
|
+
whitelist_backend_pubkey: this.whitelistBackendPubkey,
|
|
3874
3896
|
whitelist_ecosystem: whitelistEcosystem,
|
|
3875
3897
|
whitelist_snapshot_height: whitelistSnapshotHeight,
|
|
3876
3898
|
whitelist_voting_power_args: whitelistVotingPowerArgs,
|
|
3877
3899
|
circuit_type: maciVoteType,
|
|
3878
3900
|
certification_system: maciCertSystem,
|
|
3879
3901
|
qtr_lib: QTR_LIB,
|
|
3880
|
-
feegrant_operator: feegrantOperator
|
|
3902
|
+
feegrant_operator: this.feegrantOperator
|
|
3881
3903
|
},
|
|
3882
3904
|
"[Oracle MACI]" + title,
|
|
3883
3905
|
"auto"
|
|
@@ -3954,7 +3976,9 @@ var MaciClient2 = class {
|
|
|
3954
3976
|
maciCodeId,
|
|
3955
3977
|
oracleCodeId,
|
|
3956
3978
|
customFetch,
|
|
3957
|
-
defaultOptions
|
|
3979
|
+
defaultOptions,
|
|
3980
|
+
feegrantOperator,
|
|
3981
|
+
whitelistBackendPubkey
|
|
3958
3982
|
}) {
|
|
3959
3983
|
const defaultParams = getDefaultParams(network);
|
|
3960
3984
|
this.rpcEndpoint = rpcEndpoint || defaultParams.rpcEndpoint;
|
|
@@ -3963,6 +3987,8 @@ var MaciClient2 = class {
|
|
|
3963
3987
|
this.registryAddress = registryAddress || defaultParams.registryAddress;
|
|
3964
3988
|
this.maciCodeId = maciCodeId || defaultParams.maciCodeId;
|
|
3965
3989
|
this.oracleCodeId = oracleCodeId || defaultParams.oracleCodeId;
|
|
3990
|
+
this.feegrantOperator = feegrantOperator || defaultParams.oracleFeegrantOperator;
|
|
3991
|
+
this.whitelistBackendPubkey = whitelistBackendPubkey || defaultParams.oracleWhitelistBackendPubkey;
|
|
3966
3992
|
this.http = new Http(
|
|
3967
3993
|
this.apiEndpoint,
|
|
3968
3994
|
this.restEndpoint,
|
|
@@ -3979,7 +4005,9 @@ var MaciClient2 = class {
|
|
|
3979
4005
|
rpcEndpoint: this.rpcEndpoint,
|
|
3980
4006
|
registryAddress: this.registryAddress,
|
|
3981
4007
|
maciCodeId: this.maciCodeId,
|
|
3982
|
-
oracleCodeId: this.oracleCodeId
|
|
4008
|
+
oracleCodeId: this.oracleCodeId,
|
|
4009
|
+
feegrantOperator: this.feegrantOperator,
|
|
4010
|
+
whitelistBackendPubkey: this.whitelistBackendPubkey
|
|
3983
4011
|
});
|
|
3984
4012
|
}
|
|
3985
4013
|
async oracleMaciClient({
|
|
@@ -4175,7 +4203,11 @@ var MaciClient2 = class {
|
|
|
4175
4203
|
Round,
|
|
4176
4204
|
Transaction,
|
|
4177
4205
|
circuits,
|
|
4206
|
+
compressPublicKey,
|
|
4207
|
+
decompressPublicKey,
|
|
4178
4208
|
getDefaultParams,
|
|
4209
|
+
hexToDecimalString,
|
|
4210
|
+
isValidAddress,
|
|
4179
4211
|
validator_operator_set
|
|
4180
4212
|
});
|
|
4181
4213
|
//# sourceMappingURL=index.js.map
|