@dorafactory/maci-sdk 0.1.3-pre.46.beta.15 → 0.1.3-pre.46.beta.17

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 CHANGED
@@ -247,12 +247,19 @@ function handleError(error) {
247
247
  }
248
248
 
249
249
  // src/libs/http/http.ts
250
+ var DEFAULT_RETRIES = 5;
251
+ var DEFAULT_RETRY_DELAY = 200;
252
+ async function sleep(ms) {
253
+ return new Promise((resolve) => setTimeout(resolve, ms));
254
+ }
250
255
  var Http = class {
251
- constructor(apiEndpoint, restEndpoint, customFetch, defaultOptions) {
256
+ constructor(apiEndpoint, restEndpoints, customFetch, defaultOptions, retries, retryDelay) {
252
257
  this.customFetch = customFetch;
253
258
  this.apiEndpoint = apiEndpoint;
254
- this.restEndpoint = restEndpoint;
259
+ this.restEndpoints = Array.isArray(restEndpoints) ? restEndpoints : [restEndpoints];
255
260
  this.defaultOptions = defaultOptions;
261
+ this.retries = retries ?? DEFAULT_RETRIES;
262
+ this.retryDelay = retryDelay ?? DEFAULT_RETRY_DELAY;
256
263
  }
257
264
  getFetch() {
258
265
  return this.customFetch || fetch;
@@ -265,10 +272,7 @@ var Http = class {
265
272
  ...options
266
273
  });
267
274
  if (!response.ok) {
268
- throw new HttpError(
269
- `HTTP error! status: ${response.status}`,
270
- response.status
271
- );
275
+ throw new HttpError(`HTTP error! status: ${response.status}`, response.status);
272
276
  }
273
277
  return response;
274
278
  } catch (error) {
@@ -297,25 +301,16 @@ var Http = class {
297
301
  if (!response.ok) {
298
302
  const errorData = await response.json();
299
303
  if (errorData.errors?.[0]?.message?.includes("Syntax Error")) {
300
- throw new GraphQLError(
301
- `GraphQL syntax error: ${errorData.errors[0].message}`
302
- );
304
+ throw new GraphQLError(`GraphQL syntax error: ${errorData.errors[0].message}`);
303
305
  }
304
306
  if (errorData.errors?.length > 0) {
305
- throw new GraphQLError(
306
- errorData.errors[0].message || "Unknown GraphQL error"
307
- );
307
+ throw new GraphQLError(errorData.errors[0].message || "Unknown GraphQL error");
308
308
  }
309
- throw new HttpError(
310
- `HTTP error: ${JSON.stringify(errorData)}`,
311
- response.status
312
- );
309
+ throw new HttpError(`HTTP error: ${JSON.stringify(errorData)}`, response.status);
313
310
  }
314
311
  const data = await response.json();
315
312
  if (data.errors) {
316
- throw new GraphQLError(
317
- data.errors[0]?.message || "GraphQL query failed"
318
- );
313
+ throw new GraphQLError(data.errors[0]?.message || "GraphQL query failed");
319
314
  }
320
315
  return data;
321
316
  } catch (error) {
@@ -325,39 +320,51 @@ var Http = class {
325
320
  if (error instanceof SyntaxError) {
326
321
  throw new ParseError("Failed to parse JSON response");
327
322
  }
328
- throw new HttpError(
329
- `Failed to fetch GraphQL: ${error.message}`,
330
- 500
331
- );
323
+ throw new HttpError(`Failed to fetch GraphQL: ${error.message}`, 500);
332
324
  }
333
325
  }
334
326
  async fetchRest(path, options) {
335
- try {
336
- const fetchFn = this.getFetch();
337
- const response = await fetchFn(`${this.restEndpoint}${path}`, {
338
- ...this.defaultOptions,
339
- ...options
340
- });
341
- if (!response.ok) {
342
- throw new HttpError(
343
- `HTTP error! status: ${response.status}`,
344
- response.status
345
- );
346
- }
327
+ let lastError;
328
+ let restIndex = 0;
329
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
330
+ const endpoint = this.restEndpoints[restIndex];
347
331
  try {
348
- return await response.json();
332
+ const fetchFn = this.getFetch();
333
+ const response = await fetchFn(`${endpoint}${path}`, {
334
+ ...this.defaultOptions,
335
+ ...options
336
+ });
337
+ if (!response.ok) {
338
+ throw new HttpError(`HTTP error! status: ${response.status}`, response.status);
339
+ }
340
+ try {
341
+ return await response.json();
342
+ } catch {
343
+ throw new ParseError("Failed to parse JSON response");
344
+ }
349
345
  } catch (error) {
350
- throw new ParseError("Failed to parse JSON response");
351
- }
352
- } catch (error) {
353
- if (error instanceof BaseError) {
354
- throw error;
346
+ if (error instanceof HttpError && error.code >= 400 && error.code < 500) {
347
+ throw error;
348
+ }
349
+ lastError = error;
350
+ const nextIndex = (restIndex + 1) % this.restEndpoints.length;
351
+ const delay = this.retryDelay;
352
+ console.warn(
353
+ `[Http] REST request failed (attempt ${attempt + 1}/${this.retries + 1}) on ${endpoint}${path}: ${error?.message ?? error}` + (attempt < this.retries ? ` \u2014 retrying on ${this.restEndpoints[nextIndex]} in ${delay}ms` : " \u2014 all retries exhausted")
354
+ );
355
+ restIndex = nextIndex;
356
+ if (attempt < this.retries) {
357
+ await sleep(delay);
358
+ }
355
359
  }
356
- throw new HttpError(
357
- `Failed to fetch REST: ${error.message}`,
358
- 500
359
- );
360
360
  }
361
+ if (lastError instanceof BaseError) {
362
+ throw lastError;
363
+ }
364
+ throw new HttpError(
365
+ `Failed to fetch REST: ${lastError?.message ?? "unknown error"}`,
366
+ 500
367
+ );
361
368
  }
362
369
  async fetchAllGraphqlPages(query, variables) {
363
370
  let hasNextPage = true;
@@ -476,9 +483,9 @@ function getDefaultParams(network = "mainnet") {
476
483
  return {
477
484
  network: "mainnet",
478
485
  chainId: "vota-ash",
479
- rpcEndpoint: "https://vota-rpc.dorafactory.org",
480
- restEndpoint: "https://vota-rest.dorafactory.org",
481
- apiEndpoint: "https://vota-api.dorafactory.org",
486
+ rpcEndpoints: ["https://vota-rpc.dorafactory.org", "https://vota-archive-rpc.dorafactory.org"],
487
+ restEndpoints: ["https://vota-rest.dorafactory.org", "https://vota-archive-rest.dorafactory.org"],
488
+ apiEndpoint: "https://maci-graphql.dorafactory.org",
482
489
  saasApiEndpoint: "https://maci-xl-api.dorafactory.org",
483
490
  certificateApiEndpoint: "https://vota-certificate-api.dorafactory.org/api/v1",
484
491
  registryAddress: "dora1smg5qp5trjdkcekdjssqpjehdjf6n4cjss0clyvqcud3t3u3948s8rmgg4",
@@ -496,9 +503,9 @@ function getDefaultParams(network = "mainnet") {
496
503
  return {
497
504
  network: "testnet",
498
505
  chainId: "vota-testnet",
499
- rpcEndpoint: "https://vota-testnet-rpc.dorafactory.org",
500
- restEndpoint: "https://vota-testnet-rest.dorafactory.org",
501
- apiEndpoint: "https://vota-testnet-api.dorafactory.org",
506
+ rpcEndpoints: ["https://vota-testnet-rpc.dorafactory.org"],
507
+ restEndpoints: ["https://vota-testnet-rest.dorafactory.org"],
508
+ apiEndpoint: "https://maci-testnet-graphql.dorafactory.org",
502
509
  saasApiEndpoint: "https://maci-xl-testnet-api.dorafactory.org",
503
510
  certificateApiEndpoint: "https://vota-testnet-certificate-api.dorafactory.org/api/v1",
504
511
  registryAddress: "dora13c8aecstyxrhax9znvvh5zey89edrmd2k5va57pxvpe3fxtfsfeqlhsjnd",
@@ -1851,14 +1858,14 @@ var Operator = class {
1851
1858
  const ROUNDS_QUERY = `query {
1852
1859
  activeRoundsCount: rounds(filter: {
1853
1860
  period: {notEqualTo: "Ended"},
1854
- operator: {equalTo: "${operatorResponse.operatorAddress}"},
1861
+ operatorAddress: {equalTo: "${operatorResponse.operatorAddress}"},
1855
1862
  caller: {equalTo: "${this.amaciRegistryContract}"}
1856
1863
  }) {
1857
1864
  totalCount
1858
1865
  }
1859
1866
  completedRoundsCount: rounds(filter: {
1860
1867
  period: {equalTo: "Ended"},
1861
- operator: {equalTo: "${operatorResponse.operatorAddress}"},
1868
+ operatorAddress: {equalTo: "${operatorResponse.operatorAddress}"},
1862
1869
  caller: {equalTo: "${this.amaciRegistryContract}"}
1863
1870
  }) {
1864
1871
  totalCount
@@ -1923,10 +1930,9 @@ var Operator = class {
1923
1930
  delayReason
1924
1931
  delayType
1925
1932
  id
1926
- nodeId
1927
1933
  operatorAddress
1928
1934
  timestamp
1929
- roundAddress
1935
+ contractAddress
1930
1936
  }
1931
1937
  }
1932
1938
  }
@@ -2001,14 +2007,14 @@ var Operator = class {
2001
2007
  const ROUNDS_QUERY = `query {
2002
2008
  activeRoundsCount: rounds(filter: {
2003
2009
  period: {notEqualTo: "Ended"},
2004
- operator: {equalTo: "${operator.operatorAddress}"},
2010
+ operatorAddress: {equalTo: "${operator.operatorAddress}"},
2005
2011
  caller: {equalTo: "${this.amaciRegistryContract}"}
2006
2012
  }) {
2007
2013
  totalCount
2008
2014
  }
2009
2015
  completedRoundsCount: rounds(filter: {
2010
2016
  period: {equalTo: "Ended"},
2011
- operator: {equalTo: "${operator.operatorAddress}"},
2017
+ operatorAddress: {equalTo: "${operator.operatorAddress}"},
2012
2018
  caller: {equalTo: "${this.amaciRegistryContract}"}
2013
2019
  }) {
2014
2020
  totalCount
@@ -2084,10 +2090,9 @@ var Operator = class {
2084
2090
  delayReason
2085
2091
  delayType
2086
2092
  id
2087
- nodeId
2088
2093
  operatorAddress
2089
2094
  timestamp
2090
- roundAddress
2095
+ contractAddress
2091
2096
  }
2092
2097
  }
2093
2098
  }
@@ -2095,7 +2100,7 @@ var Operator = class {
2095
2100
  const ROUNDS_QUERY = `query ($limit: Int, $after: Cursor) {
2096
2101
  rounds(first: $limit, after: $after,
2097
2102
  filter: {
2098
- operator: {equalTo: "${address}"},
2103
+ operatorAddress: {equalTo: "${address}"},
2099
2104
  votingEnd: { greaterThanOrEqualTo: "${endNanosTimestamp}" }
2100
2105
  },
2101
2106
  orderBy: [TIMESTAMP_DESC]
@@ -2112,7 +2117,7 @@ var Operator = class {
2112
2117
  txHash
2113
2118
  caller
2114
2119
  admin
2115
- operator
2120
+ operatorAddress
2116
2121
  contractAddress
2117
2122
  circuitName
2118
2123
  timestamp
@@ -2304,7 +2309,7 @@ var Round = class {
2304
2309
  txHash
2305
2310
  caller
2306
2311
  admin
2307
- operator
2312
+ operatorAddress
2308
2313
  contractAddress
2309
2314
  circuitName
2310
2315
  timestamp
@@ -2332,7 +2337,9 @@ var Round = class {
2332
2337
  maciType
2333
2338
  voiceCreditAmount
2334
2339
  preDeactivateRoot
2335
- identity
2340
+ operator {
2341
+ identity
2342
+ }
2336
2343
  }
2337
2344
  }`;
2338
2345
  const response = await this.http.fetchGraphql(ROUND_QUERY, "");
@@ -2347,7 +2354,7 @@ var Round = class {
2347
2354
  }
2348
2355
  response.data.round.operatorLogoUrl = "";
2349
2356
  response.data.round.operatorMoniker = "";
2350
- const identity = response.data.round.identity;
2357
+ const identity = response.data.round.operator?.identity ?? "";
2351
2358
  const keybaseUrl = `https://keybase.io/_/api/1.0/user/lookup.json?key_suffix=${identity}`;
2352
2359
  const keybaseResponse = await this.http.fetch(keybaseUrl);
2353
2360
  const keybaseData = await keybaseResponse.json();
@@ -2393,7 +2400,7 @@ var Round = class {
2393
2400
  "txHash",
2394
2401
  "caller",
2395
2402
  "admin",
2396
- "operator",
2403
+ "operatorAddress",
2397
2404
  "contractAddress",
2398
2405
  "circuitName",
2399
2406
  "timestamp",
@@ -2420,8 +2427,7 @@ var Round = class {
2420
2427
  "codeId",
2421
2428
  "maciType",
2422
2429
  "voiceCreditAmount",
2423
- "preDeactivateRoot",
2424
- "identity"
2430
+ "preDeactivateRoot"
2425
2431
  // 'funds',
2426
2432
  ];
2427
2433
  if (fields && fields.length > 0) {
@@ -2477,7 +2483,7 @@ var Round = class {
2477
2483
  txHash
2478
2484
  caller
2479
2485
  admin
2480
- operator
2486
+ operatorAddress
2481
2487
  contractAddress
2482
2488
  circuitName
2483
2489
  timestamp
@@ -2554,7 +2560,7 @@ var Round = class {
2554
2560
  txHash
2555
2561
  caller
2556
2562
  admin
2557
- operator
2563
+ operatorAddress
2558
2564
  contractAddress
2559
2565
  circuitName
2560
2566
  timestamp
@@ -2669,7 +2675,7 @@ var Round = class {
2669
2675
  txHash
2670
2676
  caller
2671
2677
  admin
2672
- operator
2678
+ operatorAddress
2673
2679
  contractAddress
2674
2680
  circuitName
2675
2681
  timestamp
@@ -2736,7 +2742,7 @@ var Round = class {
2736
2742
  }
2737
2743
  const ROUND_HISTORY_QUERY = `query ($limit: Int!, $after: Cursor) {
2738
2744
  rounds(first: $limit, after: $after, filter:{
2739
- operator:{
2745
+ operatorAddress:{
2740
2746
  equalTo: "${operator}"
2741
2747
  }
2742
2748
  }, orderBy: [TIMESTAMP_DESC]){
@@ -2753,7 +2759,7 @@ var Round = class {
2753
2759
  txHash
2754
2760
  caller
2755
2761
  admin
2756
- operator
2762
+ operatorAddress
2757
2763
  contractAddress
2758
2764
  circuitName
2759
2765
  timestamp
@@ -3086,12 +3092,12 @@ query signUpEvents($limit: Int, $after: Cursor) {
3086
3092
  }
3087
3093
  async fetchAllDeactivateLogs(contractAddress) {
3088
3094
  const DEACTIVATE_MESSAGE_QUERY = `query ($limit: Int, $offset: Int) {
3089
- deactivateMessages(
3095
+ uploadedDeactivateMessages(
3090
3096
  first: $limit,
3091
3097
  offset: $offset,
3092
3098
  orderBy: [BLOCK_HEIGHT_ASC],
3093
3099
  filter: {
3094
- maciContractAddress: {
3100
+ contractAddress: {
3095
3101
  equalTo: "${contractAddress}"
3096
3102
  },
3097
3103
  }
@@ -3107,8 +3113,8 @@ query signUpEvents($limit: Int, $after: Cursor) {
3107
3113
  timestamp
3108
3114
  txHash
3109
3115
  deactivateMessage
3110
- maciContractAddress
3111
- maciOperator
3116
+ contractAddress
3117
+ operatorAddress
3112
3118
  }
3113
3119
  }
3114
3120
  }`;
@@ -4631,20 +4637,45 @@ var DEFAULT_DELAY_CONFIG = {
4631
4637
  };
4632
4638
 
4633
4639
  // src/libs/contract/contract.ts
4640
+ function toUtf8(str) {
4641
+ return new TextEncoder().encode(str);
4642
+ }
4643
+ var DEFAULT_GAS_PRICE = import_stargate2.GasPrice.fromString("10000000000peaka");
4644
+ var DEFAULT_RETRIES2 = 5;
4645
+ var DEFAULT_RETRY_DELAY2 = 200;
4646
+ async function sleep2(ms) {
4647
+ return new Promise((resolve) => setTimeout(resolve, ms));
4648
+ }
4649
+ async function resolveFee(signingClient, address, msgs, fee, granter) {
4650
+ let stdFee;
4651
+ if (typeof fee === "object") {
4652
+ stdFee = fee;
4653
+ } else {
4654
+ const multiplier = typeof fee === "number" ? fee : 1.8;
4655
+ const gasEstimation = await signingClient.simulate(address, msgs, "");
4656
+ stdFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), DEFAULT_GAS_PRICE);
4657
+ }
4658
+ if (granter) {
4659
+ return { ...stdFee, granter };
4660
+ }
4661
+ return stdFee;
4662
+ }
4634
4663
  var Contract = class {
4635
4664
  constructor({
4636
4665
  network,
4637
- rpcEndpoint,
4666
+ rpcEndpoints,
4638
4667
  registryAddress,
4639
4668
  saasAddress,
4640
4669
  apiSaasAddress,
4641
4670
  maciCodeId,
4642
4671
  oracleCodeId,
4643
4672
  feegrantOperator,
4644
- whitelistBackendPubkey
4673
+ whitelistBackendPubkey,
4674
+ retries,
4675
+ retryDelay
4645
4676
  }) {
4646
4677
  this.network = network;
4647
- this.rpcEndpoint = rpcEndpoint;
4678
+ this.rpcUrls = rpcEndpoints;
4648
4679
  this.registryAddress = registryAddress;
4649
4680
  this.saasAddress = saasAddress;
4650
4681
  this.apiSaasAddress = apiSaasAddress;
@@ -4652,106 +4683,79 @@ var Contract = class {
4652
4683
  this.oracleCodeId = oracleCodeId;
4653
4684
  this.feegrantOperator = feegrantOperator;
4654
4685
  this.whitelistBackendPubkey = whitelistBackendPubkey;
4686
+ this.retries = retries ?? DEFAULT_RETRIES2;
4687
+ this.retryDelay = retryDelay ?? DEFAULT_RETRY_DELAY2;
4655
4688
  }
4656
- async createAMaciRound(params) {
4657
- const { signer } = params;
4658
- const roundInfo = {
4659
- title: params.title,
4660
- description: params.description ?? "",
4661
- link: params.link ?? ""
4662
- };
4663
- const votingTime = {
4664
- start_time: (BigInt(params.startVoting.getTime()) * 1000000n).toString(),
4665
- end_time: (BigInt(params.endVoting.getTime()) * 1000000n).toString()
4666
- };
4667
- const client = await createRegistryClientBy({
4668
- rpcEndpoint: this.rpcEndpoint,
4669
- wallet: signer,
4670
- contractAddress: this.registryAddress
4671
- });
4672
- const fee = params.fee ?? "auto";
4673
- const res = await client.createRound(
4674
- {
4675
- certificationSystem: params.certificationSystem ?? "0",
4676
- circuitType: params.circuitType.toString(),
4677
- deactivateEnabled: params.deactivateEnabled,
4678
- operator: params.operator,
4679
- registrationMode: params.registrationMode,
4680
- roundInfo,
4681
- voiceCreditMode: params.voiceCreditMode,
4682
- voteOptionMap: params.voteOptionMap,
4683
- votingTime
4684
- },
4685
- fee,
4686
- void 0,
4687
- [{ denom: FEE_DENOM, amount: DEFAULT_BASE_FEE }]
4688
- );
4689
- let contractAddress = "";
4690
- let pollId = "";
4691
- for (const event of res.events) {
4692
- if (event.type === "wasm") {
4693
- const actionEvent = event.attributes.find(
4694
- (attr) => attr.key === "action"
4689
+ /**
4690
+ * Execute fn with primary-first multi-endpoint failover and exponential backoff retry.
4691
+ * Every call starts from rpcUrls[0] (primary). On failure the next endpoint is tried
4692
+ * in order, cycling back to the primary once all endpoints have been exhausted.
4693
+ * Retries only on connection-level errors; tx-level rejections fail fast.
4694
+ */
4695
+ async withRetry(fn) {
4696
+ let lastError;
4697
+ let urlIndex = 0;
4698
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
4699
+ const rpcEndpoint = this.rpcUrls[urlIndex];
4700
+ try {
4701
+ return await fn(rpcEndpoint);
4702
+ } catch (err) {
4703
+ if (err instanceof import_stargate2.BroadcastTxError) {
4704
+ throw err;
4705
+ }
4706
+ lastError = err;
4707
+ const nextIndex = (urlIndex + 1) % this.rpcUrls.length;
4708
+ const delay = this.retryDelay;
4709
+ console.warn(
4710
+ `[Contract] RPC request failed (attempt ${attempt + 1}/${this.retries + 1}) on ${rpcEndpoint}: ${err?.message ?? err}` + (attempt < this.retries ? ` \u2014 retrying on ${this.rpcUrls[nextIndex]} in ${delay}ms` : " \u2014 all retries exhausted")
4695
4711
  );
4696
- if (actionEvent && actionEvent.value === "created_round") {
4697
- const roundAddrEvent = event.attributes.find(
4698
- (attr) => attr.key === "round_addr"
4699
- );
4700
- const pollIdEvent = event.attributes.find(
4701
- (attr) => attr.key === "poll_id"
4702
- );
4703
- if (roundAddrEvent) {
4704
- contractAddress = roundAddrEvent.value.toString();
4705
- }
4706
- if (pollIdEvent) {
4707
- pollId = pollIdEvent.value.toString();
4708
- }
4709
- if (contractAddress) {
4710
- break;
4711
- }
4712
+ urlIndex = nextIndex;
4713
+ if (attempt < this.retries) {
4714
+ await sleep2(delay);
4712
4715
  }
4713
4716
  }
4714
4717
  }
4715
- return {
4716
- ...res,
4717
- contractAddress,
4718
- pollId
4719
- };
4718
+ throw lastError;
4720
4719
  }
4720
+ // ==================== Query Methods (unchanged) ====================
4721
4721
  async queryRoundInfo({ signer, roundAddress }) {
4722
- const client = await createAMaciClientBy({
4723
- rpcEndpoint: this.rpcEndpoint,
4724
- wallet: signer,
4725
- contractAddress: roundAddress
4722
+ return this.withRetry(async (rpcEndpoint) => {
4723
+ const client = await createAMaciQueryClientBy({ rpcEndpoint, contractAddress: roundAddress });
4724
+ return client.getRoundInfo();
4726
4725
  });
4727
- const roundInfo = await client.getRoundInfo();
4728
- return roundInfo;
4729
4726
  }
4730
4727
  async getStateIdx({
4731
4728
  contractAddress,
4732
4729
  pubkey
4733
4730
  }) {
4734
- const client = await createAMaciQueryClientBy({
4735
- rpcEndpoint: this.rpcEndpoint,
4736
- contractAddress
4731
+ return this.withRetry(async (rpcEndpoint) => {
4732
+ const client = await createAMaciQueryClientBy({ rpcEndpoint, contractAddress });
4733
+ return client.signuped({ pubkey });
4737
4734
  });
4738
- const stateIdx = await client.signuped({ pubkey });
4739
- return stateIdx;
4740
4735
  }
4741
4736
  async getPollId({ contractAddress }) {
4742
- const client = await createAMaciQueryClientBy({
4743
- rpcEndpoint: this.rpcEndpoint,
4744
- contractAddress
4737
+ return this.withRetry(async (rpcEndpoint) => {
4738
+ const client = await createAMaciQueryClientBy({ rpcEndpoint, contractAddress });
4739
+ return client.getPollId();
4740
+ });
4741
+ }
4742
+ async isApiSaasOperator({ signer, operator }) {
4743
+ return this.withRetry(async (rpcEndpoint) => {
4744
+ const client = await createApiSaasClientBy({
4745
+ rpcEndpoint,
4746
+ wallet: signer,
4747
+ contractAddress: this.apiSaasAddress
4748
+ });
4749
+ return client.isOperator({ address: operator });
4745
4750
  });
4746
- const pollId = await client.getPollId();
4747
- return pollId;
4748
4751
  }
4752
+ // ==================== Client Accessors ====================
4749
4753
  async registryClient({
4750
4754
  signer,
4751
4755
  contractAddress
4752
4756
  }) {
4753
4757
  return createRegistryClientBy({
4754
- rpcEndpoint: this.rpcEndpoint,
4758
+ rpcEndpoint: this.rpcUrls[0],
4755
4759
  wallet: signer,
4756
4760
  contractAddress
4757
4761
  });
@@ -4761,20 +4765,20 @@ var Contract = class {
4761
4765
  contractAddress
4762
4766
  }) {
4763
4767
  return createAMaciClientBy({
4764
- rpcEndpoint: this.rpcEndpoint,
4768
+ rpcEndpoint: this.rpcUrls[0],
4765
4769
  wallet: signer,
4766
4770
  contractAddress
4767
4771
  });
4768
4772
  }
4769
4773
  async amaciQueryClient({ contractAddress }) {
4770
4774
  return createAMaciQueryClientBy({
4771
- rpcEndpoint: this.rpcEndpoint,
4775
+ rpcEndpoint: this.rpcUrls[0],
4772
4776
  contractAddress
4773
4777
  });
4774
4778
  }
4775
4779
  async registryQueryClient() {
4776
4780
  return createRegistryQueryClientBy({
4777
- rpcEndpoint: this.rpcEndpoint,
4781
+ rpcEndpoint: this.rpcUrls[0],
4778
4782
  contractAddress: this.registryAddress
4779
4783
  });
4780
4784
  }
@@ -4783,13 +4787,53 @@ var Contract = class {
4783
4787
  contractAddress
4784
4788
  }) {
4785
4789
  return createApiSaasClientBy({
4786
- rpcEndpoint: this.rpcEndpoint,
4790
+ rpcEndpoint: this.rpcUrls[0],
4787
4791
  wallet: signer,
4788
4792
  contractAddress
4789
4793
  });
4790
4794
  }
4791
4795
  async contractClient({ signer }) {
4792
- return createContractClientByWallet(this.rpcEndpoint, signer);
4796
+ return createContractClientByWallet(this.rpcUrls[0], signer);
4797
+ }
4798
+ // ==================== Write Transaction Methods ====================
4799
+ async createAMaciRound(params) {
4800
+ const { signer } = params;
4801
+ return this.withRetry(async (rpcEndpoint) => {
4802
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
4803
+ const [{ address }] = await signer.getAccounts();
4804
+ const msg = {
4805
+ create_round: {
4806
+ certification_system: params.certificationSystem ?? "0",
4807
+ circuit_type: params.circuitType.toString(),
4808
+ deactivate_enabled: params.deactivateEnabled,
4809
+ operator: params.operator,
4810
+ registration_mode: params.registrationMode,
4811
+ round_info: {
4812
+ title: params.title,
4813
+ description: params.description ?? "",
4814
+ link: params.link ?? ""
4815
+ },
4816
+ voice_credit_mode: params.voiceCreditMode,
4817
+ vote_option_map: params.voteOptionMap,
4818
+ voting_time: {
4819
+ start_time: (BigInt(params.startVoting.getTime()) * 1000000n).toString(),
4820
+ end_time: (BigInt(params.endVoting.getTime()) * 1000000n).toString()
4821
+ }
4822
+ }
4823
+ };
4824
+ const executeMsg = {
4825
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4826
+ value: {
4827
+ sender: address,
4828
+ contract: this.registryAddress,
4829
+ msg: toUtf8(JSON.stringify(msg)),
4830
+ funds: [{ denom: FEE_DENOM, amount: DEFAULT_BASE_FEE }]
4831
+ }
4832
+ };
4833
+ const fee = await resolveFee(signingClient, address, [executeMsg], params.fee ?? "auto");
4834
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], fee);
4835
+ return { txHash };
4836
+ });
4793
4837
  }
4794
4838
  async setApiSaasMaciRoundInfo({
4795
4839
  signer,
@@ -4800,74 +4844,29 @@ var Contract = class {
4800
4844
  gasStation = false,
4801
4845
  fee = 1.8
4802
4846
  }) {
4803
- const client = await createApiSaasClientBy({
4804
- rpcEndpoint: this.rpcEndpoint,
4805
- wallet: signer,
4806
- contractAddress: this.apiSaasAddress
4807
- });
4808
- const roundInfo = {
4809
- title,
4810
- description,
4811
- link
4812
- };
4813
- if (gasStation && typeof fee !== "object") {
4847
+ return this.withRetry(async (rpcEndpoint) => {
4848
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
4814
4849
  const [{ address }] = await signer.getAccounts();
4815
- const contractClient = await this.contractClient({ signer });
4816
4850
  const msg = {
4817
4851
  set_round_info: {
4818
4852
  contract_addr: contractAddress,
4819
- round_info: roundInfo
4853
+ round_info: { title, description, link }
4820
4854
  }
4821
4855
  };
4822
- const gasEstimation = await contractClient.simulate(
4823
- address,
4824
- [
4825
- {
4826
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4827
- value: {
4828
- sender: address,
4829
- contract: this.apiSaasAddress,
4830
- msg: new TextEncoder().encode(JSON.stringify(msg))
4831
- }
4832
- }
4833
- ],
4834
- ""
4835
- );
4836
- const multiplier = typeof fee === "number" ? fee : 1.8;
4837
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
4838
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
4839
- const grantFee = {
4840
- amount: calculatedFee.amount,
4841
- gas: calculatedFee.gas,
4842
- granter: this.apiSaasAddress
4843
- };
4844
- return client.setRoundInfo(
4845
- {
4846
- contractAddr: contractAddress,
4847
- roundInfo
4848
- },
4849
- grantFee
4850
- );
4851
- } else if (gasStation && typeof fee === "object") {
4852
- const grantFee = {
4853
- ...fee,
4854
- granter: this.apiSaasAddress
4856
+ const executeMsg = {
4857
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4858
+ value: {
4859
+ sender: address,
4860
+ contract: this.apiSaasAddress,
4861
+ msg: toUtf8(JSON.stringify(msg)),
4862
+ funds: []
4863
+ }
4855
4864
  };
4856
- return client.setRoundInfo(
4857
- {
4858
- contractAddr: contractAddress,
4859
- roundInfo
4860
- },
4861
- grantFee
4862
- );
4863
- }
4864
- return client.setRoundInfo(
4865
- {
4866
- contractAddr: contractAddress,
4867
- roundInfo
4868
- },
4869
- fee
4870
- );
4865
+ const granter = gasStation ? this.apiSaasAddress : void 0;
4866
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
4867
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
4868
+ return { txHash };
4869
+ });
4871
4870
  }
4872
4871
  async setApiSaasMaciRoundVoteOptions({
4873
4872
  signer,
@@ -4876,69 +4875,29 @@ var Contract = class {
4876
4875
  gasStation = false,
4877
4876
  fee = 1.8
4878
4877
  }) {
4879
- const client = await createApiSaasClientBy({
4880
- rpcEndpoint: this.rpcEndpoint,
4881
- wallet: signer,
4882
- contractAddress: this.apiSaasAddress
4883
- });
4884
- if (gasStation && typeof fee !== "object") {
4878
+ return this.withRetry(async (rpcEndpoint) => {
4879
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
4885
4880
  const [{ address }] = await signer.getAccounts();
4886
- const contractClient = await this.contractClient({ signer });
4887
4881
  const msg = {
4888
4882
  set_vote_options_map: {
4889
4883
  contract_addr: contractAddress,
4890
4884
  vote_option_map: voteOptionMap
4891
4885
  }
4892
4886
  };
4893
- const gasEstimation = await contractClient.simulate(
4894
- address,
4895
- [
4896
- {
4897
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4898
- value: {
4899
- sender: address,
4900
- contract: this.apiSaasAddress,
4901
- msg: new TextEncoder().encode(JSON.stringify(msg))
4902
- }
4903
- }
4904
- ],
4905
- ""
4906
- );
4907
- const multiplier = typeof fee === "number" ? fee : 1.8;
4908
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
4909
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
4910
- const grantFee = {
4911
- amount: calculatedFee.amount,
4912
- gas: calculatedFee.gas,
4913
- granter: this.apiSaasAddress
4914
- };
4915
- return client.setVoteOptionsMap(
4916
- {
4917
- contractAddr: contractAddress,
4918
- voteOptionMap
4919
- },
4920
- grantFee
4921
- );
4922
- } else if (gasStation && typeof fee === "object") {
4923
- const grantFee = {
4924
- ...fee,
4925
- granter: this.apiSaasAddress
4887
+ const executeMsg = {
4888
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4889
+ value: {
4890
+ sender: address,
4891
+ contract: this.apiSaasAddress,
4892
+ msg: toUtf8(JSON.stringify(msg)),
4893
+ funds: []
4894
+ }
4926
4895
  };
4927
- return client.setVoteOptionsMap(
4928
- {
4929
- contractAddr: contractAddress,
4930
- voteOptionMap
4931
- },
4932
- grantFee
4933
- );
4934
- }
4935
- return client.setVoteOptionsMap(
4936
- {
4937
- contractAddr: contractAddress,
4938
- voteOptionMap
4939
- },
4940
- fee
4941
- );
4896
+ const granter = gasStation ? this.apiSaasAddress : void 0;
4897
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
4898
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
4899
+ return { txHash };
4900
+ });
4942
4901
  }
4943
4902
  async addApiSaasOperator({
4944
4903
  signer,
@@ -4946,50 +4905,24 @@ var Contract = class {
4946
4905
  gasStation = false,
4947
4906
  fee = 1.8
4948
4907
  }) {
4949
- const client = await createApiSaasClientBy({
4950
- rpcEndpoint: this.rpcEndpoint,
4951
- wallet: signer,
4952
- contractAddress: this.apiSaasAddress
4953
- });
4954
- if (gasStation && typeof fee !== "object") {
4908
+ return this.withRetry(async (rpcEndpoint) => {
4909
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
4955
4910
  const [{ address }] = await signer.getAccounts();
4956
- const contractClient = await this.contractClient({ signer });
4957
- const msg = {
4958
- add_operator: {
4959
- operator
4911
+ const msg = { add_operator: { operator } };
4912
+ const executeMsg = {
4913
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4914
+ value: {
4915
+ sender: address,
4916
+ contract: this.apiSaasAddress,
4917
+ msg: toUtf8(JSON.stringify(msg)),
4918
+ funds: []
4960
4919
  }
4961
4920
  };
4962
- const gasEstimation = await contractClient.simulate(
4963
- address,
4964
- [
4965
- {
4966
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4967
- value: {
4968
- sender: address,
4969
- contract: this.apiSaasAddress,
4970
- msg: new TextEncoder().encode(JSON.stringify(msg))
4971
- }
4972
- }
4973
- ],
4974
- ""
4975
- );
4976
- const multiplier = typeof fee === "number" ? fee : 1.8;
4977
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
4978
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
4979
- const grantFee = {
4980
- amount: calculatedFee.amount,
4981
- gas: calculatedFee.gas,
4982
- granter: this.apiSaasAddress
4983
- };
4984
- return client.addOperator({ operator }, grantFee);
4985
- } else if (gasStation && typeof fee === "object") {
4986
- const grantFee = {
4987
- ...fee,
4988
- granter: this.apiSaasAddress
4989
- };
4990
- return client.addOperator({ operator }, grantFee);
4991
- }
4992
- return client.addOperator({ operator }, fee);
4921
+ const granter = gasStation ? this.apiSaasAddress : void 0;
4922
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
4923
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
4924
+ return { txHash };
4925
+ });
4993
4926
  }
4994
4927
  async removeApiSaasOperator({
4995
4928
  signer,
@@ -4997,285 +4930,457 @@ var Contract = class {
4997
4930
  gasStation = false,
4998
4931
  fee = 1.8
4999
4932
  }) {
5000
- const client = await createApiSaasClientBy({
5001
- rpcEndpoint: this.rpcEndpoint,
5002
- wallet: signer,
5003
- contractAddress: this.apiSaasAddress
5004
- });
5005
- if (gasStation && typeof fee !== "object") {
4933
+ return this.withRetry(async (rpcEndpoint) => {
4934
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5006
4935
  const [{ address }] = await signer.getAccounts();
5007
- const contractClient = await this.contractClient({ signer });
5008
- const msg = {
5009
- remove_operator: {
5010
- operator
4936
+ const msg = { remove_operator: { operator } };
4937
+ const executeMsg = {
4938
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4939
+ value: {
4940
+ sender: address,
4941
+ contract: this.apiSaasAddress,
4942
+ msg: toUtf8(JSON.stringify(msg)),
4943
+ funds: []
5011
4944
  }
5012
4945
  };
5013
- const gasEstimation = await contractClient.simulate(
5014
- address,
5015
- [
5016
- {
5017
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5018
- value: {
5019
- sender: address,
5020
- contract: this.apiSaasAddress,
5021
- msg: new TextEncoder().encode(JSON.stringify(msg))
5022
- }
5023
- }
5024
- ],
5025
- ""
5026
- );
5027
- const multiplier = typeof fee === "number" ? fee : 1.8;
5028
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
5029
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5030
- const grantFee = {
5031
- amount: calculatedFee.amount,
5032
- gas: calculatedFee.gas,
5033
- granter: this.apiSaasAddress
5034
- };
5035
- return client.removeOperator({ operator }, grantFee);
5036
- } else if (gasStation && typeof fee === "object") {
5037
- const grantFee = {
5038
- ...fee,
5039
- granter: this.apiSaasAddress
5040
- };
5041
- return client.removeOperator({ operator }, grantFee);
5042
- }
5043
- return client.removeOperator({ operator }, fee);
5044
- }
5045
- async isApiSaasOperator({ signer, operator }) {
5046
- const client = await createApiSaasClientBy({
5047
- rpcEndpoint: this.rpcEndpoint,
5048
- wallet: signer,
5049
- contractAddress: this.apiSaasAddress
4946
+ const granter = gasStation ? this.apiSaasAddress : void 0;
4947
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
4948
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
4949
+ return { txHash };
5050
4950
  });
5051
- return client.isOperator({ address: operator });
5052
4951
  }
5053
4952
  async createApiSaasAmaciRound(params) {
5054
4953
  const { signer } = params;
5055
- const roundInfo = {
5056
- title: params.title,
5057
- description: params.description ?? "",
5058
- link: params.link ?? ""
5059
- };
5060
- const votingTime = {
5061
- start_time: (BigInt(params.startVoting.getTime()) * 1000000n).toString(),
5062
- end_time: (BigInt(params.endVoting.getTime()) * 1000000n).toString()
5063
- };
5064
- const circuitType = params.circuitType.toString();
5065
- const client = await createApiSaasClientBy({
5066
- rpcEndpoint: this.rpcEndpoint,
5067
- wallet: signer,
5068
- contractAddress: this.apiSaasAddress
5069
- });
5070
- const roundParams = {
5071
- certificationSystem: params.certificationSystem ?? "0",
5072
- circuitType,
5073
- deactivateEnabled: params.deactivateEnabled,
5074
- operator: params.operator,
5075
- registrationMode: params.registrationMode,
5076
- roundInfo,
5077
- voiceCreditMode: params.voiceCreditMode,
5078
- voteOptionMap: params.voteOptionMap,
5079
- votingTime
5080
- };
5081
- const gasStation = params.gasStation ?? false;
5082
- const fee = params.fee ?? 1.8;
5083
- let createResponse;
5084
- if (gasStation && typeof fee !== "object") {
4954
+ return this.withRetry(async (rpcEndpoint) => {
4955
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5085
4956
  const [{ address }] = await signer.getAccounts();
5086
- const contractClient = await this.contractClient({ signer });
5087
4957
  const msg = {
5088
4958
  create_amaci_round: {
5089
- certification_system: roundParams.certificationSystem,
5090
- circuit_type: roundParams.circuitType,
5091
- deactivate_enabled: roundParams.deactivateEnabled,
5092
- operator: roundParams.operator,
5093
- registration_mode: roundParams.registrationMode,
5094
- round_info: roundParams.roundInfo,
5095
- voice_credit_mode: roundParams.voiceCreditMode,
5096
- vote_option_map: roundParams.voteOptionMap,
5097
- voting_time: roundParams.votingTime
4959
+ certification_system: params.certificationSystem ?? "0",
4960
+ circuit_type: params.circuitType.toString(),
4961
+ deactivate_enabled: params.deactivateEnabled,
4962
+ operator: params.operator,
4963
+ registration_mode: params.registrationMode,
4964
+ round_info: {
4965
+ title: params.title,
4966
+ description: params.description ?? "",
4967
+ link: params.link ?? ""
4968
+ },
4969
+ voice_credit_mode: params.voiceCreditMode,
4970
+ vote_option_map: params.voteOptionMap,
4971
+ voting_time: {
4972
+ start_time: (BigInt(params.startVoting.getTime()) * 1000000n).toString(),
4973
+ end_time: (BigInt(params.endVoting.getTime()) * 1000000n).toString()
4974
+ }
4975
+ }
4976
+ };
4977
+ const executeMsg = {
4978
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
4979
+ value: {
4980
+ sender: address,
4981
+ contract: this.apiSaasAddress,
4982
+ msg: toUtf8(JSON.stringify(msg)),
4983
+ funds: []
5098
4984
  }
5099
4985
  };
5100
- const gasEstimation = await contractClient.simulate(
4986
+ const granter = params.gasStation ?? false ? this.apiSaasAddress : void 0;
4987
+ const stdFee = await resolveFee(
4988
+ signingClient,
5101
4989
  address,
5102
- [
5103
- {
5104
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5105
- value: {
5106
- sender: address,
5107
- contract: this.apiSaasAddress,
5108
- msg: new TextEncoder().encode(JSON.stringify(msg))
5109
- }
5110
- }
5111
- ],
5112
- ""
4990
+ [executeMsg],
4991
+ params.fee ?? 1.8,
4992
+ granter
5113
4993
  );
5114
- const multiplier = typeof fee === "number" ? fee : 1.8;
5115
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
5116
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5117
- const grantFee = {
5118
- amount: calculatedFee.amount,
5119
- gas: calculatedFee.gas,
5120
- granter: this.apiSaasAddress
5121
- };
5122
- createResponse = await client.createAmaciRound(roundParams, grantFee);
5123
- } else if (gasStation && typeof fee === "object") {
5124
- const grantFee = {
5125
- ...fee,
5126
- granter: this.apiSaasAddress
5127
- };
5128
- createResponse = await client.createAmaciRound(roundParams, grantFee);
5129
- } else {
5130
- createResponse = await client.createAmaciRound(roundParams, fee);
5131
- }
5132
- let contractAddress = "";
5133
- let pollId = "";
5134
- for (const event of createResponse.events) {
5135
- if (event.type === "wasm") {
5136
- const actionEvent = event.attributes.find(
5137
- (attr) => attr.key === "action"
5138
- );
5139
- if (actionEvent && actionEvent.value === "created_round") {
5140
- const roundAddrEvent = event.attributes.find(
5141
- (attr) => attr.key === "round_addr"
5142
- );
5143
- const pollIdEvent = event.attributes.find(
5144
- (attr) => attr.key === "poll_id"
5145
- );
5146
- if (roundAddrEvent) {
5147
- contractAddress = roundAddrEvent.value.toString();
5148
- }
5149
- if (pollIdEvent) {
5150
- pollId = pollIdEvent.value.toString();
5151
- }
5152
- if (contractAddress) {
5153
- break;
5154
- }
5155
- }
5156
- }
5157
- }
5158
- return {
5159
- ...createResponse,
5160
- contractAddress,
5161
- pollId
5162
- };
4994
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
4995
+ return { txHash };
4996
+ });
5163
4997
  }
5164
- async publishMessageViaSaas({
4998
+ async signupViaSaas({
5165
4999
  signer,
5166
5000
  contractAddress,
5167
- encPubKeys,
5168
- messages,
5001
+ pubkey,
5002
+ certificate,
5003
+ amount,
5169
5004
  granter,
5170
5005
  fee = 1.8
5171
5006
  }) {
5172
- const client = await createApiSaasClientBy({
5173
- rpcEndpoint: this.rpcEndpoint,
5174
- wallet: signer,
5175
- contractAddress: this.apiSaasAddress
5176
- });
5177
- const saasGranter = granter || this.apiSaasAddress;
5178
- if (typeof fee !== "object") {
5007
+ return this.withRetry(async (rpcEndpoint) => {
5008
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5179
5009
  const [{ address }] = await signer.getAccounts();
5180
- const contractClient = await this.contractClient({ signer });
5181
5010
  const msg = {
5182
- publish_message: {
5011
+ sign_up: {
5183
5012
  contract_addr: contractAddress,
5184
- enc_pub_keys: encPubKeys,
5185
- messages
5013
+ pubkey,
5014
+ certificate: certificate ?? null,
5015
+ amount: amount ?? null
5186
5016
  }
5187
5017
  };
5188
- const gasEstimation = await contractClient.simulate(
5189
- address,
5190
- [
5191
- {
5192
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5193
- value: {
5194
- sender: address,
5195
- contract: this.apiSaasAddress,
5196
- msg: new TextEncoder().encode(JSON.stringify(msg))
5197
- }
5198
- }
5199
- ],
5200
- ""
5201
- );
5202
- const multiplier = typeof fee === "number" ? fee : 1.8;
5203
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
5204
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5205
- const grantFee = {
5206
- amount: calculatedFee.amount,
5207
- gas: calculatedFee.gas,
5208
- granter: saasGranter
5209
- };
5210
- return client.publishMessage({ contractAddr: contractAddress, encPubKeys, messages }, grantFee);
5211
- } else {
5212
- const grantFee = {
5213
- ...fee,
5214
- granter: saasGranter
5018
+ const executeMsg = {
5019
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5020
+ value: {
5021
+ sender: address,
5022
+ contract: this.apiSaasAddress,
5023
+ msg: toUtf8(JSON.stringify(msg)),
5024
+ funds: []
5025
+ }
5215
5026
  };
5216
- return client.publishMessage({ contractAddr: contractAddress, encPubKeys, messages }, grantFee);
5217
- }
5027
+ const saasGranter = granter ?? this.apiSaasAddress;
5028
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, saasGranter);
5029
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5030
+ return { txHash };
5031
+ });
5218
5032
  }
5219
- async publishDeactivateMessageViaSaas({
5033
+ async preAddNewKeyViaSaas({
5220
5034
  signer,
5221
5035
  contractAddress,
5222
- encPubKey,
5223
- message,
5036
+ pubkey,
5037
+ nullifier,
5038
+ d,
5039
+ groth16Proof,
5224
5040
  granter,
5225
5041
  fee = 1.8
5226
5042
  }) {
5227
- const client = await createApiSaasClientBy({
5228
- rpcEndpoint: this.rpcEndpoint,
5229
- wallet: signer,
5230
- contractAddress: this.apiSaasAddress
5231
- });
5232
- const saasGranter = granter || this.apiSaasAddress;
5233
- if (typeof fee !== "object") {
5043
+ return this.withRetry(async (rpcEndpoint) => {
5044
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5234
5045
  const [{ address }] = await signer.getAccounts();
5235
- const contractClient = await this.contractClient({ signer });
5236
5046
  const msg = {
5237
- publish_deactivate_message: {
5047
+ pre_add_new_key: {
5238
5048
  contract_addr: contractAddress,
5239
- enc_pub_key: encPubKey,
5240
- message
5049
+ pubkey,
5050
+ nullifier,
5051
+ d,
5052
+ groth16_proof: groth16Proof
5241
5053
  }
5242
5054
  };
5243
- const gasEstimation = await contractClient.simulate(
5244
- address,
5245
- [
5246
- {
5247
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5248
- value: {
5249
- sender: address,
5250
- contract: this.apiSaasAddress,
5251
- msg: new TextEncoder().encode(JSON.stringify(msg))
5252
- }
5253
- }
5254
- ],
5255
- ""
5256
- );
5257
- const multiplier = typeof fee === "number" ? fee : 1.8;
5258
- const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
5259
- const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5260
- const grantFee = {
5261
- amount: calculatedFee.amount,
5262
- gas: calculatedFee.gas,
5263
- granter: saasGranter
5055
+ const executeMsg = {
5056
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5057
+ value: {
5058
+ sender: address,
5059
+ contract: this.apiSaasAddress,
5060
+ msg: toUtf8(JSON.stringify(msg)),
5061
+ funds: []
5062
+ }
5264
5063
  };
5265
- return client.publishDeactivateMessage(
5266
- { contractAddr: contractAddress, encPubKey, message },
5267
- grantFee
5268
- );
5269
- } else {
5270
- const grantFee = {
5271
- ...fee,
5272
- granter: saasGranter
5064
+ const saasGranter = granter ?? this.apiSaasAddress;
5065
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, saasGranter);
5066
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5067
+ return { txHash };
5068
+ });
5069
+ }
5070
+ async preAddNewKey({
5071
+ signer,
5072
+ contractAddress,
5073
+ pubkey,
5074
+ nullifier,
5075
+ d,
5076
+ groth16Proof,
5077
+ granter,
5078
+ funds = [],
5079
+ fee = "auto"
5080
+ }) {
5081
+ return this.withRetry(async (rpcEndpoint) => {
5082
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5083
+ const [{ address }] = await signer.getAccounts();
5084
+ const msg = {
5085
+ pre_add_new_key: {
5086
+ d,
5087
+ groth16_proof: groth16Proof,
5088
+ nullifier,
5089
+ pubkey
5090
+ }
5273
5091
  };
5274
- return client.publishDeactivateMessage(
5275
- { contractAddr: contractAddress, encPubKey, message },
5276
- grantFee
5277
- );
5278
- }
5092
+ const executeMsg = {
5093
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5094
+ value: {
5095
+ sender: address,
5096
+ contract: contractAddress,
5097
+ msg: toUtf8(JSON.stringify(msg)),
5098
+ funds
5099
+ }
5100
+ };
5101
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
5102
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5103
+ return { txHash };
5104
+ });
5105
+ }
5106
+ async addNewKeyViaSaas({
5107
+ signer,
5108
+ contractAddress,
5109
+ pubkey,
5110
+ nullifier,
5111
+ d,
5112
+ groth16Proof,
5113
+ granter,
5114
+ fee = 1.8
5115
+ }) {
5116
+ return this.withRetry(async (rpcEndpoint) => {
5117
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5118
+ const [{ address }] = await signer.getAccounts();
5119
+ const msg = {
5120
+ add_new_key: {
5121
+ contract_addr: contractAddress,
5122
+ pubkey,
5123
+ nullifier,
5124
+ d,
5125
+ groth16_proof: groth16Proof
5126
+ }
5127
+ };
5128
+ const executeMsg = {
5129
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5130
+ value: {
5131
+ sender: address,
5132
+ contract: this.apiSaasAddress,
5133
+ msg: toUtf8(JSON.stringify(msg)),
5134
+ funds: []
5135
+ }
5136
+ };
5137
+ const saasGranter = granter ?? this.apiSaasAddress;
5138
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, saasGranter);
5139
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5140
+ return { txHash };
5141
+ });
5142
+ }
5143
+ async publishMessageViaSaas({
5144
+ signer,
5145
+ contractAddress,
5146
+ encPubKeys,
5147
+ messages,
5148
+ granter,
5149
+ fee = 1.8
5150
+ }) {
5151
+ return this.withRetry(async (rpcEndpoint) => {
5152
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5153
+ const [{ address }] = await signer.getAccounts();
5154
+ const msg = {
5155
+ publish_message: {
5156
+ contract_addr: contractAddress,
5157
+ enc_pub_keys: encPubKeys,
5158
+ messages
5159
+ }
5160
+ };
5161
+ const executeMsg = {
5162
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5163
+ value: {
5164
+ sender: address,
5165
+ contract: this.apiSaasAddress,
5166
+ msg: toUtf8(JSON.stringify(msg)),
5167
+ funds: []
5168
+ }
5169
+ };
5170
+ const saasGranter = granter ?? this.apiSaasAddress;
5171
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, saasGranter);
5172
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5173
+ return { txHash };
5174
+ });
5175
+ }
5176
+ async publishDeactivateMessageViaSaas({
5177
+ signer,
5178
+ contractAddress,
5179
+ encPubKey,
5180
+ message,
5181
+ granter,
5182
+ fee = 1.8
5183
+ }) {
5184
+ return this.withRetry(async (rpcEndpoint) => {
5185
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5186
+ const [{ address }] = await signer.getAccounts();
5187
+ const msg = {
5188
+ publish_deactivate_message: {
5189
+ contract_addr: contractAddress,
5190
+ enc_pub_key: encPubKey,
5191
+ message
5192
+ }
5193
+ };
5194
+ const executeMsg = {
5195
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5196
+ value: {
5197
+ sender: address,
5198
+ contract: this.apiSaasAddress,
5199
+ msg: toUtf8(JSON.stringify(msg)),
5200
+ funds: []
5201
+ }
5202
+ };
5203
+ const saasGranter = granter ?? this.apiSaasAddress;
5204
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, saasGranter);
5205
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5206
+ return { txHash };
5207
+ });
5208
+ }
5209
+ // ── Direct (non-SAAS) write methods ──────────────────────────────────────
5210
+ async signup({
5211
+ signer,
5212
+ contractAddress,
5213
+ pubkey,
5214
+ amount = "0",
5215
+ certificate = "",
5216
+ granter,
5217
+ funds = [],
5218
+ fee = "auto"
5219
+ }) {
5220
+ return this.withRetry(async (rpcEndpoint) => {
5221
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5222
+ const [{ address }] = await signer.getAccounts();
5223
+ const msg = {
5224
+ sign_up: {
5225
+ pubkey,
5226
+ amount,
5227
+ certificate
5228
+ }
5229
+ };
5230
+ const executeMsg = {
5231
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5232
+ value: {
5233
+ sender: address,
5234
+ contract: contractAddress,
5235
+ msg: toUtf8(JSON.stringify(msg)),
5236
+ funds
5237
+ }
5238
+ };
5239
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
5240
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5241
+ return { txHash };
5242
+ });
5243
+ }
5244
+ async addNewKey({
5245
+ signer,
5246
+ contractAddress,
5247
+ pubkey,
5248
+ nullifier,
5249
+ d,
5250
+ groth16Proof,
5251
+ granter,
5252
+ funds = [],
5253
+ fee = "auto"
5254
+ }) {
5255
+ return this.withRetry(async (rpcEndpoint) => {
5256
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5257
+ const [{ address }] = await signer.getAccounts();
5258
+ const msg = {
5259
+ add_new_key: {
5260
+ d,
5261
+ groth16_proof: groth16Proof,
5262
+ nullifier,
5263
+ pubkey
5264
+ }
5265
+ };
5266
+ const executeMsg = {
5267
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5268
+ value: {
5269
+ sender: address,
5270
+ contract: contractAddress,
5271
+ msg: toUtf8(JSON.stringify(msg)),
5272
+ funds
5273
+ }
5274
+ };
5275
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
5276
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5277
+ return { txHash };
5278
+ });
5279
+ }
5280
+ async publishMessage({
5281
+ signer,
5282
+ contractAddress,
5283
+ encPubKeys,
5284
+ messages,
5285
+ granter,
5286
+ funds = [],
5287
+ fee = "auto"
5288
+ }) {
5289
+ return this.withRetry(async (rpcEndpoint) => {
5290
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5291
+ const [{ address }] = await signer.getAccounts();
5292
+ const msg = {
5293
+ publish_message: {
5294
+ enc_pub_keys: encPubKeys,
5295
+ messages
5296
+ }
5297
+ };
5298
+ const executeMsg = {
5299
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5300
+ value: {
5301
+ sender: address,
5302
+ contract: contractAddress,
5303
+ msg: toUtf8(JSON.stringify(msg)),
5304
+ funds
5305
+ }
5306
+ };
5307
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
5308
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5309
+ return { txHash };
5310
+ });
5311
+ }
5312
+ /**
5313
+ * Generic execute with retry – used for the legacy publish_message_batch format
5314
+ * where the caller pre-builds the EncodeObject (e.g. with stringizing).
5315
+ */
5316
+ async executeWithRetry({
5317
+ signer,
5318
+ address,
5319
+ msgs,
5320
+ granter,
5321
+ fee = "auto"
5322
+ }) {
5323
+ return this.withRetry(async (rpcEndpoint) => {
5324
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5325
+ const stdFee = await resolveFee(signingClient, address, msgs, fee, granter);
5326
+ const txHash = await signingClient.signAndBroadcastSync(address, msgs, stdFee);
5327
+ return { txHash };
5328
+ });
5329
+ }
5330
+ async publishDeactivateMessage({
5331
+ signer,
5332
+ contractAddress,
5333
+ encPubKey,
5334
+ message,
5335
+ granter,
5336
+ funds = [],
5337
+ fee = "auto"
5338
+ }) {
5339
+ return this.withRetry(async (rpcEndpoint) => {
5340
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5341
+ const [{ address }] = await signer.getAccounts();
5342
+ const msg = {
5343
+ publish_deactivate_message: {
5344
+ enc_pub_key: encPubKey,
5345
+ message
5346
+ }
5347
+ };
5348
+ const executeMsg = {
5349
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5350
+ value: {
5351
+ sender: address,
5352
+ contract: contractAddress,
5353
+ msg: toUtf8(JSON.stringify(msg)),
5354
+ funds
5355
+ }
5356
+ };
5357
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, granter);
5358
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5359
+ return { txHash };
5360
+ });
5361
+ }
5362
+ async claim({
5363
+ signer,
5364
+ contractAddress,
5365
+ funds = [],
5366
+ fee = "auto"
5367
+ }) {
5368
+ return this.withRetry(async (rpcEndpoint) => {
5369
+ const signingClient = await createContractClientByWallet(rpcEndpoint, signer);
5370
+ const [{ address }] = await signer.getAccounts();
5371
+ const executeMsg = {
5372
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5373
+ value: {
5374
+ sender: address,
5375
+ contract: contractAddress,
5376
+ msg: toUtf8(JSON.stringify({ claim: {} })),
5377
+ funds
5378
+ }
5379
+ };
5380
+ const stdFee = await resolveFee(signingClient, address, [executeMsg], fee, void 0);
5381
+ const txHash = await signingClient.signAndBroadcastSync(address, [executeMsg], stdFee);
5382
+ return { txHash };
5383
+ });
5279
5384
  }
5280
5385
  };
5281
5386
 
@@ -5374,7 +5479,6 @@ var OracleCertificate = class {
5374
5479
  };
5375
5480
 
5376
5481
  // src/libs/maci/maci.ts
5377
- var import_stargate3 = require("@cosmjs/stargate");
5378
5482
  var import_tx = require("cosmjs-types/cosmwasm/wasm/v1/tx.js");
5379
5483
  function isErrorResponse(response) {
5380
5484
  return typeof response === "object" && response !== null && "error" in response && typeof response.error === "object" && "message" in response.error;
@@ -5621,7 +5725,6 @@ var MACI = class {
5621
5725
  }
5622
5726
  async signup({
5623
5727
  signer,
5624
- address,
5625
5728
  contractAddress,
5626
5729
  maciKeypair,
5627
5730
  oracleCertificate,
@@ -5629,66 +5732,30 @@ var MACI = class {
5629
5732
  fee
5630
5733
  }) {
5631
5734
  try {
5632
- if (!address) {
5633
- address = (await signer.getAccounts())[0].address;
5634
- }
5635
5735
  if (maciKeypair === void 0) {
5636
5736
  maciKeypair = this.maciKeypair;
5637
5737
  }
5638
- const client = await this.contract.contractClient({
5639
- signer
5640
- });
5641
- const msg = {
5642
- sign_up: {
5643
- pubkey: {
5644
- x: maciKeypair.pubKey[0].toString(),
5645
- y: maciKeypair.pubKey[1].toString()
5646
- },
5647
- amount: oracleCertificate?.amount || "0",
5648
- certificate: oracleCertificate?.signature || ""
5649
- }
5650
- };
5651
5738
  const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
5652
- if (gasStation === true && typeof fee !== "object") {
5653
- const gasEstimation = await client.simulate(
5654
- address,
5655
- [
5656
- {
5657
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5658
- value: {
5659
- sender: address,
5660
- contract: contractAddress,
5661
- msg: new TextEncoder().encode(JSON.stringify(msg)),
5662
- funds: signupFunds
5663
- }
5664
- }
5665
- ],
5666
- ""
5667
- );
5668
- const multiplier = typeof fee === "number" ? fee : 1.8;
5669
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
5670
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5671
- const grantFee = {
5672
- amount: calculatedFee.amount,
5673
- gas: calculatedFee.gas,
5674
- granter: contractAddress
5675
- };
5676
- return client.execute(address, contractAddress, msg, grantFee, void 0, signupFunds);
5677
- } else if (gasStation === true && typeof fee === "object") {
5678
- const grantFee = {
5679
- ...fee,
5680
- granter: contractAddress
5681
- };
5682
- return client.execute(address, contractAddress, msg, grantFee, void 0, signupFunds);
5683
- }
5684
- return client.execute(address, contractAddress, msg, fee || "auto", void 0, signupFunds);
5739
+ const granter = gasStation ? contractAddress : void 0;
5740
+ return await this.contract.signup({
5741
+ signer,
5742
+ contractAddress,
5743
+ pubkey: {
5744
+ x: maciKeypair.pubKey[0].toString(),
5745
+ y: maciKeypair.pubKey[1].toString()
5746
+ },
5747
+ amount: oracleCertificate?.amount ?? "0",
5748
+ certificate: oracleCertificate?.signature ?? "",
5749
+ granter,
5750
+ funds: signupFunds,
5751
+ fee: fee ?? "auto"
5752
+ });
5685
5753
  } catch (error) {
5686
5754
  throw Error(`Signup failed! ${error}`);
5687
5755
  }
5688
5756
  }
5689
5757
  async rawSignup({
5690
5758
  signer,
5691
- address,
5692
5759
  contractAddress,
5693
5760
  pubKey,
5694
5761
  oracleCertificate,
@@ -5696,60 +5763,35 @@ var MACI = class {
5696
5763
  granter,
5697
5764
  fee
5698
5765
  }) {
5699
- try {
5700
- if (!address) {
5701
- address = (await signer.getAccounts())[0].address;
5702
- }
5703
- const client = await this.contract.contractClient({
5704
- signer
5766
+ const pubkey = {
5767
+ x: pubKey[0].toString(),
5768
+ y: pubKey[1].toString()
5769
+ };
5770
+ const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
5771
+ if (gasStation === true && granter === this.contract.apiSaasAddress) {
5772
+ console.log("[rawSignup] path: viaSaas (gasStation=true, granter=apiSaasAddress)");
5773
+ return this.contract.signupViaSaas({
5774
+ signer,
5775
+ contractAddress,
5776
+ pubkey,
5777
+ certificate: oracleCertificate?.signature,
5778
+ amount: oracleCertificate?.amount,
5779
+ granter,
5780
+ fee
5705
5781
  });
5706
- const msg = {
5707
- sign_up: {
5708
- pubkey: {
5709
- x: pubKey[0].toString(),
5710
- y: pubKey[1].toString()
5711
- },
5712
- amount: oracleCertificate?.amount || "0",
5713
- certificate: oracleCertificate?.signature || ""
5714
- }
5715
- };
5716
- const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
5717
- if (gasStation === true && typeof fee !== "object") {
5718
- const gasEstimation = await client.simulate(
5719
- address,
5720
- [
5721
- {
5722
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5723
- value: {
5724
- sender: address,
5725
- contract: contractAddress,
5726
- msg: new TextEncoder().encode(JSON.stringify(msg)),
5727
- funds: signupFunds
5728
- }
5729
- }
5730
- ],
5731
- ""
5732
- );
5733
- const multiplier = typeof fee === "number" ? fee : 1.8;
5734
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
5735
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5736
- const grantFee = {
5737
- amount: calculatedFee.amount,
5738
- gas: calculatedFee.gas,
5739
- granter: granter || contractAddress
5740
- };
5741
- return client.execute(address, contractAddress, msg, grantFee, void 0, signupFunds);
5742
- } else if (gasStation === true && typeof fee === "object") {
5743
- const grantFee = {
5744
- ...fee,
5745
- granter: granter || contractAddress
5746
- };
5747
- return client.execute(address, contractAddress, msg, grantFee, void 0, signupFunds);
5748
- }
5749
- return client.execute(address, contractAddress, msg, fee || "auto", void 0, signupFunds);
5750
- } catch (error) {
5751
- throw Error(`Signup failed! ${error}`);
5752
5782
  }
5783
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
5784
+ console.log(`[rawSignup] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`);
5785
+ return this.contract.signup({
5786
+ signer,
5787
+ contractAddress,
5788
+ pubkey,
5789
+ amount: oracleCertificate?.amount ?? "0",
5790
+ certificate: oracleCertificate?.signature ?? "",
5791
+ granter: effectiveGranter,
5792
+ funds: signupFunds,
5793
+ fee: fee ?? "auto"
5794
+ });
5753
5795
  }
5754
5796
  async processVoteOptions({
5755
5797
  selectedOptions,
@@ -5848,15 +5890,34 @@ var MACI = class {
5848
5890
  fee
5849
5891
  });
5850
5892
  }
5851
- const client = await this.contract.contractClient({
5852
- signer
5853
- });
5854
- return await this.publishMessage({
5855
- client,
5893
+ if (!address) {
5894
+ address = (await signer.getAccounts())[0].address;
5895
+ }
5896
+ const totalFee = (BigInt(this.feeConfig.messageFee) * BigInt(payload.length)).toString();
5897
+ const legacyMsgs = payload.map(({ msg, encPubkeys }) => ({
5898
+ typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5899
+ value: import_tx.MsgExecuteContract.fromPartial({
5900
+ sender: address,
5901
+ contract: contractAddress,
5902
+ msg: new TextEncoder().encode(
5903
+ JSON.stringify(
5904
+ stringizing({
5905
+ publish_message: {
5906
+ messages: [{ data: msg }],
5907
+ enc_pub_keys: [{ x: encPubkeys[0], y: encPubkeys[1] }]
5908
+ }
5909
+ })
5910
+ )
5911
+ ),
5912
+ funds: [{ denom: FEE_DENOM, amount: this.feeConfig.messageFee }]
5913
+ })
5914
+ }));
5915
+ const granter = gasStation ? contractAddress : void 0;
5916
+ return await this.contract.executeWithRetry({
5917
+ signer,
5856
5918
  address,
5857
- payload,
5858
- contractAddress,
5859
- gasStation,
5919
+ msgs: legacyMsgs,
5920
+ granter,
5860
5921
  fee
5861
5922
  });
5862
5923
  } catch (error) {
@@ -5902,7 +5963,7 @@ var MACI = class {
5902
5963
  }
5903
5964
  }
5904
5965
  async publishMessage({
5905
- client,
5966
+ signer,
5906
5967
  address,
5907
5968
  payload,
5908
5969
  contractAddress,
@@ -5910,7 +5971,10 @@ var MACI = class {
5910
5971
  granter,
5911
5972
  fee = 1.8
5912
5973
  }) {
5913
- const msgs = payload.map(({ msg, encPubkeys }) => ({
5974
+ if (!address) {
5975
+ address = (await signer.getAccounts())[0].address;
5976
+ }
5977
+ const legacyMsgs = payload.map(({ msg, encPubkeys }) => ({
5914
5978
  typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5915
5979
  value: import_tx.MsgExecuteContract.fromPartial({
5916
5980
  sender: address,
@@ -5928,25 +5992,8 @@ var MACI = class {
5928
5992
  funds: [{ denom: FEE_DENOM, amount: this.feeConfig.messageFee }]
5929
5993
  })
5930
5994
  }));
5931
- if (gasStation && typeof fee !== "object") {
5932
- const gasEstimation = await client.simulate(address, msgs, "");
5933
- const multiplier = typeof fee === "number" ? fee : 1.8;
5934
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
5935
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
5936
- const grantFee = {
5937
- amount: calculatedFee.amount,
5938
- gas: calculatedFee.gas,
5939
- granter: granter || contractAddress
5940
- };
5941
- return client.signAndBroadcast(address, msgs, grantFee);
5942
- } else if (gasStation && typeof fee === "object") {
5943
- const grantFee = {
5944
- ...fee,
5945
- granter: granter || contractAddress
5946
- };
5947
- return client.signAndBroadcast(address, msgs, grantFee);
5948
- }
5949
- return client.signAndBroadcast(address, msgs, fee);
5995
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
5996
+ return this.contract.executeWithRetry({ signer, address, msgs: legacyMsgs, granter: effectiveGranter, fee });
5950
5997
  }
5951
5998
  async publishMessageBatch({
5952
5999
  signer,
@@ -5960,10 +6007,6 @@ var MACI = class {
5960
6007
  if (!address) {
5961
6008
  address = (await signer.getAccounts())[0].address;
5962
6009
  }
5963
- const amaciClient = await this.contract.amaciClient({
5964
- signer,
5965
- contractAddress
5966
- });
5967
6010
  const messages = payload.map((p) => ({
5968
6011
  data: p.msg.map((m) => m.toString())
5969
6012
  }));
@@ -5974,6 +6017,7 @@ var MACI = class {
5974
6017
  const totalFee = (BigInt(this.feeConfig.messageFee) * BigInt(payload.length)).toString();
5975
6018
  const batchFunds = [{ denom: FEE_DENOM, amount: totalFee }];
5976
6019
  if (gasStation && granter === this.contract.apiSaasAddress) {
6020
+ console.log("[publishMessageBatch] path: viaSaas (gasStation=true, granter=apiSaasAddress)");
5977
6021
  return this.contract.publishMessageViaSaas({
5978
6022
  signer,
5979
6023
  contractAddress,
@@ -5982,37 +6026,20 @@ var MACI = class {
5982
6026
  granter,
5983
6027
  fee
5984
6028
  });
5985
- } else if (gasStation && typeof fee !== "object") {
5986
- const client = await this.contract.contractClient({ signer });
5987
- const msgForSimulate = {
5988
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
5989
- value: import_tx.MsgExecuteContract.fromPartial({
5990
- sender: address,
5991
- contract: contractAddress,
5992
- msg: new TextEncoder().encode(
5993
- JSON.stringify({ publish_message: { enc_pub_keys: encPubKeys, messages } })
5994
- ),
5995
- funds: batchFunds
5996
- })
5997
- };
5998
- const gasEstimation = await client.simulate(address, [msgForSimulate], "");
5999
- const multiplier = typeof fee === "number" ? fee : 1.8;
6000
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6001
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6002
- const grantFee = {
6003
- amount: calculatedFee.amount,
6004
- gas: calculatedFee.gas,
6005
- granter: granter || contractAddress
6006
- };
6007
- return amaciClient.publishMessage({ encPubKeys, messages }, grantFee, void 0, batchFunds);
6008
- } else if (gasStation && typeof fee === "object") {
6009
- const grantFee = {
6010
- ...fee,
6011
- granter: granter || contractAddress
6012
- };
6013
- return amaciClient.publishMessage({ encPubKeys, messages }, grantFee, void 0, batchFunds);
6014
6029
  }
6015
- return amaciClient.publishMessage({ encPubKeys, messages }, fee, void 0, batchFunds);
6030
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
6031
+ console.log(
6032
+ `[publishMessageBatch] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`
6033
+ );
6034
+ return this.contract.publishMessage({
6035
+ signer,
6036
+ contractAddress,
6037
+ encPubKeys,
6038
+ messages,
6039
+ granter: effectiveGranter,
6040
+ funds: batchFunds,
6041
+ fee
6042
+ });
6016
6043
  }
6017
6044
  async publishMessageBatchLegacy({
6018
6045
  signer,
@@ -6026,7 +6053,6 @@ var MACI = class {
6026
6053
  if (!address) {
6027
6054
  address = (await signer.getAccounts())[0].address;
6028
6055
  }
6029
- const client = await this.contract.contractClient({ signer });
6030
6056
  const messages = payload.map((p) => ({
6031
6057
  data: p.msg
6032
6058
  }));
@@ -6036,7 +6062,7 @@ var MACI = class {
6036
6062
  }));
6037
6063
  const totalFee = (BigInt(this.feeConfig.messageFee) * BigInt(payload.length)).toString();
6038
6064
  const batchFunds = [{ denom: FEE_DENOM, amount: totalFee }];
6039
- const msg = {
6065
+ const legacyMsg = {
6040
6066
  typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
6041
6067
  value: import_tx.MsgExecuteContract.fromPartial({
6042
6068
  sender: address,
@@ -6054,25 +6080,17 @@ var MACI = class {
6054
6080
  funds: batchFunds
6055
6081
  })
6056
6082
  };
6057
- if (gasStation && typeof fee !== "object") {
6058
- const gasEstimation = await client.simulate(address, [msg], "");
6059
- const multiplier = typeof fee === "number" ? fee : 1.8;
6060
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6061
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6062
- const grantFee = {
6063
- amount: calculatedFee.amount,
6064
- gas: calculatedFee.gas,
6065
- granter: granter || contractAddress
6066
- };
6067
- return client.signAndBroadcast(address, [msg], grantFee);
6068
- } else if (gasStation && typeof fee === "object") {
6069
- const grantFee = {
6070
- ...fee,
6071
- granter: granter || contractAddress
6072
- };
6073
- return client.signAndBroadcast(address, [msg], grantFee);
6074
- }
6075
- return client.signAndBroadcast(address, [msg], fee);
6083
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
6084
+ console.log(
6085
+ `[publishMessageBatchLegacy] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`
6086
+ );
6087
+ return this.contract.executeWithRetry({
6088
+ signer,
6089
+ address,
6090
+ msgs: [legacyMsg],
6091
+ granter: effectiveGranter,
6092
+ fee
6093
+ });
6076
6094
  }
6077
6095
  async deactivate({
6078
6096
  signer,
@@ -6087,9 +6105,6 @@ var MACI = class {
6087
6105
  if (maciKeypair === void 0) {
6088
6106
  maciKeypair = this.maciKeypair;
6089
6107
  }
6090
- const client = await this.contract.contractClient({
6091
- signer
6092
- });
6093
6108
  const stateIdx = await this.getStateIdxInc({
6094
6109
  address,
6095
6110
  contractAddress
@@ -6108,132 +6123,61 @@ var MACI = class {
6108
6123
  [[0, 0]],
6109
6124
  Number(pollId)
6110
6125
  );
6111
- const { msg, encPubkeys } = payload[0];
6112
- const deactivateMsg = stringizing({
6113
- publish_deactivate_message: {
6114
- enc_pub_key: {
6115
- x: encPubkeys[0],
6116
- y: encPubkeys[1]
6117
- },
6118
- message: {
6119
- data: msg
6120
- }
6121
- }
6126
+ return await this.rawDeactivate({
6127
+ signer,
6128
+ contractAddress,
6129
+ payload: payload[0],
6130
+ gasStation,
6131
+ fee
6122
6132
  });
6123
- const deactivateFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.deactivateFee }];
6124
- if (gasStation === true && typeof fee !== "object") {
6125
- const gasEstimation = await client.simulate(
6126
- address,
6127
- [
6128
- {
6129
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
6130
- value: import_tx.MsgExecuteContract.fromPartial({
6131
- sender: address,
6132
- contract: contractAddress,
6133
- msg: new TextEncoder().encode(JSON.stringify(deactivateMsg)),
6134
- funds: deactivateFunds
6135
- })
6136
- }
6137
- ],
6138
- ""
6139
- );
6140
- const multiplier = typeof fee === "number" ? fee : 1.8;
6141
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6142
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6143
- const grantFee = {
6144
- amount: calculatedFee.amount,
6145
- gas: calculatedFee.gas,
6146
- granter: contractAddress
6147
- };
6148
- return client.execute(address, contractAddress, deactivateMsg, grantFee, void 0, deactivateFunds);
6149
- } else if (gasStation === true && typeof fee === "object") {
6150
- const grantFee = {
6151
- ...fee,
6152
- granter: contractAddress
6153
- };
6154
- return client.execute(address, contractAddress, deactivateMsg, grantFee, void 0, deactivateFunds);
6155
- }
6156
- return client.execute(address, contractAddress, deactivateMsg, fee, void 0, deactivateFunds);
6157
6133
  } catch (error) {
6158
6134
  throw Error(`Submit deactivate failed! ${error}`);
6159
6135
  }
6160
6136
  }
6161
6137
  async rawDeactivate({
6162
6138
  signer,
6163
- address,
6164
6139
  contractAddress,
6165
6140
  payload,
6166
6141
  gasStation = false,
6167
6142
  granter,
6168
6143
  fee = 1.8
6169
6144
  }) {
6170
- try {
6171
- address = address || (await signer.getAccounts())[0].address;
6172
- const { msg, encPubkeys } = payload;
6173
- if (gasStation === true && granter === this.contract.apiSaasAddress) {
6174
- return this.contract.publishDeactivateMessageViaSaas({
6175
- signer,
6176
- contractAddress,
6177
- encPubKey: {
6178
- x: encPubkeys[0].toString(),
6179
- y: encPubkeys[1].toString()
6180
- },
6181
- message: {
6182
- data: msg.map((m) => m.toString())
6183
- },
6184
- granter,
6185
- fee
6186
- });
6187
- }
6188
- const client = await this.contract.contractClient({ signer });
6189
- const deactivateMsg = stringizing({
6190
- publish_deactivate_message: {
6191
- enc_pub_key: {
6192
- x: encPubkeys[0],
6193
- y: encPubkeys[1]
6194
- },
6195
- message: {
6196
- data: msg
6197
- }
6198
- }
6145
+ const { msg, encPubkeys } = payload;
6146
+ if (gasStation === true && granter === this.contract.apiSaasAddress) {
6147
+ console.log("[rawDeactivate] path: viaSaas (gasStation=true, granter=apiSaasAddress)");
6148
+ return this.contract.publishDeactivateMessageViaSaas({
6149
+ signer,
6150
+ contractAddress,
6151
+ encPubKey: {
6152
+ x: encPubkeys[0].toString(),
6153
+ y: encPubkeys[1].toString()
6154
+ },
6155
+ message: {
6156
+ data: msg.map((m) => m.toString())
6157
+ },
6158
+ granter,
6159
+ fee
6199
6160
  });
6200
- const deactivateFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.deactivateFee }];
6201
- if (gasStation === true && typeof fee !== "object") {
6202
- const gasEstimation = await client.simulate(
6203
- address,
6204
- [
6205
- {
6206
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
6207
- value: import_tx.MsgExecuteContract.fromPartial({
6208
- sender: address,
6209
- contract: contractAddress,
6210
- msg: new TextEncoder().encode(JSON.stringify(deactivateMsg)),
6211
- funds: deactivateFunds
6212
- })
6213
- }
6214
- ],
6215
- ""
6216
- );
6217
- const multiplier = typeof fee === "number" ? fee : 1.8;
6218
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6219
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6220
- const grantFee = {
6221
- amount: calculatedFee.amount,
6222
- gas: calculatedFee.gas,
6223
- granter: granter || contractAddress
6224
- };
6225
- return client.execute(address, contractAddress, deactivateMsg, grantFee, void 0, deactivateFunds);
6226
- } else if (gasStation === true && typeof fee === "object") {
6227
- const grantFee = {
6228
- ...fee,
6229
- granter: granter || contractAddress
6230
- };
6231
- return client.execute(address, contractAddress, deactivateMsg, grantFee, void 0, deactivateFunds);
6232
- }
6233
- return client.execute(address, contractAddress, deactivateMsg, fee, void 0, deactivateFunds);
6234
- } catch (error) {
6235
- throw Error(`Submit deactivate failed! ${error}`);
6236
6161
  }
6162
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
6163
+ console.log(
6164
+ `[rawDeactivate] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`
6165
+ );
6166
+ const deactivateFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.deactivateFee }];
6167
+ return this.contract.publishDeactivateMessage({
6168
+ signer,
6169
+ contractAddress,
6170
+ encPubKey: {
6171
+ x: encPubkeys[0].toString(),
6172
+ y: encPubkeys[1].toString()
6173
+ },
6174
+ message: {
6175
+ data: msg.map((m) => m.toString())
6176
+ },
6177
+ granter: effectiveGranter,
6178
+ funds: deactivateFunds,
6179
+ fee
6180
+ });
6237
6181
  }
6238
6182
  async fetchAllDeactivateLogs({ contractAddress }) {
6239
6183
  const deactivates = await this.indexer.fetchAllDeactivateLogs(contractAddress);
@@ -6271,25 +6215,15 @@ var MACI = class {
6271
6215
  newMaciKeypair,
6272
6216
  fee = "auto"
6273
6217
  }) {
6274
- const client = await this.contract.amaciClient({
6218
+ return this.rawAddNewKey({
6275
6219
  signer,
6276
- contractAddress
6220
+ contractAddress,
6221
+ d,
6222
+ proof,
6223
+ nullifier,
6224
+ newPubkey: newMaciKeypair.pubKey,
6225
+ fee
6277
6226
  });
6278
- const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
6279
- return await client.addNewKey(
6280
- {
6281
- d,
6282
- groth16Proof: proof,
6283
- nullifier: nullifier.toString(),
6284
- pubkey: {
6285
- x: newMaciKeypair.pubKey[0].toString(),
6286
- y: newMaciKeypair.pubKey[1].toString()
6287
- }
6288
- },
6289
- fee,
6290
- void 0,
6291
- signupFunds
6292
- );
6293
6227
  }
6294
6228
  async rawAddNewKey({
6295
6229
  signer,
@@ -6302,66 +6236,40 @@ var MACI = class {
6302
6236
  granter,
6303
6237
  fee = "auto"
6304
6238
  }) {
6305
- const client = await this.contract.amaciClient({
6306
- signer,
6307
- contractAddress
6308
- });
6309
6239
  const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
6310
- const keyParams = {
6240
+ const pubkey = {
6241
+ x: newPubkey[0].toString(),
6242
+ y: newPubkey[1].toString()
6243
+ };
6244
+ const nullifierStr = nullifier.toString();
6245
+ if (gasStation === true && granter === this.contract.apiSaasAddress) {
6246
+ console.log("[rawAddNewKey] path: viaSaas (gasStation=true, granter=apiSaasAddress)");
6247
+ return this.contract.addNewKeyViaSaas({
6248
+ signer,
6249
+ contractAddress,
6250
+ pubkey,
6251
+ nullifier: nullifierStr,
6252
+ d,
6253
+ groth16Proof: proof,
6254
+ granter,
6255
+ fee
6256
+ });
6257
+ }
6258
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
6259
+ console.log(
6260
+ `[rawAddNewKey] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`
6261
+ );
6262
+ return this.contract.addNewKey({
6263
+ signer,
6264
+ contractAddress,
6265
+ pubkey,
6266
+ nullifier: nullifierStr,
6311
6267
  d,
6312
6268
  groth16Proof: proof,
6313
- nullifier: nullifier.toString(),
6314
- pubkey: {
6315
- x: newPubkey[0].toString(),
6316
- y: newPubkey[1].toString()
6317
- }
6318
- };
6319
- if (gasStation === true && typeof fee !== "object") {
6320
- const [{ address }] = await signer.getAccounts();
6321
- const contractClient = await this.contract.contractClient({ signer });
6322
- const msg = {
6323
- add_new_key: {
6324
- d,
6325
- groth16_proof: proof,
6326
- nullifier: nullifier.toString(),
6327
- pubkey: {
6328
- x: newPubkey[0].toString(),
6329
- y: newPubkey[1].toString()
6330
- }
6331
- }
6332
- };
6333
- const gasEstimation = await contractClient.simulate(
6334
- address,
6335
- [
6336
- {
6337
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
6338
- value: {
6339
- sender: address,
6340
- contract: contractAddress,
6341
- msg: new TextEncoder().encode(JSON.stringify(msg)),
6342
- funds: signupFunds
6343
- }
6344
- }
6345
- ],
6346
- ""
6347
- );
6348
- const multiplier = typeof fee === "number" ? fee : 1.8;
6349
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6350
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6351
- const grantFee = {
6352
- amount: calculatedFee.amount,
6353
- gas: calculatedFee.gas,
6354
- granter: granter || contractAddress
6355
- };
6356
- return await client.addNewKey(keyParams, grantFee, void 0, signupFunds);
6357
- } else if (gasStation === true && typeof fee === "object") {
6358
- const grantFee = {
6359
- ...fee,
6360
- granter: granter || contractAddress
6361
- };
6362
- return await client.addNewKey(keyParams, grantFee, void 0, signupFunds);
6363
- }
6364
- return await client.addNewKey(keyParams, fee, void 0, signupFunds);
6269
+ granter: effectiveGranter,
6270
+ funds: signupFunds,
6271
+ fee
6272
+ });
6365
6273
  }
6366
6274
  async rawPreAddNewKey({
6367
6275
  signer,
@@ -6374,77 +6282,47 @@ var MACI = class {
6374
6282
  granter,
6375
6283
  fee = "auto"
6376
6284
  }) {
6377
- const client = await this.contract.amaciClient({
6378
- signer,
6379
- contractAddress
6380
- });
6381
6285
  const signupFunds = [{ denom: FEE_DENOM, amount: this.feeConfig.signupFee }];
6382
- const keyParams = {
6286
+ const pubkey = {
6287
+ x: newPubkey[0].toString(),
6288
+ y: newPubkey[1].toString()
6289
+ };
6290
+ const nullifierStr = nullifier.toString();
6291
+ if (gasStation === true && granter === this.contract.apiSaasAddress) {
6292
+ console.log("[rawPreAddNewKey] path: viaSaas (gasStation=true, granter=apiSaasAddress)");
6293
+ return this.contract.preAddNewKeyViaSaas({
6294
+ signer,
6295
+ contractAddress,
6296
+ pubkey,
6297
+ nullifier: nullifierStr,
6298
+ d,
6299
+ groth16Proof: proof,
6300
+ granter,
6301
+ fee
6302
+ });
6303
+ }
6304
+ const effectiveGranter = gasStation ? granter ?? contractAddress : void 0;
6305
+ console.log(
6306
+ `[rawPreAddNewKey] path: direct (gasStation=${gasStation}, granter=${effectiveGranter ?? "none"})`
6307
+ );
6308
+ return this.contract.preAddNewKey({
6309
+ signer,
6310
+ contractAddress,
6311
+ pubkey,
6312
+ nullifier: nullifierStr,
6383
6313
  d,
6384
6314
  groth16Proof: proof,
6385
- nullifier: nullifier.toString(),
6386
- pubkey: {
6387
- x: newPubkey[0].toString(),
6388
- y: newPubkey[1].toString()
6389
- }
6390
- };
6391
- if (gasStation === true && typeof fee !== "object") {
6392
- const [{ address }] = await signer.getAccounts();
6393
- const contractClient = await this.contract.contractClient({ signer });
6394
- const msg = {
6395
- pre_add_new_key: {
6396
- d,
6397
- groth16_proof: proof,
6398
- nullifier: nullifier.toString(),
6399
- pubkey: {
6400
- x: newPubkey[0].toString(),
6401
- y: newPubkey[1].toString()
6402
- }
6403
- }
6404
- };
6405
- const gasEstimation = await contractClient.simulate(
6406
- address,
6407
- [
6408
- {
6409
- typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
6410
- value: {
6411
- sender: address,
6412
- contract: contractAddress,
6413
- msg: new TextEncoder().encode(JSON.stringify(msg)),
6414
- funds: signupFunds
6415
- }
6416
- }
6417
- ],
6418
- ""
6419
- );
6420
- const multiplier = typeof fee === "number" ? fee : 1.8;
6421
- const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
6422
- const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
6423
- const grantFee = {
6424
- amount: calculatedFee.amount,
6425
- gas: calculatedFee.gas,
6426
- granter: granter || contractAddress
6427
- };
6428
- return await client.preAddNewKey(keyParams, grantFee, void 0, signupFunds);
6429
- } else if (gasStation === true && typeof fee === "object") {
6430
- const grantFee = {
6431
- ...fee,
6432
- granter: granter || contractAddress
6433
- };
6434
- return await client.preAddNewKey(keyParams, grantFee, void 0, signupFunds);
6435
- }
6436
- return await client.preAddNewKey(keyParams, fee, void 0, signupFunds);
6315
+ granter: effectiveGranter,
6316
+ funds: signupFunds,
6317
+ fee
6318
+ });
6437
6319
  }
6438
6320
  async claimAMaciRound({
6439
6321
  signer,
6440
6322
  contractAddress,
6441
6323
  fee = "auto"
6442
6324
  }) {
6443
- const client = await this.contract.amaciClient({
6444
- signer,
6445
- contractAddress
6446
- });
6447
- return client.claim(fee);
6325
+ return this.contract.claim({ signer, contractAddress, fee });
6448
6326
  }
6449
6327
  async getOracleCertificateConfig() {
6450
6328
  const ecosystems = await this.oracleCertificate.listEcosystems();
@@ -6465,9 +6343,6 @@ var MACI = class {
6465
6343
  amount,
6466
6344
  fee = "auto"
6467
6345
  }) {
6468
- const client = await this.contract.contractClient({
6469
- signer
6470
- });
6471
6346
  if (!address) {
6472
6347
  address = (await signer.getAccounts())[0].address;
6473
6348
  }
@@ -6509,12 +6384,7 @@ var MACI = class {
6509
6384
  })
6510
6385
  }
6511
6386
  ];
6512
- try {
6513
- const result = await client.signAndBroadcast(address, msgs, fee);
6514
- return result;
6515
- } catch (err) {
6516
- throw err;
6517
- }
6387
+ return this.contract.executeWithRetry({ signer, address, msgs, fee });
6518
6388
  }
6519
6389
  /**
6520
6390
  * Batch revoke with withdraw (for maci)
@@ -6529,9 +6399,6 @@ var MACI = class {
6529
6399
  address,
6530
6400
  fee = "auto"
6531
6401
  }) {
6532
- const client = await this.contract.contractClient({
6533
- signer
6534
- });
6535
6402
  if (!address) {
6536
6403
  address = (await signer.getAccounts())[0].address;
6537
6404
  }
@@ -6565,12 +6432,7 @@ var MACI = class {
6565
6432
  })
6566
6433
  }
6567
6434
  ];
6568
- try {
6569
- const result = await client.signAndBroadcast(address, msgs, fee);
6570
- return result;
6571
- } catch (err) {
6572
- throw err;
6573
- }
6435
+ return this.contract.executeWithRetry({ signer, address, msgs, fee });
6574
6436
  }
6575
6437
  };
6576
6438
 
@@ -6854,14 +6716,6 @@ var MaciApiClient = class {
6854
6716
  });
6855
6717
  }
6856
6718
  // ==================== Pre-deactivate APIs ====================
6857
- /**
6858
- * Get pre-deactivate data by contract address
6859
- */
6860
- async getPreDeactivate(params) {
6861
- return this.fetch(`/v1/pre-deactivate/${params.contractAddress}`, {
6862
- method: "GET"
6863
- });
6864
- }
6865
6719
  /**
6866
6720
  * Get coordinator public key, deactivate root, and voter scale for a round.
6867
6721
  * Lighter alternative to the full data endpoint when only circuit inputs are needed.
@@ -6919,8 +6773,8 @@ var MaciClient = class {
6919
6773
  constructor({
6920
6774
  signer,
6921
6775
  network,
6922
- rpcEndpoint,
6923
- restEndpoint,
6776
+ rpcEndpoints,
6777
+ restEndpoints,
6924
6778
  apiEndpoint,
6925
6779
  saasApiEndpoint,
6926
6780
  saasApiKey,
@@ -6934,13 +6788,17 @@ var MaciClient = class {
6934
6788
  feegrantOperator,
6935
6789
  whitelistBackendPubkey,
6936
6790
  certificateApiEndpoint,
6937
- maciKeypair
6791
+ maciKeypair,
6792
+ retries,
6793
+ retryDelay
6938
6794
  }) {
6939
6795
  this.signer = signer;
6940
6796
  this.network = network;
6941
6797
  const defaultParams = getDefaultParams(network);
6942
- this.rpcEndpoint = rpcEndpoint || defaultParams.rpcEndpoint;
6943
- this.restEndpoint = restEndpoint || defaultParams.restEndpoint;
6798
+ const rpcUrls = rpcEndpoints ?? defaultParams.rpcEndpoints;
6799
+ const restUrls = restEndpoints ?? defaultParams.restEndpoints;
6800
+ this.rpcEndpoints = rpcUrls;
6801
+ this.restEndpoints = restUrls;
6944
6802
  this.apiEndpoint = apiEndpoint || defaultParams.apiEndpoint;
6945
6803
  this.saasApiEndpoint = saasApiEndpoint || defaultParams.saasApiEndpoint;
6946
6804
  this.certificateApiEndpoint = certificateApiEndpoint || defaultParams.certificateApiEndpoint;
@@ -6952,9 +6810,9 @@ var MaciClient = class {
6952
6810
  this.feegrantOperator = feegrantOperator || defaultParams.oracleFeegrantOperator;
6953
6811
  this.whitelistBackendPubkey = whitelistBackendPubkey || defaultParams.oracleWhitelistBackendPubkey;
6954
6812
  this.maciKeypair = maciKeypair ?? genKeypair();
6955
- this.http = new Http(this.apiEndpoint, this.restEndpoint, customFetch, defaultOptions);
6813
+ this.http = new Http(this.apiEndpoint, restUrls, customFetch, defaultOptions, retries, retryDelay);
6956
6814
  this.indexer = new Indexer({
6957
- restEndpoint: this.restEndpoint,
6815
+ restEndpoint: restUrls[0],
6958
6816
  apiEndpoint: this.apiEndpoint,
6959
6817
  // Indexer GraphQL API
6960
6818
  registryAddress: this.registryAddress,
@@ -6962,14 +6820,16 @@ var MaciClient = class {
6962
6820
  });
6963
6821
  this.contract = new Contract({
6964
6822
  network: this.network,
6965
- rpcEndpoint: this.rpcEndpoint,
6823
+ rpcEndpoints: rpcUrls,
6966
6824
  registryAddress: this.registryAddress,
6967
6825
  saasAddress: this.saasAddress,
6968
6826
  apiSaasAddress: this.apiSaasAddress,
6969
6827
  maciCodeId: this.maciCodeId,
6970
6828
  oracleCodeId: this.oracleCodeId,
6971
6829
  feegrantOperator: this.feegrantOperator,
6972
- whitelistBackendPubkey: this.whitelistBackendPubkey
6830
+ whitelistBackendPubkey: this.whitelistBackendPubkey,
6831
+ retries,
6832
+ retryDelay
6973
6833
  });
6974
6834
  this.oracleCertificate = new OracleCertificate({
6975
6835
  certificateApiEndpoint: this.certificateApiEndpoint,
@@ -7020,6 +6880,38 @@ var MaciClient = class {
7020
6880
  }
7021
6881
  return this.saasApiClient;
7022
6882
  }
6883
+ /**
6884
+ * Poll the chain REST endpoint until the given transaction is committed on-chain,
6885
+ * then return its `tx_response` object with an added `status` field.
6886
+ *
6887
+ * @param txHash - On-chain transaction hash to wait for.
6888
+ * @param options.timeout - Max wait time in milliseconds (default: 60 000 ms).
6889
+ * @param options.interval - Polling interval in milliseconds (default: 2 000 ms).
6890
+ * @returns The Cosmos `tx_response` record plus `status`: `'success'` when `code === 0`, `'failed'` otherwise.
6891
+ * @throws If the transaction is not found within the timeout period.
6892
+ */
6893
+ async waitForTransaction(txHash, options = {}) {
6894
+ const timeout = options.timeout ?? 6e4;
6895
+ const interval = options.interval ?? 2e3;
6896
+ const deadline = Date.now() + timeout;
6897
+ while (Date.now() < deadline) {
6898
+ try {
6899
+ const data = await this.http.fetchRest(`/cosmos/tx/v1beta1/txs/${txHash}`);
6900
+ if (data?.tx_response) {
6901
+ const txResponse = data.tx_response;
6902
+ return {
6903
+ ...txResponse,
6904
+ status: txResponse.code === 0 ? "success" : "failed"
6905
+ };
6906
+ }
6907
+ } catch {
6908
+ }
6909
+ await new Promise((resolve) => setTimeout(resolve, interval));
6910
+ }
6911
+ throw new Error(
6912
+ `waitForTransaction: transaction ${txHash} not found on chain within ${timeout}ms`
6913
+ );
6914
+ }
7023
6915
  getMaciKeypair() {
7024
6916
  return this.maciKeypair;
7025
6917
  }
@@ -7991,23 +7883,28 @@ var VoterClient = class _VoterClient {
7991
7883
  mnemonic,
7992
7884
  secretKey,
7993
7885
  apiEndpoint,
7994
- restEndpoint,
7886
+ rpcEndpoints,
7887
+ restEndpoints,
7995
7888
  saasApiEndpoint,
7996
7889
  saasApiKey,
7997
7890
  registryAddress,
7998
7891
  customFetch,
7999
- defaultOptions
7892
+ defaultOptions,
7893
+ retries,
7894
+ retryDelay
8000
7895
  }) {
8001
7896
  this.network = network;
8002
7897
  this.accountManager = new MaciAccount({ mnemonic, secretKey });
8003
7898
  const defaultParams = getDefaultParams(network);
8004
- this.restEndpoint = restEndpoint || defaultParams.restEndpoint;
7899
+ const rpcUrls = rpcEndpoints ?? defaultParams.rpcEndpoints;
7900
+ const restUrls = restEndpoints ?? defaultParams.restEndpoints;
7901
+ this.restEndpoints = restUrls;
8005
7902
  this.apiEndpoint = apiEndpoint || defaultParams.apiEndpoint;
8006
7903
  this.saasApiEndpoint = saasApiEndpoint || defaultParams.saasApiEndpoint;
8007
7904
  this.registryAddress = registryAddress || defaultParams.registryAddress;
8008
- this.http = new Http(this.apiEndpoint, this.restEndpoint, customFetch, defaultOptions);
7905
+ this.http = new Http(this.apiEndpoint, restUrls, customFetch, defaultOptions, retries, retryDelay);
8009
7906
  this.indexer = new Indexer({
8010
- restEndpoint: this.restEndpoint,
7907
+ restEndpoint: restUrls[0],
8011
7908
  apiEndpoint: this.apiEndpoint,
8012
7909
  // Indexer GraphQL API
8013
7910
  registryAddress: this.registryAddress,
@@ -8020,14 +7917,16 @@ var VoterClient = class _VoterClient {
8020
7917
  });
8021
7918
  this.contract = new Contract({
8022
7919
  network: this.network,
8023
- rpcEndpoint: defaultParams.rpcEndpoint,
7920
+ rpcEndpoints: rpcUrls,
8024
7921
  registryAddress: this.registryAddress,
8025
7922
  saasAddress: defaultParams.saasAddress,
8026
7923
  apiSaasAddress: defaultParams.apiSaasAddress,
8027
7924
  maciCodeId: defaultParams.maciCodeId,
8028
7925
  oracleCodeId: defaultParams.oracleCodeId,
8029
7926
  feegrantOperator: defaultParams.oracleFeegrantOperator,
8030
- whitelistBackendPubkey: defaultParams.oracleWhitelistBackendPubkey
7927
+ whitelistBackendPubkey: defaultParams.oracleWhitelistBackendPubkey,
7928
+ retries,
7929
+ retryDelay
8031
7930
  });
8032
7931
  }
8033
7932
  /**
@@ -8797,16 +8696,6 @@ var VoterClient = class _VoterClient {
8797
8696
  }
8798
8697
  return await this.saasApiClient.createAmaciRound(params);
8799
8698
  }
8800
- /**
8801
- * Get pre-deactivate data via SaaS API
8802
- * @param contractAddress - Contract address
8803
- */
8804
- async saasGetPreDeactivate(contractAddress) {
8805
- if (!this.saasApiClient) {
8806
- throw new Error("SaaS API client not initialized");
8807
- }
8808
- return await this.saasApiClient.getPreDeactivate({ contractAddress });
8809
- }
8810
8699
  /**
8811
8700
  * Signup via SaaS API
8812
8701
  * @param params - Signup parameters (including ticket)
@@ -8862,6 +8751,43 @@ var VoterClient = class _VoterClient {
8862
8751
  }
8863
8752
  return await this.saasApiClient.preAddNewKey(params);
8864
8753
  }
8754
+ // ==================== Transaction Utilities ====================
8755
+ /**
8756
+ * Poll the chain REST endpoint until the given transaction is committed on-chain,
8757
+ * then return its `tx_response` object with an added `status` field.
8758
+ *
8759
+ * The underlying REST client automatically rotates through all configured
8760
+ * `restEndpoints` on failure, so a single unavailable node will not block polling.
8761
+ *
8762
+ * @param txHash - On-chain transaction hash to wait for.
8763
+ * @param options.timeout - Max wait time in milliseconds (default: 60 000 ms).
8764
+ * @param options.interval - Polling interval in milliseconds (default: 2 000 ms).
8765
+ * @returns The Cosmos `tx_response` record plus `status`: `'success'` when `code === 0`, `'failed'` otherwise.
8766
+ * The `events` array can be parsed with helpers such as `parseCreatedRoundEvent`.
8767
+ * @throws If the transaction is not found within the timeout period.
8768
+ */
8769
+ async waitForTransaction(txHash, options = {}) {
8770
+ const timeout = options.timeout ?? 6e4;
8771
+ const interval = options.interval ?? 2e3;
8772
+ const deadline = Date.now() + timeout;
8773
+ while (Date.now() < deadline) {
8774
+ try {
8775
+ const data = await this.http.fetchRest(`/cosmos/tx/v1beta1/txs/${txHash}`);
8776
+ if (data?.tx_response) {
8777
+ const txResponse = data.tx_response;
8778
+ return {
8779
+ ...txResponse,
8780
+ status: txResponse.code === 0 ? "success" : "failed"
8781
+ };
8782
+ }
8783
+ } catch {
8784
+ }
8785
+ await new Promise((resolve) => setTimeout(resolve, interval));
8786
+ }
8787
+ throw new Error(
8788
+ `waitForTransaction: transaction ${txHash} not found on chain within ${timeout}ms`
8789
+ );
8790
+ }
8865
8791
  // ==================== Maci Voter Methods ====================
8866
8792
  /**
8867
8793
  * Pre-create a new account for AMACI voting (pre-deactivate mode).
@@ -8890,7 +8816,7 @@ var VoterClient = class _VoterClient {
8890
8816
  }) {
8891
8817
  const newVoterClient = new _VoterClient({
8892
8818
  network: this.network,
8893
- restEndpoint: this.restEndpoint,
8819
+ restEndpoints: this.restEndpoints,
8894
8820
  apiEndpoint: this.apiEndpoint,
8895
8821
  saasApiEndpoint: this.saasApiEndpoint,
8896
8822
  registryAddress: this.registryAddress
@@ -8997,10 +8923,12 @@ var OperatorClient = class {
8997
8923
  mnemonic,
8998
8924
  secretKey,
8999
8925
  apiEndpoint,
9000
- restEndpoint,
8926
+ restEndpoints,
9001
8927
  registryAddress,
9002
8928
  customFetch,
9003
- defaultOptions
8929
+ defaultOptions,
8930
+ retries,
8931
+ retryDelay
9004
8932
  }) {
9005
8933
  // State
9006
8934
  this.deactivateSize = 0;
@@ -9022,12 +8950,13 @@ var OperatorClient = class {
9022
8950
  this.network = network;
9023
8951
  this.accountManager = new MaciAccount({ mnemonic, secretKey });
9024
8952
  const defaultParams = getDefaultParams(network);
9025
- this.restEndpoint = restEndpoint || defaultParams.restEndpoint;
8953
+ const restUrls = restEndpoints ?? defaultParams.restEndpoints;
8954
+ this.restEndpoints = restUrls;
9026
8955
  this.apiEndpoint = apiEndpoint || defaultParams.apiEndpoint;
9027
8956
  this.registryAddress = registryAddress || defaultParams.registryAddress;
9028
- this.http = new Http(this.apiEndpoint, this.restEndpoint, customFetch, defaultOptions);
8957
+ this.http = new Http(this.apiEndpoint, restUrls, customFetch, defaultOptions, retries, retryDelay);
9029
8958
  this.indexer = new Indexer({
9030
- restEndpoint: this.restEndpoint,
8959
+ restEndpoint: restUrls[0],
9031
8960
  apiEndpoint: this.apiEndpoint,
9032
8961
  // Indexer GraphQL API
9033
8962
  registryAddress: this.registryAddress,
@@ -9035,14 +8964,16 @@ var OperatorClient = class {
9035
8964
  });
9036
8965
  this.contract = new Contract({
9037
8966
  network: this.network,
9038
- rpcEndpoint: defaultParams.rpcEndpoint,
8967
+ rpcEndpoints: defaultParams.rpcEndpoints,
9039
8968
  registryAddress: this.registryAddress,
9040
8969
  saasAddress: defaultParams.saasAddress,
9041
8970
  apiSaasAddress: defaultParams.apiSaasAddress,
9042
8971
  maciCodeId: defaultParams.maciCodeId,
9043
8972
  oracleCodeId: defaultParams.oracleCodeId,
9044
8973
  feegrantOperator: defaultParams.oracleFeegrantOperator,
9045
- whitelistBackendPubkey: defaultParams.oracleWhitelistBackendPubkey
8974
+ whitelistBackendPubkey: defaultParams.oracleWhitelistBackendPubkey,
8975
+ retries,
8976
+ retryDelay
9046
8977
  });
9047
8978
  }
9048
8979
  /**