@moonwell-fi/moonwell-sdk 0.10.7 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/actions/core/markets/common.js +26 -12
  3. package/_cjs/actions/core/markets/common.js.map +1 -1
  4. package/_cjs/actions/core/markets/getMarketSnapshots.js +173 -321
  5. package/_cjs/actions/core/markets/getMarketSnapshots.js.map +1 -1
  6. package/_cjs/actions/core/user-positions/getUserPositionSnapshots.js +31 -26
  7. package/_cjs/actions/core/user-positions/getUserPositionSnapshots.js.map +1 -1
  8. package/_cjs/actions/governance/getCirculatingSupplySnapshots.js +35 -29
  9. package/_cjs/actions/governance/getCirculatingSupplySnapshots.js.map +1 -1
  10. package/_cjs/actions/governance/getStakingSnapshots.js +16 -12
  11. package/_cjs/actions/governance/getStakingSnapshots.js.map +1 -1
  12. package/_cjs/actions/governance/proposals/common.js +247 -211
  13. package/_cjs/actions/governance/proposals/common.js.map +1 -1
  14. package/_cjs/actions/lunar-indexer-client.js +32 -0
  15. package/_cjs/actions/lunar-indexer-client.js.map +1 -1
  16. package/_cjs/actions/morpho/markets/common.js +26 -29
  17. package/_cjs/actions/morpho/markets/common.js.map +1 -1
  18. package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js +41 -56
  19. package/_cjs/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js.map +1 -1
  20. package/_cjs/actions/morpho/vaults/common.js +7 -4
  21. package/_cjs/actions/morpho/vaults/common.js.map +1 -1
  22. package/_cjs/actions/morpho/vaults/getMorphoVaultSnapshots.js +21 -78
  23. package/_cjs/actions/morpho/vaults/getMorphoVaultSnapshots.js.map +1 -1
  24. package/_cjs/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js +13 -66
  25. package/_cjs/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js.map +1 -1
  26. package/_cjs/client/createMoonwellClient.js +9 -3
  27. package/_cjs/client/createMoonwellClient.js.map +1 -1
  28. package/_cjs/environments/definitions/arbitrum/environment.js +1 -2
  29. package/_cjs/environments/definitions/arbitrum/environment.js.map +1 -1
  30. package/_cjs/environments/definitions/avalanche/environment.js +1 -2
  31. package/_cjs/environments/definitions/avalanche/environment.js.map +1 -1
  32. package/_cjs/environments/definitions/base/custom.js +0 -1
  33. package/_cjs/environments/definitions/base/custom.js.map +1 -1
  34. package/_cjs/environments/definitions/base/environment.js +1 -2
  35. package/_cjs/environments/definitions/base/environment.js.map +1 -1
  36. package/_cjs/environments/definitions/ethereum/environment.js +1 -2
  37. package/_cjs/environments/definitions/ethereum/environment.js.map +1 -1
  38. package/_cjs/environments/definitions/moonbeam/environment.js +1 -2
  39. package/_cjs/environments/definitions/moonbeam/environment.js.map +1 -1
  40. package/_cjs/environments/definitions/optimism/custom.js +0 -1
  41. package/_cjs/environments/definitions/optimism/custom.js.map +1 -1
  42. package/_cjs/environments/definitions/optimism/environment.js +1 -2
  43. package/_cjs/environments/definitions/optimism/environment.js.map +1 -1
  44. package/_cjs/environments/definitions/polygon/environment.js +1 -2
  45. package/_cjs/environments/definitions/polygon/environment.js.map +1 -1
  46. package/_cjs/environments/index.js +8 -8
  47. package/_cjs/environments/index.js.map +1 -1
  48. package/_cjs/environments/types/config.js +1 -0
  49. package/_cjs/environments/types/config.js.map +1 -1
  50. package/_cjs/errors/version.js +1 -1
  51. package/_esm/actions/core/markets/common.js +26 -13
  52. package/_esm/actions/core/markets/common.js.map +1 -1
  53. package/_esm/actions/core/markets/getMarketSnapshots.js +194 -346
  54. package/_esm/actions/core/markets/getMarketSnapshots.js.map +1 -1
  55. package/_esm/actions/core/user-positions/getUserPositionSnapshots.js +32 -29
  56. package/_esm/actions/core/user-positions/getUserPositionSnapshots.js.map +1 -1
  57. package/_esm/actions/governance/getCirculatingSupplySnapshots.js +35 -30
  58. package/_esm/actions/governance/getCirculatingSupplySnapshots.js.map +1 -1
  59. package/_esm/actions/governance/getStakingSnapshots.js +17 -13
  60. package/_esm/actions/governance/getStakingSnapshots.js.map +1 -1
  61. package/_esm/actions/governance/proposals/common.js +246 -216
  62. package/_esm/actions/governance/proposals/common.js.map +1 -1
  63. package/_esm/actions/lunar-indexer-client.js +35 -0
  64. package/_esm/actions/lunar-indexer-client.js.map +1 -1
  65. package/_esm/actions/morpho/markets/common.js +27 -34
  66. package/_esm/actions/morpho/markets/common.js.map +1 -1
  67. package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js +42 -54
  68. package/_esm/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.js.map +1 -1
  69. package/_esm/actions/morpho/vaults/common.js +7 -4
  70. package/_esm/actions/morpho/vaults/common.js.map +1 -1
  71. package/_esm/actions/morpho/vaults/getMorphoVaultSnapshots.js +24 -78
  72. package/_esm/actions/morpho/vaults/getMorphoVaultSnapshots.js.map +1 -1
  73. package/_esm/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js +15 -65
  74. package/_esm/actions/morpho/vaults/getMorphoVaultStakingSnapshots.js.map +1 -1
  75. package/_esm/client/createMoonwellClient.js +9 -3
  76. package/_esm/client/createMoonwellClient.js.map +1 -1
  77. package/_esm/environments/definitions/arbitrum/environment.js +1 -2
  78. package/_esm/environments/definitions/arbitrum/environment.js.map +1 -1
  79. package/_esm/environments/definitions/avalanche/environment.js +1 -2
  80. package/_esm/environments/definitions/avalanche/environment.js.map +1 -1
  81. package/_esm/environments/definitions/base/custom.js +0 -1
  82. package/_esm/environments/definitions/base/custom.js.map +1 -1
  83. package/_esm/environments/definitions/base/environment.js +1 -2
  84. package/_esm/environments/definitions/base/environment.js.map +1 -1
  85. package/_esm/environments/definitions/ethereum/environment.js +1 -2
  86. package/_esm/environments/definitions/ethereum/environment.js.map +1 -1
  87. package/_esm/environments/definitions/moonbeam/environment.js +1 -2
  88. package/_esm/environments/definitions/moonbeam/environment.js.map +1 -1
  89. package/_esm/environments/definitions/optimism/custom.js +0 -1
  90. package/_esm/environments/definitions/optimism/custom.js.map +1 -1
  91. package/_esm/environments/definitions/optimism/environment.js +1 -2
  92. package/_esm/environments/definitions/optimism/environment.js.map +1 -1
  93. package/_esm/environments/definitions/polygon/environment.js +1 -2
  94. package/_esm/environments/definitions/polygon/environment.js.map +1 -1
  95. package/_esm/environments/index.js +8 -8
  96. package/_esm/environments/index.js.map +1 -1
  97. package/_esm/environments/types/config.js +1 -0
  98. package/_esm/environments/types/config.js.map +1 -1
  99. package/_esm/errors/version.js +1 -1
  100. package/_types/actions/core/markets/common.d.ts.map +1 -1
  101. package/_types/actions/core/markets/getMarketSnapshots.d.ts.map +1 -1
  102. package/_types/actions/core/user-positions/getUserPositionSnapshots.d.ts +0 -1
  103. package/_types/actions/core/user-positions/getUserPositionSnapshots.d.ts.map +1 -1
  104. package/_types/actions/governance/getCirculatingSupplySnapshots.d.ts.map +1 -1
  105. package/_types/actions/governance/getStakingSnapshots.d.ts.map +1 -1
  106. package/_types/actions/governance/proposals/common.d.ts +2 -8
  107. package/_types/actions/governance/proposals/common.d.ts.map +1 -1
  108. package/_types/actions/lunar-indexer-client.d.ts +26 -0
  109. package/_types/actions/lunar-indexer-client.d.ts.map +1 -1
  110. package/_types/actions/morpho/markets/common.d.ts.map +1 -1
  111. package/_types/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.d.ts +9 -3
  112. package/_types/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.d.ts.map +1 -1
  113. package/_types/actions/morpho/vaults/common.d.ts.map +1 -1
  114. package/_types/actions/morpho/vaults/getMorphoVaultSnapshots.d.ts.map +1 -1
  115. package/_types/actions/morpho/vaults/getMorphoVaultStakingSnapshots.d.ts.map +1 -1
  116. package/_types/client/createMoonwellClient.d.ts +4 -4
  117. package/_types/client/createMoonwellClient.d.ts.map +1 -1
  118. package/_types/environments/definitions/arbitrum/environment.d.ts +1 -1
  119. package/_types/environments/definitions/arbitrum/environment.d.ts.map +1 -1
  120. package/_types/environments/definitions/avalanche/environment.d.ts +1 -1
  121. package/_types/environments/definitions/avalanche/environment.d.ts.map +1 -1
  122. package/_types/environments/definitions/base/custom.d.ts +0 -1
  123. package/_types/environments/definitions/base/custom.d.ts.map +1 -1
  124. package/_types/environments/definitions/base/environment.d.ts +1 -1
  125. package/_types/environments/definitions/base/environment.d.ts.map +1 -1
  126. package/_types/environments/definitions/ethereum/environment.d.ts +1 -1
  127. package/_types/environments/definitions/ethereum/environment.d.ts.map +1 -1
  128. package/_types/environments/definitions/moonbeam/environment.d.ts +1 -1
  129. package/_types/environments/definitions/moonbeam/environment.d.ts.map +1 -1
  130. package/_types/environments/definitions/optimism/custom.d.ts +0 -1
  131. package/_types/environments/definitions/optimism/custom.d.ts.map +1 -1
  132. package/_types/environments/definitions/optimism/environment.d.ts +1 -2
  133. package/_types/environments/definitions/optimism/environment.d.ts.map +1 -1
  134. package/_types/environments/definitions/polygon/environment.d.ts +1 -1
  135. package/_types/environments/definitions/polygon/environment.d.ts.map +1 -1
  136. package/_types/environments/index.d.ts +0 -3
  137. package/_types/environments/index.d.ts.map +1 -1
  138. package/_types/environments/types/config.d.ts +10 -3
  139. package/_types/environments/types/config.d.ts.map +1 -1
  140. package/_types/errors/version.d.ts +1 -1
  141. package/actions/core/markets/common.ts +33 -18
  142. package/actions/core/markets/getMarketSnapshots.ts +261 -511
  143. package/actions/core/user-positions/getUserPositionSnapshots.ts +44 -46
  144. package/actions/governance/getCirculatingSupplySnapshots.ts +43 -35
  145. package/actions/governance/getStakingSnapshots.ts +32 -29
  146. package/actions/governance/proposals/common.ts +369 -330
  147. package/actions/lunar-indexer-client.ts +64 -0
  148. package/actions/morpho/markets/common.ts +32 -43
  149. package/actions/morpho/user-positions/getMorphoVaultUserPositionSnapshots.ts +76 -87
  150. package/actions/morpho/vaults/common.ts +7 -6
  151. package/actions/morpho/vaults/getMorphoVaultSnapshots.ts +36 -120
  152. package/actions/morpho/vaults/getMorphoVaultStakingSnapshots.ts +24 -111
  153. package/client/createMoonwellClient.ts +17 -5
  154. package/environments/definitions/arbitrum/environment.ts +0 -2
  155. package/environments/definitions/avalanche/environment.ts +0 -2
  156. package/environments/definitions/base/custom.ts +0 -1
  157. package/environments/definitions/base/environment.ts +0 -2
  158. package/environments/definitions/ethereum/environment.ts +0 -2
  159. package/environments/definitions/moonbeam/environment.ts +0 -2
  160. package/environments/definitions/optimism/custom.ts +0 -1
  161. package/environments/definitions/optimism/environment.ts +0 -2
  162. package/environments/definitions/polygon/environment.ts +0 -2
  163. package/environments/index.ts +6 -27
  164. package/environments/types/config.ts +11 -3
  165. package/errors/version.ts +1 -1
  166. package/package.json +1 -1
