@moonwell-fi/moonwell-sdk 0.20.3 → 0.20.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/_cjs/actions/governance/common.js +15 -2
  3. package/_cjs/actions/governance/common.js.map +1 -1
  4. package/_cjs/actions/governance/governor-api-client.js +3 -2
  5. package/_cjs/actions/governance/governor-api-client.js.map +1 -1
  6. package/_cjs/actions/governance/proposals/common.js +11 -296
  7. package/_cjs/actions/governance/proposals/common.js.map +1 -1
  8. package/_cjs/actions/governance/proposals/getProposal.js +9 -25
  9. package/_cjs/actions/governance/proposals/getProposal.js.map +1 -1
  10. package/_cjs/actions/governance/proposals/getProposals.js +23 -14
  11. package/_cjs/actions/governance/proposals/getProposals.js.map +1 -1
  12. package/_cjs/errors/version.js +1 -1
  13. package/_cjs/types/proposal.js.map +1 -1
  14. package/_esm/actions/governance/common.js +29 -3
  15. package/_esm/actions/governance/common.js.map +1 -1
  16. package/_esm/actions/governance/governor-api-client.js +21 -4
  17. package/_esm/actions/governance/governor-api-client.js.map +1 -1
  18. package/_esm/actions/governance/ipfs.js +2 -2
  19. package/_esm/actions/governance/proposals/common.js +28 -302
  20. package/_esm/actions/governance/proposals/common.js.map +1 -1
  21. package/_esm/actions/governance/proposals/getProposal.js +23 -35
  22. package/_esm/actions/governance/proposals/getProposal.js.map +1 -1
  23. package/_esm/actions/governance/proposals/getProposals.js +48 -20
  24. package/_esm/actions/governance/proposals/getProposals.js.map +1 -1
  25. package/_esm/errors/version.js +1 -1
  26. package/_esm/types/proposal.js.map +1 -1
  27. package/_types/actions/governance/common.d.ts.map +1 -1
  28. package/_types/actions/governance/getUserVoteReceipt.d.ts +4 -4
  29. package/_types/actions/governance/governor-api-client.d.ts +34 -4
  30. package/_types/actions/governance/governor-api-client.d.ts.map +1 -1
  31. package/_types/actions/governance/ipfs.d.ts +2 -2
  32. package/_types/actions/governance/proposals/common.d.ts +12 -39
  33. package/_types/actions/governance/proposals/common.d.ts.map +1 -1
  34. package/_types/actions/governance/proposals/getProposal.d.ts +2 -1
  35. package/_types/actions/governance/proposals/getProposal.d.ts.map +1 -1
  36. package/_types/actions/governance/proposals/getProposals.d.ts.map +1 -1
  37. package/_types/errors/version.d.ts +1 -1
  38. package/_types/types/proposal.d.ts +11 -0
  39. package/_types/types/proposal.d.ts.map +1 -1
  40. package/actions/governance/common.ts +39 -3
  41. package/actions/governance/getUserVoteReceipt.ts +4 -4
  42. package/actions/governance/governor-api-client.ts +35 -4
  43. package/actions/governance/ipfs.ts +2 -2
  44. package/actions/governance/proposals/common.ts +28 -466
  45. package/actions/governance/proposals/getProposal.ts +25 -49
  46. package/actions/governance/proposals/getProposals.ts +57 -30
  47. package/errors/version.ts +1 -1
  48. package/package.json +1 -1
  49. package/types/proposal.ts +11 -0
@@ -8,11 +8,7 @@ import { type Proposal, ProposalState } from "../../../types/proposal.js";
8
8
  import { type ApiProposal, fetchAllProposals } from "../governor-api-client.js";
9
9
  import { resolveIpfsDescriptions } from "../ipfs.js";
10
10
  import {
11
- appendProposalExtendedData,
12
11
  formatApiProposalData,
13
- getCrossChainProposalData,
14
- getExtendedProposalData,
15
- getProposalData,
16
12
  getProposalsOnChainData,
17
13
  readCrossChainQuorums,
18
14
  } from "./common.js";
@@ -49,10 +45,10 @@ export async function getProposals<
49
45
  const allProposals = await Promise.all(
50
46
  governanceEnvironments.map(async (governanceEnvironment) => {
51
47
  if (governanceEnvironment.chainId === moonbeam.id) {
52
- // Moonbeam: Use new Governor API
48
+ // Moonbeam + Ethereum: Governor API (chainIds 1 and 1284)
53
49
  return getMoonbeamProposals(governanceEnvironment);
54
50
  } else {
55
- // Moonriver: Use old Ponder approach
51
+ // Moonriver: Governor API, single legacy governor (chainId 1285)
56
52
  return getMoonriverProposals(governanceEnvironment);
57
53
  }
58
54
  }),
@@ -109,6 +105,53 @@ async function getMoonbeamProposals(
109
105
  }
110
106
  });
111
107
 
