@dorafactory/maci-sdk 0.1.2 → 0.1.3-pre.10

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.
Files changed (39) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +2371 -975
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +2369 -975
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/libs/const.d.ts +1 -2
  7. package/dist/libs/contract/config.d.ts +12 -0
  8. package/dist/libs/contract/contract.d.ts +66 -4
  9. package/dist/libs/contract/ts/AMaci.client.d.ts +25 -3
  10. package/dist/libs/contract/ts/AMaci.types.d.ts +26 -1
  11. package/dist/libs/contract/ts/ApiMaci.client.d.ts +170 -0
  12. package/dist/libs/contract/ts/ApiMaci.types.d.ts +187 -0
  13. package/dist/libs/contract/ts/ApiSaas.client.d.ts +148 -0
  14. package/dist/libs/contract/ts/ApiSaas.types.d.ts +126 -0
  15. package/dist/libs/contract/ts/Registry.client.d.ts +17 -7
  16. package/dist/libs/contract/ts/Registry.types.d.ts +16 -5
  17. package/dist/libs/contract/types.d.ts +15 -3
  18. package/dist/libs/crypto/bigintUtils.d.ts +2 -0
  19. package/dist/libs/maci/maci.d.ts +34 -4
  20. package/dist/maci.d.ts +47 -3
  21. package/dist/types/index.d.ts +2 -2
  22. package/package.json +1 -1
  23. package/src/index.ts +5 -1
  24. package/src/libs/const.ts +5 -6
  25. package/src/libs/contract/config.ts +36 -0
  26. package/src/libs/contract/contract.ts +611 -6
  27. package/src/libs/contract/ts/AMaci.client.ts +66 -0
  28. package/src/libs/contract/ts/AMaci.types.ts +30 -1
  29. package/src/libs/contract/ts/ApiMaci.client.ts +459 -0
  30. package/src/libs/contract/ts/ApiMaci.types.ts +188 -0
  31. package/src/libs/contract/ts/ApiSaas.client.ts +581 -0
  32. package/src/libs/contract/ts/ApiSaas.types.ts +144 -0
  33. package/src/libs/contract/ts/Registry.client.ts +57 -9
  34. package/src/libs/contract/ts/Registry.types.ts +18 -5
  35. package/src/libs/contract/types.ts +16 -3
  36. package/src/libs/crypto/bigintUtils.ts +28 -0
  37. package/src/libs/maci/maci.ts +190 -9
  38. package/src/maci.ts +86 -4
  39. package/src/types/index.ts +2 -2
@@ -2,6 +2,8 @@ import { OfflineSigner } from '@cosmjs/proto-signing';
2
2
  import { ContractParams } from '../../types';