@@ -11,6 +11,8 @@ import {
11
11
  } from "../../../types/proposal.js";
12
12
  import type { ApiProposal } from "../governor-api-client.js";
13
13
 
14
+ export const WORMHOLE_CONTRACT = "0xc8e2b0cd52cf01b0ce87d389daa3d414d4ce29f3";
15
+
14
16
  type PonderExtendedProposalData = {
15
17
  id: number;
16
18
  title: string;
@@ -28,8 +30,6 @@ type PonderExtendedProposalData = {
28
30
 
29
31
  axios.defaults.timeout = 5_000;
30
32
 
31
- export const WORMHOLE_CONTRACT = "0xc8e2b0cd52cf01b0ce87d389daa3d414d4ce29f3";
32
-
33
33
  /**
34
34
  * Extract proposal subtitle from description
35
35
  */
@@ -314,35 +314,6 @@ export const getProposalsOnChainData = async (
314
314
  }));
315
315
  };
316
316
 
317
- /**
318
- * Append extended proposal data (Ponder-based, for Moonriver)
319
- */
320
- export const appendProposalExtendedData = (
321
- proposals: Proposal[],
322
- extendedDatas: PonderExtendedProposalData[],
323
- ) => {
324
- proposals.forEach((proposal) => {
325
- const extendedData = extendedDatas.find(
326
- (item) => item.id === proposal.proposalId,
327
- );
328
-
329
- if (extendedData) {
330
- proposal.title = extendedData.title;
331
- proposal.calldatas = extendedData.calldatas;
332
- proposal.description = extendedData.description;
333
- proposal.signatures = extendedData.signatures;
334
- proposal.stateChanges = extendedData.stateChanges.map((change) => ({
335
- blockNumber: change.blockNumber,
336
- transactionHash: change.transactionHash,
337
- state: change.state,
338
- chainId: proposal.chainId,
339
- }));
340
- proposal.subtitle = extendedData.subtitle;
341
- proposal.targets = extendedData.targets;
342
- }
343
- });
344
- };
345
-
346
317
  /**
347
318
  * Get proposal data from on-chain (Ponder-based, for Moonriver)
348
319
  */