108
+ return buildProposals(apiProposals, governanceEnvironment);
109
+ }
110
+
111
+ /**
112
+ * Fetch proposals for Moonriver using the Governor API.
113
+ *
114
+ * Moonriver runs a single legacy standalone governor (no multichain governor),
115
+ * so we fetch only its chainId from the same lunar indexer and reuse the shared
116
+ * pipeline. `getProposalsOnChainData` classifies these as non-multichain and
117
+ * reads state/quorum from the legacy governor (via `getQuorum`).
118
+ */
119
+ async function getMoonriverProposals(
120
+ governanceEnvironment: Environment,
121
+ ): Promise<Proposal[]> {
122
+ // Moonriver is a single chain, so there's no other chain to "continue with"
123
+ // like the Moonbeam fan-out — but a bare throw would reject the whole
124
+ // `Promise.all` in getProposals and drop Moonbeam/Ethereum results too. Mirror
125
+ // the per-chain handling getMoonbeamProposals uses: report the outage via
126
+ // onError and degrade to an empty Moonriver list instead of rejecting.
127
+ let apiProposals: ApiProposal[] = [];
128
+ try {
129
+ apiProposals = await fetchAllProposals(governanceEnvironment, {
130
+ chainId: moonriver.id,
131
+ });
132
+ } catch (reason) {
133
+ console.warn(
134
+ `[getProposals] Failed to fetch proposals for chainId=${moonriver.id}; continuing with an empty Moonriver list.`,
135
+ reason,
136
+ );
137
+ governanceEnvironment.onError?.(reason, {
138
+ source: "governance-proposals",
139
+ chainId: moonriver.id,
140
+ });
141
+ }
142
+ return buildProposals(apiProposals, governanceEnvironment);
143
+ }
144
+
145
+ /**
146
+ * Shared Governor-API pipeline: resolve IPFS descriptions + cross-chain quorums
147
+ * in parallel, read on-chain data, then map each ApiProposal to a Proposal.
148
+ * Used by both the Moonbeam/Ethereum and Moonriver paths so the mapping stays
149
+ * in one place.
150
+ */
151
+ async function buildProposals(
152
+ apiProposals: ApiProposal[],
153
+ governanceEnvironment: Environment,
154
+ ): Promise<Proposal[]> {
112
155
  // IPFS resolution and cross-chain quorum reads are independent — run them in
113
156
  // parallel to save one network round-trip on the proposal list path.
114
157
  const [, crossChainQuorums] = await Promise.all([
@@ -180,11 +223,18 @@ async function getMoonbeamProposals(
180
223
  description: apiProposal.description,
181
224
  targets: apiProposal.targets,
182
225
  calldatas: apiProposal.calldatas,
183
- signatures: [],
226
+ // Legacy-governor proposals (Moonriver, early Moonbeam) carry the function
227
+ // signature separately from the selector-less calldata; pass it through so
228
+ // consumers can decode the call. Empty for multichain-governor proposals.
229
+ signatures: apiProposal.signatures ?? [],
184
230
  stateChanges: formattedData.stateChanges,
185
231
  environment: governanceEnvironment,
186
232
  };
187
233
 
234
+ if (apiProposal.snapshotBlocks) {
235
+ proposal.snapshotBlocks = apiProposal.snapshotBlocks;
236
+ }
237
+
188
238
  if (isMultichain) {
189
239
  proposal.multichain = {
190
240
  id: apiProposal.proposalId,
@@ -197,26 +247,3 @@ async function getMoonbeamProposals(
197
247
 
198
248
  return proposals;
199
249
  }
200
-
201
- /**
202
- * Fetch proposals for Moonriver using the old Ponder-based approach
203
- */
204
- async function getMoonriverProposals(
205
- governanceEnvironment: Environment,
206
- ): Promise<Proposal[]> {
207
- const [_proposals, _xcProposals, _extendedDatas] = await Promise.all([
208
- getProposalData({ environment: governanceEnvironment }),
209
- getCrossChainProposalData({ environment: governanceEnvironment }),
210
- getExtendedProposalData({ environment: governanceEnvironment }),
211
- ]);
212
-
213
- const proposals = [..._proposals, ..._xcProposals];
214
-
215
- proposals.forEach((proposal) => {
216
- proposal.environment = governanceEnvironment;
217
- });
218
-
219
- appendProposalExtendedData(proposals, _extendedDatas);
220
-
221
- return proposals;
222
- }
package/errors/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '0.20.3'
1
+ export const version = '0.20.5'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@moonwell-fi/moonwell-sdk",
3
3
  "description": "TypeScript Interface for Moonwell",
4
- "version": "0.20.3",
4
+ "version": "0.20.5",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
package/types/proposal.ts CHANGED
@@ -23,6 +23,17 @@ export type Proposal = {
23
23
  id: number;
24
24
  votesCollected: boolean;
25
25
  };
26
+ /**
27
+ * Authoritative per-chain voting-power snapshot blocks resolved by the
28
+ * lunar-indexer, keyed by chain name (`mainnet` → 1, `base` → 8453,
29
+ * `optimism` → 10, `moonbeam` → 1284). Block numbers are decimal strings.
30
+ *
31
+ * Present on indexer-sourced multichain proposals; absent for older
32
+ * proposals indexed before the field existed and for on-chain (Moonriver)
33
+ * proposals. Consumers reading voting power should prefer these blocks over
34
+ * resolving the snapshot timestamp to a block client-side.
35
+ */
36
+ snapshotBlocks?: Record<string, string>;
26
37
  //proposal extended data
27
38
  title?: string;
28
39
  subtitle?: string;