3
3
  import {
4
4
  createAMaciClientBy,
5
+ createApiMaciClientBy,
6
+ createApiSaasClientBy,
5
7
  createContractClientByWallet,
6
8
  createMaciClientBy,
7
9
  createOracleMaciClientBy,
@@ -13,6 +15,7 @@ import {
13
15
  CreateMaciRoundParams,
14
16
  CreateOracleMaciRoundParams,
15
17
  CreateSaasOracleMaciRoundParams,
18
+ CreateApiSaasAmaciRoundParams,
16
19
  } from './types';
17
20
  import { getAMaciRoundCircuitFee, getContractParams } from './utils';
18
21
  import { QTR_LIB } from './vars';
@@ -27,9 +30,9 @@ export class Contract {
27
30
  public rpcEndpoint: string;
28
31
  public registryAddress: string;
29
32
  public saasAddress: string;
33
+ public apiSaasAddress: string;
30
34
  public maciCodeId: number;
31
35
  public oracleCodeId: number;
32
- public saasOracleCodeId: number;
33
36
  public feegrantOperator: string;
34
37
  public whitelistBackendPubkey: string;
35
38
 
@@ -38,9 +41,9 @@ export class Contract {
38
41
  rpcEndpoint,
39
42
  registryAddress,
40
43
  saasAddress,
44
+ apiSaasAddress,
41
45
  maciCodeId,
42
46
  oracleCodeId,
43
- saasOracleCodeId,
44
47
  feegrantOperator,
45
48
  whitelistBackendPubkey,
46
49
  }: ContractParams) {
@@ -48,9 +51,9 @@ export class Contract {
48
51
  this.rpcEndpoint = rpcEndpoint;
49
52
  this.registryAddress = registryAddress;
50
53
  this.saasAddress = saasAddress;
54
+ this.apiSaasAddress = apiSaasAddress;
51
55
  this.maciCodeId = maciCodeId;
52
56
  this.oracleCodeId = oracleCodeId;
53
- this.saasOracleCodeId = saasOracleCodeId;
54
57
  this.feegrantOperator = feegrantOperator;
55
58
  this.whitelistBackendPubkey = whitelistBackendPubkey;
56
59
  }
@@ -65,10 +68,11 @@ export class Contract {
65
68
  description,
66
69
  link,
67
70
  maxVoter,
68
- maxOption,
71
+ voteOptionMap,
69
72
  voiceCreditAmount,
70
73
  circuitType,
71
74
  preDeactivateRoot,
75
+ oracleWhitelistPubkey,
72
76
  fee = 'auto',
73
77
  }: CreateAMaciRoundParams & { signer: OfflineSigner }) {
74
78
  const start_time = (startVoting.getTime() * 10 ** 6).toString();
@@ -82,7 +86,7 @@ export class Contract {
82
86
  const requiredFee = getAMaciRoundCircuitFee(
83
87
  this.network,
84
88
  maxVoter,
85
- maxOption
89
+ voteOptionMap.length
86
90
  );
87
91
 
88
92
  preDeactivateRoot = preDeactivateRoot || '0';
@@ -102,9 +106,10 @@ export class Contract {
102
106
  end_time,
103
107
  },
104
108
  maxVoter: maxVoter.toString(),
105
- maxOption: maxOption.toString(),
109
+ voteOptionMap,
106
110
  certificationSystem: '0',
107
111
  circuitType,
112
+ oracleWhitelistPubkey,
108
113
  },
109
114
  fee,
110
115
  undefined,
@@ -1005,6 +1010,20 @@ export class Contract {
1005
1010
  });
1006
1011
  }
1007
1012
 
1013
+ async apiMaciClient({
1014
+ signer,
1015
+ contractAddress,
1016
+ }: {
1017
+ signer: OfflineSigner;
1018
+ contractAddress: string;
1019
+ }) {
1020
+ return createApiMaciClientBy({
1021
+ rpcEndpoint: this.rpcEndpoint,
1022
+ wallet: signer,
1023
+ contractAddress,
1024
+ });
1025
+ }
1026
+
1008
1027
  async saasClient({
1009
1028
  signer,
1010
1029
  contractAddress,
@@ -1019,7 +1038,593 @@ export class Contract {
1019
1038
  });
1020
1039
  }
1021
1040
 
1041
+ async apiSaasClient({
1042
+ signer,
1043
+ contractAddress,
1044
+ }: {
1045
+ signer: OfflineSigner;
1046
+ contractAddress: string;
1047
+ }) {
1048
+ return createApiSaasClientBy({
1049
+ rpcEndpoint: this.rpcEndpoint,
1050
+ wallet: signer,
1051
+ contractAddress,
1052
+ });
1053
+ }
1054
+
1022
1055
  async contractClient({ signer }: { signer: OfflineSigner }) {
1023
1056
  return createContractClientByWallet(this.rpcEndpoint, signer);
1024
1057
  }