@@ -350,258 +321,85 @@ export const getProposalData = async (params: {
350
321
  environment: Environment;
351
322
  id?: number;
352
323
  }) => {
353
- if (params.environment.contracts.governor) {
354
- let count = 0n;
355
- let quorum = 0n;
356
-
357
- if (params.environment.chainId === moonriver.id) {
358
- [count, quorum] = await Promise.all([
359
- params.environment.contracts.governor.read.proposalCount(),
360
- params.environment.contracts.governor.read.getQuorum(),
361
- ]);
362
- } else {
363
- [count, quorum] = await Promise.all([
364
- params.environment.contracts.governor.read.proposalCount(),
365
- params.environment.contracts.governor.read.quorumVotes(),
366
- ]);
367
- }
368
-
369
- if (params.id) {
370
- if (BigInt(params.id) > count) {
371
- return [];
324
+ try {
325
+ if (params.environment.contracts.governor) {
326
+ let count = 0n;
327
+ let quorum = 0n;
328
+
329
+ if (params.environment.chainId === moonriver.id) {
330
+ [count, quorum] = await Promise.all([
331
+ params.environment.contracts.governor.read.proposalCount(),
332
+ params.environment.contracts.governor.read.getQuorum(),
333
+ ]);
334
+ } else {
335
+ [count, quorum] = await Promise.all([
336
+ params.environment.contracts.governor.read.proposalCount(),
337
+ params.environment.contracts.governor.read.quorumVotes(),
338
+ ]);
372
339
  }
373
- }
374
-
375
- const ids = params.id
376
- ? [BigInt(params.id)]
377
- : Array.from({ length: Number(count) }, (_, i) => count - BigInt(i));
378
-
379
- const proposalDataCall = Promise.all(
380
- ids.map((id) =>
381
- params.environment.contracts.governor?.read.proposals([id]),
382
- ),
383
- );
384
-
385
- const proposalStateCall = Promise.all(
386
- ids.map((id) => params.environment.contracts.governor?.read.state([id])),
387
- );
388
-
389
- const [proposalsData, proposalsState] = await Promise.all([
390
- proposalDataCall,
391
- proposalStateCall,
392
- ]);
393
-
394
- const proposals = proposalsData?.map((item, index: number) => {
395
- const state = proposalsState?.[index]!;
396
-
397
- const [
398
- id,
399
- proposer,
400
- eta,
401
- startTimestamp,
402
- endTimestamp,
403
- startBlock,
404
- forVotes,
405
- againstVotes,
406
- abstainVotes,
407
- totalVotes,
408
- canceled,
409
- executed,
410
- ] = item!;
411
-
412
- const proposal: Proposal = {
413
- chainId: params.environment.chainId,
414
- id: Number(id),
415
- proposalId: Number(id),
416
- proposer,
417
- eta: Number(eta),
418
- startTimestamp: Number(startTimestamp),
419
- endTimestamp: Number(endTimestamp),
420
- startBlock: Number(startBlock),
421
- forVotes: new Amount(forVotes, 18),
422
- againstVotes: new Amount(againstVotes, 18),
423
- abstainVotes: new Amount(abstainVotes, 18),
424
- totalVotes: new Amount(totalVotes, 18),
425
- canceled,
426
- executed,
427
- quorum: new Amount(quorum, 18),
428
- state,
429
- };
430
-
431
- return proposal;
432
- });
433
-
434
- return proposals;
435
- } else {
436
- return [];
437
- }
438
- };
439
-
440
- /**
441
- * Get cross-chain proposal data (Ponder-based, for Moonriver)
442
- */
443
- export const getCrossChainProposalData = async (params: {
444
- environment: Environment;
445
- id?: number;
446
- }) => {
447
- if (params.environment.contracts.governor) {
448
- const xcGovernanceSettings = params.environment.custom.governance;
449
- if (
450
- params.environment.contracts.multichainGovernor &&
451
- xcGovernanceSettings &&
452
- xcGovernanceSettings.chainIds.length > 0
453
- ) {
454
- const xcEnvironments = xcGovernanceSettings.chainIds
455
- .map((chainId) =>
456
- (Object.values(publicEnvironments) as Environment[]).find(
457
- (env) => env.chainId === chainId,
458
- ),
459
- )
460
- .filter((xcEnvironment) => !!xcEnvironment)
461
- .filter(
462
- (xcEnvironment) =>
463
- xcEnvironment!.custom?.wormhole?.chainId &&
464
- xcEnvironment!.contracts.voteCollector,
465
- );
466
-
467
- const [xcCount, xcQuorum] = await Promise.all([
468
- params.environment.contracts.multichainGovernor.read.proposalCount(),
469
- params.environment.contracts.multichainGovernor.read.quorum(),
470
- ]);
471
340
 
472
341
  if (params.id) {
473
- params.id =
474
- Number(params.id) -
475
- (params.environment.custom?.governance?.proposalIdOffset || 0);
476
-
477
- if (params.id < 0) {
342
+ if (BigInt(params.id) > count) {
478
343
  return [];
479
- } else {
480
- if (BigInt(params.id) > xcCount) {
481
- return [];
482
- }
483
344
  }
484
345
  }
485
346
 
486
347
  const ids = params.id
487
348
  ? [BigInt(params.id)]
488
- : Array.from(
489
- { length: Number(xcCount) },
490
- (_, i) => xcCount - BigInt(i),
491
- );
349
+ : Array.from({ length: Number(count) }, (_, i) => count - BigInt(i));
492
350
 
493
- const xcProposalsDataCall = Promise.all(
351
+ const proposalDataCall = Promise.all(
494
352
  ids.map((id) =>
495
- params.environment.contracts.multichainGovernor?.read.proposals([id]),
353
+ params.environment.contracts.governor?.read.proposals([id]),
496
354
  ),
497
355
  );
498
356
 
499
- const xcProposalsStateCall = Promise.all(
357
+ const proposalStateCall = Promise.all(
500
358
  ids.map((id) =>
501
- params.environment.contracts.multichainGovernor?.read.state([id]),
359
+ params.environment.contracts.governor?.read.state([id]),
502
360
  ),
503
361
  );
504
362
 
505
- const xcVotesCall = Promise.all(
506
- xcEnvironments.map((xcEnvironment) =>
507
- Promise.all(
508
- ids.map((id) =>
509
- params.environment.contracts.multichainGovernor?.read.chainVoteCollectorVotes(
510
- [(xcEnvironment!.custom as any).wormhole.chainId, id],
511
- ),
512
- ),
513
- ),
514
- ),
515
- );
516
-
517
- const [xcProposalsData, xcProposalsState, xcVotes] = await Promise.all([
518
- xcProposalsDataCall,
519
- xcProposalsStateCall,
520
- xcVotesCall,
363
+ const [proposalsData, proposalsState] = await Promise.all([
364
+ proposalDataCall,
365
+ proposalStateCall,
521
366
  ]);
522
367
 
523
- const proposals = ids.map((xcId, proposalIndex: number) => {
524
- const state = xcProposalsState?.[proposalIndex]!;
525
- const id =
526
- Number(xcId) +
527
- (params.environment.custom?.governance?.proposalIdOffset || 0);
528
-
529
- const votesCollected = false;
530
-
531
- const votes = xcVotes.reduce(
532
- (prevVotes, currVotes) => {
533
- const voteData = currVotes[proposalIndex];
534
- if (!voteData) {
535
- return prevVotes;
536
- }
537
-
538
- // chainVoteCollectorVotes returns [forVotes, againstVotes, abstainVotes]
539
- const forVotes = voteData[0] || 0n;
540
- const againstVotes = voteData[1] || 0n;
541
- const abstainVotes = voteData[2] || 0n;
542
- const totalVotes = forVotes + againstVotes + abstainVotes;
543
-
544
- return {
545
- totalVotes: prevVotes.totalVotes + totalVotes,
546
- forVotes: prevVotes.forVotes + forVotes,
547
- againstVotes: prevVotes.againstVotes + againstVotes,
548
- abstainVotes: prevVotes.abstainVotes + abstainVotes,
549
- };
550
- },
551
- { totalVotes: 0n, forVotes: 0n, againstVotes: 0n, abstainVotes: 0n },
552
- );
553
-
554
- const proposalData = xcProposalsData?.[proposalIndex];
555
- if (!proposalData) {
556
- throw new Error(`Proposal data not found for index ${proposalIndex}`);
557
- }
368
+ const proposals = proposalsData?.map((item, index: number) => {
369
+ const state = proposalsState?.[index]!;
558
370
 
559
371
  const [
372
+ id,
560
373
  proposer,
561
- _voteSnapshotTimestamp,
562
- votingStartTime,
563
- votingEndTime,
564
- crossChainVoteCollectionEndTimestamp,
565
- voteSnapshotBlock,
566
- proposalForVotes,
567
- proposalAgainstVotes,
568
- proposalAbstainVotes,
569
- proposalTotalVotes,
374
+ eta,
375
+ startTimestamp,
376
+ endTimestamp,
377
+ startBlock,
378
+ forVotes,
379
+ againstVotes,
380
+ abstainVotes,
381
+ totalVotes,
570
382
  canceled,
571
383
  executed,
572
- ] = proposalData;
573
-
574
- const multichainState = (
575
- MultichainProposalStateMapping as { [key: number]: ProposalState }
576
- )[state]!;
384
+ ] = item!;
577
385
 
578
386
  const proposal: Proposal = {
579
387
  chainId: params.environment.chainId,
580
- id,
581
- proposalId: Number(xcId),
388
+ id: Number(id),
389
+ proposalId: Number(id),
582
390
  proposer,
583
- eta: Number(crossChainVoteCollectionEndTimestamp),
584
- startTimestamp: Number(votingStartTime),
585
- endTimestamp: Number(votingEndTime),
586
- startBlock: Number(voteSnapshotBlock),
587
- forVotes: new Amount(proposalForVotes + votes.forVotes, 18),
588
- againstVotes: new Amount(
589
- proposalAgainstVotes + votes.againstVotes,
590
- 18,
591
- ),
592
- abstainVotes: new Amount(
593
- proposalAbstainVotes + votes.abstainVotes,
594
- 18,
595
- ),
596
- totalVotes: new Amount(proposalTotalVotes + votes.totalVotes, 18),
391
+ eta: Number(eta),
392
+ startTimestamp: Number(startTimestamp),
393
+ endTimestamp: Number(endTimestamp),
394
+ startBlock: Number(startBlock),
395
+ forVotes: new Amount(forVotes, 18),
396
+ againstVotes: new Amount(againstVotes, 18),
397
+ abstainVotes: new Amount(abstainVotes, 18),
398
+ totalVotes: new Amount(totalVotes, 18),
597
399
  canceled,
598
400
  executed,
599
- quorum: new Amount(xcQuorum, 18),
600
- state: multichainState,
601
- multichain: {
602
- id: Number(xcId),
603
- votesCollected,
604
- },
401
+ quorum: new Amount(quorum, 18),
402
+ state,
605
403
  };
606
404
 
607
405
  return proposal;
@@ -611,106 +409,347 @@ export const getCrossChainProposalData = async (params: {
611
409
  } else {
612
410
  return [];
613
411
  }
614
- } else {
412
+ } catch (error) {
413
+ console.warn(
414
+ `[getProposalData] RPC failed for chain ${params.environment.chainId}:`,
415
+ error,
416
+ );
417
+ params.environment.onError?.(error, {
418
+ source: "governance-proposals",
419
+ chainId: params.environment.chainId,
420
+ });
615
421
  return [];
616
422
  }
617
423
  };
618
424
 
619
425
  /**
620
- * Get extended proposal data from Ponder (for Moonriver)
426
+ * Get cross-chain proposal data (Ponder-based, for Moonriver)
621
427
  */
428
+ export const getCrossChainProposalData = async (params: {
429
+ environment: Environment;
430
+ id?: number;
431
+ }) => {
432
+ try {
433
+ if (params.environment.contracts.governor) {
434
+ const xcGovernanceSettings = params.environment.custom.governance;
435
+ if (
436
+ params.environment.contracts.multichainGovernor &&
437
+ xcGovernanceSettings &&
438
+ xcGovernanceSettings.chainIds.length > 0
439
+ ) {
440
+ const xcEnvironments = xcGovernanceSettings.chainIds
441
+ .map((chainId) =>
442
+ (Object.values(publicEnvironments) as Environment[]).find(
443
+ (env) => env.chainId === chainId,
444
+ ),
445
+ )
446
+ .filter((xcEnvironment) => !!xcEnvironment)
447
+ .filter(
448
+ (xcEnvironment) =>
449
+ xcEnvironment!.custom?.wormhole?.chainId &&
450
+ xcEnvironment!.contracts.voteCollector,
451
+ );
452
+
453
+ const [xcCount, xcQuorum] = await Promise.all([
454
+ params.environment.contracts.multichainGovernor.read.proposalCount(),
455
+ params.environment.contracts.multichainGovernor.read.quorum(),
456
+ ]);
457
+
458
+ if (params.id) {
459
+ params.id =
460
+ Number(params.id) -
461
+ (params.environment.custom?.governance?.proposalIdOffset || 0);
462
+
463
+ if (params.id < 0) return [];
464
+ if (BigInt(params.id) > xcCount) return [];
465
+ }
466
+
467
+ const ids = params.id
468
+ ? [BigInt(params.id)]
469
+ : Array.from(
470
+ { length: Number(xcCount) },
471
+ (_, i) => xcCount - BigInt(i),
472
+ );
473
+
474
+ const xcProposalsDataCall = Promise.all(
475
+ ids.map((id) =>
476
+ params.environment.contracts.multichainGovernor?.read.proposals([
477
+ id,
478
+ ]),
479
+ ),
480
+ );
481
+
482
+ const xcProposalsStateCall = Promise.all(
483
+ ids.map((id) =>
484
+ params.environment.contracts.multichainGovernor?.read.state([id]),
485
+ ),
486
+ );
487
+
488
+ const xcVotesCall = Promise.all(
489
+ xcEnvironments.map((xcEnvironment) =>
490
+ Promise.all(
491
+ ids.map((id) =>
492
+ params.environment.contracts.multichainGovernor?.read.chainVoteCollectorVotes(
493
+ [(xcEnvironment!.custom as any).wormhole.chainId, id],
494
+ ),
495
+ ),
496
+ ),
497
+ ),
498
+ );
499
+
500
+ const [xcProposalsData, xcProposalsState, xcVotes] = await Promise.all([
501
+ xcProposalsDataCall,
502
+ xcProposalsStateCall,
503
+ xcVotesCall,
504
+ ]);
505
+
506
+ const proposals = ids.map((xcId, proposalIndex: number) => {
507
+ const state = xcProposalsState?.[proposalIndex]!;
508
+ const id =
509
+ Number(xcId) +
510
+ (params.environment.custom?.governance?.proposalIdOffset || 0);
511
+
512
+ const votesCollected = false;
513
+
514
+ const votes = xcVotes.reduce(
515
+ (prevVotes, currVotes) => {
516
+ const voteData = currVotes[proposalIndex];
517
+ if (!voteData) {
518
+ return prevVotes;
519
+ }
520
+
521
+ // chainVoteCollectorVotes returns [forVotes, againstVotes, abstainVotes]
522
+ const forVotes = voteData[0] || 0n;
523
+ const againstVotes = voteData[1] || 0n;
524
+ const abstainVotes = voteData[2] || 0n;
525
+ const totalVotes = forVotes + againstVotes + abstainVotes;
526
+
527
+ return {
528
+ totalVotes: prevVotes.totalVotes + totalVotes,
529
+ forVotes: prevVotes.forVotes + forVotes,
530
+ againstVotes: prevVotes.againstVotes + againstVotes,
531
+ abstainVotes: prevVotes.abstainVotes + abstainVotes,
532
+ };
533
+ },
534
+ {
535
+ totalVotes: 0n,
536
+ forVotes: 0n,
537
+ againstVotes: 0n,
538
+ abstainVotes: 0n,
539
+ },
540
+ );
541
+
542
+ const proposalData = xcProposalsData?.[proposalIndex];
543
+ if (!proposalData) {
544
+ throw new Error(
545
+ `Proposal data not found for index ${proposalIndex}`,
546
+ );
547
+ }
548
+
549
+ const [
550
+ proposer,
551
+ _voteSnapshotTimestamp,
552
+ votingStartTime,
553
+ votingEndTime,
554
+ crossChainVoteCollectionEndTimestamp,
555
+ voteSnapshotBlock,
556
+ proposalForVotes,
557
+ proposalAgainstVotes,
558
+ proposalAbstainVotes,
559
+ proposalTotalVotes,
560
+ canceled,
561
+ executed,
562
+ ] = proposalData;
563
+
564
+ const multichainState = (
565
+ MultichainProposalStateMapping as { [key: number]: ProposalState }
566
+ )[state]!;
567
+
568
+ const proposal: Proposal = {
569
+ chainId: params.environment.chainId,
570
+ id,
571
+ proposalId: Number(xcId),
572
+ proposer,
573
+ eta: Number(crossChainVoteCollectionEndTimestamp),
574
+ startTimestamp: Number(votingStartTime),
575
+ endTimestamp: Number(votingEndTime),
576
+ startBlock: Number(voteSnapshotBlock),
577
+ forVotes: new Amount(proposalForVotes + votes.forVotes, 18),
578
+ againstVotes: new Amount(
579
+ proposalAgainstVotes + votes.againstVotes,
580
+ 18,
581
+ ),
582
+ abstainVotes: new Amount(
583
+ proposalAbstainVotes + votes.abstainVotes,
584
+ 18,
585
+ ),
586
+ totalVotes: new Amount(proposalTotalVotes + votes.totalVotes, 18),
587
+ canceled,
588
+ executed,
589
+ quorum: new Amount(xcQuorum, 18),
590
+ state: multichainState,
591
+ multichain: {
592
+ id: Number(xcId),
593
+ votesCollected,
594
+ },
595
+ };
596
+
597
+ return proposal;
598
+ });
599
+
600
+ return proposals;
601
+ } else {
602
+ return [];
603
+ }
604
+ } else {
605
+ return [];
606
+ }
607
+ } catch (error) {
608
+ console.warn(
609
+ `[getCrossChainProposalData] RPC failed for chain ${params.environment.chainId}:`,
610
+ error,
611
+ );
612
+ params.environment.onError?.(error, {
613
+ source: "governance-proposals",
614
+ chainId: params.environment.chainId,
615
+ });
616
+ return [];
617
+ }
618
+ };
619
+
620
+ export const appendProposalExtendedData = (
621
+ proposals: Proposal[],
622
+ extendedDatas: PonderExtendedProposalData[],
623
+ ) => {
624
+ proposals.forEach((proposal) => {
625
+ const extendedData = extendedDatas.find(
626
+ (item) => item.id === proposal.proposalId,
627
+ );
628
+
629
+ if (extendedData) {
630
+ proposal.title = extendedData.title;
631
+ proposal.calldatas = extendedData.calldatas;
632
+ proposal.description = extendedData.description;
633
+ proposal.signatures = extendedData.signatures;
634
+ proposal.stateChanges = extendedData.stateChanges.map((change) => ({
635
+ blockNumber: change.blockNumber,
636
+ transactionHash: change.transactionHash,
637
+ state: change.state,
638
+ chainId: proposal.chainId,
639
+ }));
640
+ proposal.subtitle = extendedData.subtitle;
641
+ proposal.targets = extendedData.targets;
642
+ }
643
+ });
644
+ };
645
+
622
646
  export const getExtendedProposalData = async (params: {
623
647
  environment: Environment;
624
648
  id?: number;
625
649
  }): Promise<PonderExtendedProposalData[]> => {
626
- let result: PonderExtendedProposalData[] = [];
650
+ const result: PonderExtendedProposalData[] = [];
627
651
  let lastId = -1;
628
652
  let shouldContinue = true;
629
-
630
- while (shouldContinue) {
631
- const response = await axios.post<{
632
- data: {
633
- proposals: {
634
- items: {
635
- proposalId: number;
636
- description: string;
637
- targets: string[];
638
- calldatas: string[];
639
- signatures: string[];
640
- stateChanges: {
641
- items: {
642
- txnHash: string;
643
- blockNumber: number;
644
- newState: string;
645
- }[];
646
- };
647
- }[];
653
+ const MAX_PAGES = 100;
654
+ let page = 0;
655
+
656
+ try {
657
+ while (shouldContinue && page < MAX_PAGES) {
658
+ page++;
659
+ const response = await axios.post<{
660
+ data: {
661
+ proposals: {
662
+ items: {
663
+ proposalId: number;
664
+ description: string;
665
+ targets: string[];
666
+ calldatas: string[];
667
+ signatures: string[];
668
+ stateChanges: {
669
+ items: {
670
+ txnHash: string;
671
+ blockNumber: number;
672
+ newState: string;
673
+ }[];
674
+ };
675
+ }[];
676
+ };
648
677
  };
649
- };
650
- }>("https://ponder-eu2.moonwell.fi", {
651
- query: `
652
- query {
653
- proposals(
654
- limit: 1000,
655
- orderDirection: "desc",
656
- orderBy: "proposalId",
657
- where: {
658
- chainId: ${params.environment.chainId}
659
- ${params.id ? `, proposalId: ${params.id}` : lastId >= 0 ? `, proposalId_lt: ${lastId}` : ""}
660
- }
661
- ) {
662
- items {
663
- id
664
- proposalId
665
- description
666
- targets
667
- calldatas
668
- signatures
669
- stateChanges(orderBy: "blockNumber") {
670
- items {
671
- txnHash
672
- blockNumber
673
- newState
678
+ }>("https://ponder-eu2.moonwell.fi", {
679
+ query: `
680
+ query {
681
+ proposals(
682
+ limit: 1000,
683
+ orderDirection: "desc",
684
+ orderBy: "proposalId",
685
+ where: {
686
+ chainId: ${params.environment.chainId}
687
+ ${params.id ? `, proposalId: ${params.id}` : lastId >= 0 ? `, proposalId_lt: ${lastId}` : ""}
688
+ }
689
+ ) {
690
+ items {
691
+ id
692
+ proposalId
693
+ description
694
+ targets
695
+ calldatas
696
+ signatures
697
+ stateChanges(orderBy: "blockNumber") {
698
+ items {
699
+ txnHash
700
+ blockNumber
701
+ newState
702
+ }
674
703
  }
675
704
  }
676
705
  }
677
706
  }
678
- }
679
- `,
680
- });
681
-
682
- if (response.status === 200 && response.data?.data?.proposals) {
683
- const proposals = response.data.data.proposals.items.map((item) => {
684
- const extendedProposalData: PonderExtendedProposalData = {
685
- id: item.proposalId,
686
- title: `Proposal #${item.proposalId}`,
687
- subtitle: extractProposalSubtitle(item.description),
688
- description: item.description,
689
- calldatas: item.calldatas,
690
- signatures: item.signatures,
691
- stateChanges: item.stateChanges.items.map((change) => {
692
- return {
693
- blockNumber: change.blockNumber,
694
- state: change.newState,
695
- transactionHash: change.txnHash,
696
- };
697
- }),
698
- targets: item.targets,
699
- };
700
-
701
- return extendedProposalData;
707
+ `,
702
708
  });
703
709
 
704
- if (proposals.length < 1000 || proposals.length === 0) {
705
- shouldContinue = false;
710
+ if (response.status === 200 && response.data?.data?.proposals) {
711
+ const proposals = response.data.data.proposals.items.map((item) => {
712
+ const extendedProposalData: PonderExtendedProposalData = {
713
+ id: item.proposalId,
714
+ title: `Proposal #${item.proposalId}`,
715
+ subtitle: extractProposalSubtitle(item.description),
716
+ description: item.description,
717
+ calldatas: item.calldatas,
718
+ signatures: item.signatures,
719
+ stateChanges: item.stateChanges.items.map((change) => {
720
+ return {
721
+ blockNumber: change.blockNumber,
722
+ state: change.newState,
723
+ transactionHash: change.txnHash,
724
+ };
725
+ }),
726
+ targets: item.targets,
727
+ };
728
+
729
+ return extendedProposalData;
730
+ });
731
+
732
+ if (proposals.length < 1000 || proposals.length === 0) {
733
+ shouldContinue = false;
734
+ } else {
735
+ lastId = last(proposals)!.id;
736
+ }
737
+
738
+ result.push(...proposals);
706
739
  } else {
707
- lastId = last(proposals)!.id;
740
+ shouldContinue = false;
708
741
  }
709
-
710
- result = result.concat(proposals);
711
- } else {
712
- shouldContinue = false;
713
742
  }
743
+ } catch (error) {
744
+ console.warn(
745
+ `[getExtendedProposalData] Ponder failed for chain ${params.environment.chainId}:`,
746
+ error,
747
+ );
748
+ params.environment.onError?.(error, {
749
+ source: "governance-proposals",
750
+ chainId: params.environment.chainId,
751
+ });
752
+ return result;
714
753
  }
715
754
 
716
755
  return result;