1058
+
1059
+ async createApiSaasMaciRound({
1060
+ signer,
1061
+ operatorPubkey,
1062
+ startVoting,
1063
+ endVoting,
1064
+ title,
1065
+ description,
1066
+ link,
1067
+ maxVoter,
1068
+ voteOptionMap,
1069
+ whitelistBackendPubkey,
1070
+ gasStation = false,
1071
+ fee = 1.8,
1072
+ }: CreateSaasOracleMaciRoundParams & { signer: OfflineSigner }) {
1073
+ const startTime = (startVoting.getTime() * 1_000_000).toString();
1074
+ const endTime = (endVoting.getTime() * 1_000_000).toString();
1075
+
1076
+ const client = await createApiSaasClientBy({
1077
+ rpcEndpoint: this.rpcEndpoint,
1078
+ wallet: signer,
1079
+ contractAddress: this.apiSaasAddress,
1080
+ });
1081
+ const [operatorPubkeyX, operatorPubkeyY] = unpackPubKey(
1082
+ BigInt(operatorPubkey)
1083
+ );
1084
+
1085
+ const roundParams = {
1086
+ certificationSystem: '0',
1087
+ circuitType: '0',
1088
+ coordinator: {
1089
+ x: operatorPubkeyX.toString(),
1090
+ y: operatorPubkeyY.toString(),
1091
+ },
1092
+ maxVoters: maxVoter,
1093
+ roundInfo: {
1094
+ title,
1095
+ description: description || '',
1096
+ link: link || '',
1097
+ },
1098
+ startTime,
1099
+ endTime,
1100
+ voteOptionMap,
1101
+ whitelistBackendPubkey:
1102
+ whitelistBackendPubkey || this.whitelistBackendPubkey,
1103
+ };
1104
+
1105
+ let createResponse;
1106
+
1107
+ if (gasStation && typeof fee !== 'object') {
1108
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1109
+ const [{ address }] = await signer.getAccounts();
1110
+ const contractClient = await this.contractClient({ signer });
1111
+ const msg = {
1112
+ create_api_maci_round: {
1113
+ certification_system: '0',
1114
+ circuit_type: '0',
1115
+ coordinator: roundParams.coordinator,
1116
+ max_voters: roundParams.maxVoters.toString(),
1117
+ round_info: roundParams.roundInfo,
1118
+ start_time: roundParams.startTime,
1119
+ end_time: roundParams.endTime,
1120
+ vote_option_map: roundParams.voteOptionMap,
1121
+ whitelist_backend_pubkey: roundParams.whitelistBackendPubkey,
1122
+ },
1123
+ };
1124
+ const gasEstimation = await contractClient.simulate(
1125
+ address,
1126
+ [
1127
+ {
1128
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1129
+ value: {
1130
+ sender: address,
1131
+ contract: this.apiSaasAddress,
1132
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1133
+ },
1134
+ },
1135
+ ],
1136
+ ''
1137
+ );
1138
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1139
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1140
+ const calculatedFee = calculateFee(
1141
+ Math.round(gasEstimation * multiplier),
1142
+ gasPrice
1143
+ );
1144
+ const grantFee: StdFee = {
1145
+ amount: calculatedFee.amount,
1146
+ gas: calculatedFee.gas,
1147
+ granter: this.apiSaasAddress,
1148
+ };
1149
+ createResponse = await client.createMaciRound(roundParams, grantFee);
1150
+ } else if (gasStation && typeof fee === 'object') {
1151
+ // When gasStation is true and fee is StdFee, add granter
1152
+ const grantFee: StdFee = {
1153
+ ...fee,
1154
+ granter: this.apiSaasAddress,
1155
+ };
1156
+ createResponse = await client.createMaciRound(roundParams, grantFee);
1157
+ } else {
1158
+ createResponse = await client.createMaciRound(roundParams, fee);
1159
+ }
1160
+
1161
+ let contractAddress = '';
1162
+ createResponse.events.map((event) => {
1163
+ if (event.type === 'wasm') {
1164
+ let actionEvent = event.attributes.find(
1165
+ (attr) => attr.key === 'action'
1166
+ )!;
1167
+ if (actionEvent.value === 'created_maci_round') {
1168
+ contractAddress = event.attributes
1169
+ .find((attr) => attr.key === 'round_addr')!
1170
+ .value.toString();
1171
+ }
1172
+ }
1173
+ });
1174
+ return {
1175
+ ...createResponse,
1176
+ contractAddress,
1177
+ };
1178
+ }
1179
+
1180
+ async setApiSaasMaciRoundInfo({
1181
+ signer,
1182
+ contractAddress,
1183
+ title,
1184
+ description,
1185
+ link,
1186
+ gasStation = false,
1187
+ fee = 1.8,
1188
+ }: {
1189
+ signer: OfflineSigner;
1190
+ contractAddress: string;
1191
+ title: string;
1192
+ description: string;
1193
+ link: string;
1194
+ gasStation?: boolean;
1195
+ fee?: StdFee | 'auto' | number;
1196
+ }) {
1197
+ const client = await createApiSaasClientBy({
1198
+ rpcEndpoint: this.rpcEndpoint,
1199
+ wallet: signer,
1200
+ contractAddress: this.apiSaasAddress,
1201
+ });
1202
+
1203
+ const roundInfo = {
1204
+ title,
1205
+ description,
1206
+ link,
1207
+ };
1208
+
1209
+ if (gasStation && typeof fee !== 'object') {
1210
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1211
+ const [{ address }] = await signer.getAccounts();
1212
+ const contractClient = await this.contractClient({ signer });
1213
+ const msg = {
1214
+ set_round_info: {
1215
+ contract_addr: contractAddress,
1216
+ round_info: roundInfo,
1217
+ },
1218
+ };
1219
+ const gasEstimation = await contractClient.simulate(
1220
+ address,
1221
+ [
1222
+ {
1223
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1224
+ value: {
1225
+ sender: address,
1226
+ contract: this.apiSaasAddress,
1227
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1228
+ },
1229
+ },
1230
+ ],
1231
+ ''
1232
+ );
1233
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1234
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1235
+ const calculatedFee = calculateFee(
1236
+ Math.round(gasEstimation * multiplier),
1237
+ gasPrice
1238
+ );
1239
+ const grantFee: StdFee = {
1240
+ amount: calculatedFee.amount,
1241
+ gas: calculatedFee.gas,
1242
+ granter: this.apiSaasAddress,
1243
+ };
1244
+ return client.setRoundInfo(
1245
+ {
1246
+ contractAddr: contractAddress,
1247
+ roundInfo,
1248
+ },
1249
+ grantFee
1250
+ );
1251
+ } else if (gasStation && typeof fee === 'object') {
1252
+ // When gasStation is true and fee is StdFee, add granter
1253
+ const grantFee: StdFee = {
1254
+ ...fee,
1255
+ granter: this.apiSaasAddress,
1256
+ };
1257
+ return client.setRoundInfo(
1258
+ {
1259
+ contractAddr: contractAddress,
1260
+ roundInfo,
1261
+ },
1262
+ grantFee
1263
+ );
1264
+ }
1265
+
1266
+ return client.setRoundInfo(
1267
+ {
1268
+ contractAddr: contractAddress,
1269
+ roundInfo,
1270
+ },
1271
+ fee
1272
+ );
1273
+ }
1274
+
1275
+ async setApiSaasMaciRoundVoteOptions({
1276
+ signer,
1277
+ contractAddress,
1278
+ voteOptionMap,
1279
+ gasStation = false,
1280
+ fee = 1.8,
1281
+ }: {
1282
+ signer: OfflineSigner;
1283
+ contractAddress: string;
1284
+ voteOptionMap: string[];
1285
+ gasStation?: boolean;
1286
+ fee?: StdFee | 'auto' | number;
1287
+ }) {
1288
+ const client = await createApiSaasClientBy({
1289
+ rpcEndpoint: this.rpcEndpoint,
1290
+ wallet: signer,
1291
+ contractAddress: this.apiSaasAddress,
1292
+ });
1293
+
1294
+ if (gasStation && typeof fee !== 'object') {
1295
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1296
+ const [{ address }] = await signer.getAccounts();
1297
+ const contractClient = await this.contractClient({ signer });
1298
+ const msg = {
1299
+ set_vote_options_map: {
1300
+ contract_addr: contractAddress,
1301
+ vote_option_map: voteOptionMap,
1302
+ },
1303
+ };
1304
+ const gasEstimation = await contractClient.simulate(
1305
+ address,
1306
+ [
1307
+ {
1308
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1309
+ value: {
1310
+ sender: address,
1311
+ contract: this.apiSaasAddress,
1312
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1313
+ },
1314
+ },
1315
+ ],
1316
+ ''
1317
+ );
1318
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1319
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1320
+ const calculatedFee = calculateFee(
1321
+ Math.round(gasEstimation * multiplier),
1322
+ gasPrice
1323
+ );
1324
+ const grantFee: StdFee = {
1325
+ amount: calculatedFee.amount,
1326
+ gas: calculatedFee.gas,
1327
+ granter: this.apiSaasAddress,
1328
+ };
1329
+ return client.setVoteOptionsMap(
1330
+ {
1331
+ contractAddr: contractAddress,
1332
+ voteOptionMap,
1333
+ },
1334
+ grantFee
1335
+ );
1336
+ } else if (gasStation && typeof fee === 'object') {
1337
+ // When gasStation is true and fee is StdFee, add granter
1338
+ const grantFee: StdFee = {
1339
+ ...fee,
1340
+ granter: this.apiSaasAddress,
1341
+ };
1342
+ return client.setVoteOptionsMap(
1343
+ {
1344
+ contractAddr: contractAddress,
1345
+ voteOptionMap,
1346
+ },
1347
+ grantFee
1348
+ );
1349
+ }
1350
+
1351
+ return client.setVoteOptionsMap(
1352
+ {
1353
+ contractAddr: contractAddress,
1354
+ voteOptionMap,
1355
+ },
1356
+ fee
1357
+ );
1358
+ }
1359
+
1360
+ async addApiSaasOperator({
1361
+ signer,
1362
+ operator,
1363
+ gasStation = false,
1364
+ fee = 1.8,
1365
+ }: {
1366
+ signer: OfflineSigner;
1367
+ operator: string;
1368
+ gasStation?: boolean;
1369
+ fee?: StdFee | 'auto' | number;
1370
+ }) {
1371
+ const client = await createApiSaasClientBy({
1372
+ rpcEndpoint: this.rpcEndpoint,
1373
+ wallet: signer,
1374
+ contractAddress: this.apiSaasAddress,
1375
+ });
1376
+
1377
+ if (gasStation && typeof fee !== 'object') {
1378
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1379
+ const [{ address }] = await signer.getAccounts();
1380
+ const contractClient = await this.contractClient({ signer });
1381
+ const msg = {
1382
+ add_operator: {
1383
+ operator,
1384
+ },
1385
+ };
1386
+ const gasEstimation = await contractClient.simulate(
1387
+ address,
1388
+ [
1389
+ {
1390
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1391
+ value: {
1392
+ sender: address,
1393
+ contract: this.apiSaasAddress,
1394
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1395
+ },
1396
+ },
1397
+ ],
1398
+ ''
1399
+ );
1400
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1401
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1402
+ const calculatedFee = calculateFee(
1403
+ Math.round(gasEstimation * multiplier),
1404
+ gasPrice
1405
+ );
1406
+ const grantFee: StdFee = {
1407
+ amount: calculatedFee.amount,
1408
+ gas: calculatedFee.gas,
1409
+ granter: this.apiSaasAddress,
1410
+ };
1411
+ return client.addOperator({ operator }, grantFee);
1412
+ } else if (gasStation && typeof fee === 'object') {
1413
+ // When gasStation is true and fee is StdFee, add granter
1414
+ const grantFee: StdFee = {
1415
+ ...fee,
1416
+ granter: this.apiSaasAddress,
1417
+ };
1418
+ return client.addOperator({ operator }, grantFee);
1419
+ }
1420
+
1421
+ return client.addOperator({ operator }, fee);
1422
+ }
1423
+
1424
+ async removeApiSaasOperator({
1425
+ signer,
1426
+ operator,
1427
+ gasStation = false,
1428
+ fee = 1.8,
1429
+ }: {
1430
+ signer: OfflineSigner;
1431
+ operator: string;
1432
+ gasStation?: boolean;
1433
+ fee?: StdFee | 'auto' | number;
1434
+ }) {
1435
+ const client = await createApiSaasClientBy({
1436
+ rpcEndpoint: this.rpcEndpoint,
1437
+ wallet: signer,
1438
+ contractAddress: this.apiSaasAddress,
1439
+ });
1440
+
1441
+ if (gasStation && typeof fee !== 'object') {
1442
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1443
+ const [{ address }] = await signer.getAccounts();
1444
+ const contractClient = await this.contractClient({ signer });
1445
+ const msg = {
1446
+ remove_operator: {
1447
+ operator,
1448
+ },
1449
+ };
1450
+ const gasEstimation = await contractClient.simulate(
1451
+ address,
1452
+ [
1453
+ {
1454
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1455
+ value: {
1456
+ sender: address,
1457
+ contract: this.apiSaasAddress,
1458
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1459
+ },
1460
+ },
1461
+ ],
1462
+ ''
1463
+ );
1464
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1465
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1466
+ const calculatedFee = calculateFee(
1467
+ Math.round(gasEstimation * multiplier),
1468
+ gasPrice
1469
+ );
1470
+ const grantFee: StdFee = {
1471
+ amount: calculatedFee.amount,
1472
+ gas: calculatedFee.gas,
1473
+ granter: this.apiSaasAddress,
1474
+ };
1475
+ return client.removeOperator({ operator }, grantFee);
1476
+ } else if (gasStation && typeof fee === 'object') {
1477
+ // When gasStation is true and fee is StdFee, add granter
1478
+ const grantFee: StdFee = {
1479
+ ...fee,
1480
+ granter: this.apiSaasAddress,
1481
+ };
1482
+ return client.removeOperator({ operator }, grantFee);
1483
+ }
1484
+
1485
+ return client.removeOperator({ operator }, fee);
1486
+ }
1487
+
1488
+ async isApiSaasOperator({
1489
+ signer,
1490
+ operator,
1491
+ }: {
1492
+ signer: OfflineSigner;
1493
+ operator: string;
1494
+ }) {
1495
+ const client = await createApiSaasClientBy({
1496
+ rpcEndpoint: this.rpcEndpoint,
1497
+ wallet: signer,
1498
+ contractAddress: this.apiSaasAddress,
1499
+ });
1500
+ return client.isOperator({ address: operator });
1501
+ }
1502
+
1503
+ async createApiSaasAmaciRound({
1504
+ signer,
1505
+ operator,
1506
+ startVoting,
1507
+ endVoting,
1508
+ title,
1509
+ description,
1510
+ link,
1511
+ maxVoter,
1512
+ voteOptionMap,
1513
+ whitelist,
1514
+ voiceCreditAmount,
1515
+ preDeactivateRoot,
1516
+ oracleWhitelistPubkey,
1517
+ circuitType,
1518
+ gasStation = false,
1519
+ fee = 1.8,
1520
+ }: CreateApiSaasAmaciRoundParams & { signer: OfflineSigner }) {
1521
+ const startTime = (startVoting.getTime() * 1_000_000).toString();
1522
+ const endTime = (endVoting.getTime() * 1_000_000).toString();
1523
+
1524
+ const client = await createApiSaasClientBy({
1525
+ rpcEndpoint: this.rpcEndpoint,
1526
+ wallet: signer,
1527
+ contractAddress: this.apiSaasAddress,
1528
+ });
1529
+
1530
+ const roundParams = {
1531
+ certificationSystem: '0',
1532
+ circuitType: circuitType.toString(),
1533
+ maxVoter: maxVoter.toString(),
1534
+ operator,
1535
+ oracleWhitelistPubkey,
1536
+ preDeactivateRoot: preDeactivateRoot || '0',
1537
+ roundInfo: {
1538
+ title,
1539
+ description: description || '',
1540
+ link: link || '',
1541
+ },
1542
+ voiceCreditAmount,
1543
+ voteOptionMap,
1544
+ votingTime: {
1545
+ start_time: startTime,
1546
+ end_time: endTime,
1547
+ },
1548
+ whitelist,
1549
+ };
1550
+
1551
+ let createResponse;
1552
+
1553
+ if (gasStation && typeof fee !== 'object') {
1554
+ // When gasStation is true and fee is not StdFee, we need to simulate first then add granter
1555
+ const [{ address }] = await signer.getAccounts();
1556
+ const contractClient = await this.contractClient({ signer });
1557
+ const msg = {
1558
+ create_amaci_round: {
1559
+ certification_system: '0',
1560
+ circuit_type: circuitType.toString(),
1561
+ max_voter: maxVoter.toString(),
1562
+ operator,
1563
+ oracle_whitelist_pubkey: oracleWhitelistPubkey,
1564
+ pre_deactivate_root: preDeactivateRoot || '0',
1565
+ round_info: roundParams.roundInfo,
1566
+ voice_credit_amount: voiceCreditAmount,
1567
+ vote_option_map: voteOptionMap,
1568
+ voting_time: roundParams.votingTime,
1569
+ whitelist,
1570
+ },
1571
+ };
1572
+ const gasEstimation = await contractClient.simulate(
1573
+ address,
1574
+ [
1575
+ {
1576
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
1577
+ value: {
1578
+ sender: address,
1579
+ contract: this.apiSaasAddress,
1580
+ msg: new TextEncoder().encode(JSON.stringify(msg)),
1581
+ },
1582
+ },
1583
+ ],
1584
+ ''
1585
+ );
1586
+ const multiplier = typeof fee === 'number' ? fee : 1.8;
1587
+ const gasPrice = GasPrice.fromString('10000000000peaka');
1588
+ const calculatedFee = calculateFee(
1589
+ Math.round(gasEstimation * multiplier),
1590
+ gasPrice
1591
+ );
1592
+ const grantFee: StdFee = {
1593
+ amount: calculatedFee.amount,
1594
+ gas: calculatedFee.gas,
1595
+ granter: this.apiSaasAddress,
1596
+ };
1597
+ createResponse = await client.createAmaciRound(roundParams, grantFee);
1598
+ } else if (gasStation && typeof fee === 'object') {
1599
+ // When gasStation is true and fee is StdFee, add granter
1600
+ const grantFee: StdFee = {
1601
+ ...fee,
1602
+ granter: this.apiSaasAddress,
1603
+ };
1604
+ createResponse = await client.createAmaciRound(roundParams, grantFee);
1605
+ } else {
1606
+ createResponse = await client.createAmaciRound(roundParams, fee);
1607
+ }
1608
+
1609
+ let contractAddress = '';
1610
+ createResponse.events.map((event) => {
1611
+ if (event.type === 'wasm') {
1612
+ let actionEvent = event.attributes.find(
1613
+ (attr) => attr.key === 'action'
1614
+ );
1615
+ if (actionEvent && actionEvent.value === 'created_round') {
1616
+ const roundAddrEvent = event.attributes.find(
1617
+ (attr) => attr.key === 'round_addr'
1618
+ );
1619
+ if (roundAddrEvent) {
1620
+ contractAddress = roundAddrEvent.value.toString();
1621
+ }
1622
+ }
1623
+ }
1624
+ });
1625
+ return {
1626
+ ...createResponse,
1627
+ contractAddress,
1628
+ };
1629
+ }
1025
1630
  }