@ledgerhq/coin-celo 2.6.1-nightly.20260627030713 → 2.7.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.
package/CHANGELOG.md CHANGED
@@ -1,29 +1,42 @@
1
1
  # @ledgerhq/coin-celo
2
2
 
3
- ## 2.6.1-nightly.20260627030713
3
+ ## 2.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#18520](https://github.com/LedgerHQ/ledger-live/pull/18520) [`4ace552`](https://github.com/LedgerHQ/ledger-live/commit/4ace55213a4f1869980aab5160683bb120c65292) Thanks [@gre-ledger](https://github.com/gre-ledger)! - Move the dummy fee-estimation recipient out of `@ledgerhq/cryptoassets` (`abandonseed.ts`, now deleted) into each coin family. Every account bridge now exposes a required `getEstimationRecipient(account)` returning a valid recipient (or throwing for an unmapped currency, like the former `getAbandonSeedAddress`), and the swap layer dispatches through it instead of the central address map.
4
8
 
5
9
  ### Patch Changes
6
10
 
7
- - [#18917](https://github.com/LedgerHQ/ledger-live/pull/18917) [`3b9ad8e`](https://github.com/LedgerHQ/ledger-live/commit/3b9ad8e33408679af1a3737c6cb3a2473a044c07) Thanks [@YazhuEth](https://github.com/YazhuEth)! - celo: deprecate the "Ledger by Figment" validator. It is no longer shown or selectable in the vote flow and is never the default — the validator list is now ranked by TVL with none selected by default. Existing delegations remain fully manageable (unvote / unlock / withdraw).
11
+ - Updated dependencies [[`636a4cb`](https://github.com/LedgerHQ/ledger-live/commit/636a4cbc5ae01364af425e3837cecf1ce4d3f3bc), [`48dbd53`](https://github.com/LedgerHQ/ledger-live/commit/48dbd533a7a505cbb37989f8ce94f273f84bc7d2), [`ad68778`](https://github.com/LedgerHQ/ledger-live/commit/ad68778ad71686c9e4f397276917e606a099f573), [`13aeeb6`](https://github.com/LedgerHQ/ledger-live/commit/13aeeb6186997b433785e542ed1dafa6afde2267), [`1f41eee`](https://github.com/LedgerHQ/ledger-live/commit/1f41eee5b4dc6aa50accd94e5a0d6c98fcf76e23), [`b8a0765`](https://github.com/LedgerHQ/ledger-live/commit/b8a0765d7ac1ac1a60456f9c604e7a694e38bd84), [`93a84fb`](https://github.com/LedgerHQ/ledger-live/commit/93a84fbadb2b1a0e529e2ffa08ca1de790355934), [`798081d`](https://github.com/LedgerHQ/ledger-live/commit/798081db3e427c8d2d09930ceb836703146ca1ba), [`1f11587`](https://github.com/LedgerHQ/ledger-live/commit/1f11587b4681429aa9be2dc50035f292e0394108), [`ebda9d8`](https://github.com/LedgerHQ/ledger-live/commit/ebda9d88805501f4c2c03fef0fe24f116a8a2a6c), [`4ace552`](https://github.com/LedgerHQ/ledger-live/commit/4ace55213a4f1869980aab5160683bb120c65292), [`37eba10`](https://github.com/LedgerHQ/ledger-live/commit/37eba10db15542fb7859bafac772e6d280650872), [`ca20506`](https://github.com/LedgerHQ/ledger-live/commit/ca20506c138a1cfb9c254f61e6bb930aea4c6ab8)]:
12
+ - @ledgerhq/types-live@6.113.0
13
+ - @ledgerhq/coin-evm@4.4.0
14
+ - @ledgerhq/errors@6.37.0
15
+ - @ledgerhq/live-env@2.40.0
16
+ - @ledgerhq/cryptoassets@13.53.0
17
+ - @ledgerhq/devices@8.16.0
18
+ - @ledgerhq/ledger-wallet-framework@2.2.1
19
+ - @ledgerhq/hw-app-eth@7.8.8
20
+ - @ledgerhq/live-network@2.6.6
8
21
 
9
- - [#18970](https://github.com/LedgerHQ/ledger-live/pull/18970) [`0c9b5fc`](https://github.com/LedgerHQ/ledger-live/commit/0c9b5fc79922a62a2ca124d1c251f177ac3a3969) Thanks [@YazhuEth](https://github.com/YazhuEth)! - celo: stop offering saturated validator groups in the vote flow, and refresh the validator list properly.
22
+ ## 2.7.0-next.0
10
23
 
11
- - The capacity check now compares the group's vote cap (`getNumVotesReceivable`) against its current total votes instead of just checking the cap is positive, so groups that are already at or above their cap are filtered out and no longer revert with "vote cap exceeded" when voting.
12
- - `preload` now always refetches the validator groups (gated by `preloadMaxAge`) instead of skipping when a hydrated list already exists. Previously a once-cached list was pinned forever, so users never saw newly available or removed groups. Per-group capacity reads are batched into a single Multicall3 round-trip.
24
+ ### Minor Changes
13
25
 
14
26
  - [#18520](https://github.com/LedgerHQ/ledger-live/pull/18520) [`4ace552`](https://github.com/LedgerHQ/ledger-live/commit/4ace55213a4f1869980aab5160683bb120c65292) Thanks [@gre-ledger](https://github.com/gre-ledger)! - Move the dummy fee-estimation recipient out of `@ledgerhq/cryptoassets` (`abandonseed.ts`, now deleted) into each coin family. Every account bridge now exposes a required `getEstimationRecipient(account)` returning a valid recipient (or throwing for an unmapped currency, like the former `getAbandonSeedAddress`), and the swap layer dispatches through it instead of the central address map.
15
27
 
16
- - Updated dependencies [[`6df2017`](https://github.com/LedgerHQ/ledger-live/commit/6df20171a84b54e5b67eabefc938a98d7e3c3e43), [`38728f9`](https://github.com/LedgerHQ/ledger-live/commit/38728f9d9ac879c276def56ce88c5e49549e4b9d), [`636a4cb`](https://github.com/LedgerHQ/ledger-live/commit/636a4cbc5ae01364af425e3837cecf1ce4d3f3bc), [`9f8ab96`](https://github.com/LedgerHQ/ledger-live/commit/9f8ab9672ababc02909e7553d433ee326c37762e), [`e6566ff`](https://github.com/LedgerHQ/ledger-live/commit/e6566ff55d95ff36832d5f77899d67d80842f418), [`48dbd53`](https://github.com/LedgerHQ/ledger-live/commit/48dbd533a7a505cbb37989f8ce94f273f84bc7d2), [`ad68778`](https://github.com/LedgerHQ/ledger-live/commit/ad68778ad71686c9e4f397276917e606a099f573), [`13aeeb6`](https://github.com/LedgerHQ/ledger-live/commit/13aeeb6186997b433785e542ed1dafa6afde2267), [`1f41eee`](https://github.com/LedgerHQ/ledger-live/commit/1f41eee5b4dc6aa50accd94e5a0d6c98fcf76e23), [`81373c1`](https://github.com/LedgerHQ/ledger-live/commit/81373c1ca46cf2094cfd4f98958eff2114f02cea), [`7c39ea3`](https://github.com/LedgerHQ/ledger-live/commit/7c39ea39ca8999bcb8ce2294f4884430b6d1b2dc), [`d686e93`](https://github.com/LedgerHQ/ledger-live/commit/d686e93f8a548ff4e9ab3c877ad1f815510b35d9), [`b8a0765`](https://github.com/LedgerHQ/ledger-live/commit/b8a0765d7ac1ac1a60456f9c604e7a694e38bd84), [`e820e40`](https://github.com/LedgerHQ/ledger-live/commit/e820e402fb57d52b31dcd6de26f8d31d9564e2a4), [`fa0123a`](https://github.com/LedgerHQ/ledger-live/commit/fa0123a1da7b053d58afab498266cf830958e2ff), [`93a84fb`](https://github.com/LedgerHQ/ledger-live/commit/93a84fbadb2b1a0e529e2ffa08ca1de790355934), [`b10ca6a`](https://github.com/LedgerHQ/ledger-live/commit/b10ca6ab5e80889b24805b460f81eff5748f0170), [`798081d`](https://github.com/LedgerHQ/ledger-live/commit/798081db3e427c8d2d09930ceb836703146ca1ba), [`1f11587`](https://github.com/LedgerHQ/ledger-live/commit/1f11587b4681429aa9be2dc50035f292e0394108), [`df96477`](https://github.com/LedgerHQ/ledger-live/commit/df964774bdaccd897e5e7414c172e9c26ff21f67), [`ebda9d8`](https://github.com/LedgerHQ/ledger-live/commit/ebda9d88805501f4c2c03fef0fe24f116a8a2a6c), [`cf3aad1`](https://github.com/LedgerHQ/ledger-live/commit/cf3aad160bd9d2002a3154fbc70018fb1f7a6171), [`df6ca42`](https://github.com/LedgerHQ/ledger-live/commit/df6ca422fa70171162974ea71519da5c5eeb55d8), [`4ace552`](https://github.com/LedgerHQ/ledger-live/commit/4ace55213a4f1869980aab5160683bb120c65292), [`b3ffa2f`](https://github.com/LedgerHQ/ledger-live/commit/b3ffa2f4bf735f2cfeed2a8028ea92d4bc3588e3), [`37eba10`](https://github.com/LedgerHQ/ledger-live/commit/37eba10db15542fb7859bafac772e6d280650872), [`ca20506`](https://github.com/LedgerHQ/ledger-live/commit/ca20506c138a1cfb9c254f61e6bb930aea4c6ab8)]:
17
- - @ledgerhq/cryptoassets@13.53.0-nightly.20260627030713
18
- - @ledgerhq/types-live@6.113.0-nightly.20260627030713
19
- - @ledgerhq/coin-evm@4.4.0-nightly.20260627030713
20
- - @ledgerhq/ledger-wallet-framework@2.3.0-nightly.20260627030713
21
- - @ledgerhq/errors@6.36.1-nightly.20260627030713
22
- - @ledgerhq/live-env@2.40.0-nightly.20260627030713
23
- - @ledgerhq/live-promise@0.3.0-nightly.20260627030713
24
- - @ledgerhq/devices@8.16.0-nightly.20260627030713
25
- - @ledgerhq/hw-app-eth@7.8.8-nightly.20260627030713
26
- - @ledgerhq/live-network@2.6.6-nightly.20260627030713
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [[`636a4cb`](https://github.com/LedgerHQ/ledger-live/commit/636a4cbc5ae01364af425e3837cecf1ce4d3f3bc), [`48dbd53`](https://github.com/LedgerHQ/ledger-live/commit/48dbd533a7a505cbb37989f8ce94f273f84bc7d2), [`ad68778`](https://github.com/LedgerHQ/ledger-live/commit/ad68778ad71686c9e4f397276917e606a099f573), [`13aeeb6`](https://github.com/LedgerHQ/ledger-live/commit/13aeeb6186997b433785e542ed1dafa6afde2267), [`1f41eee`](https://github.com/LedgerHQ/ledger-live/commit/1f41eee5b4dc6aa50accd94e5a0d6c98fcf76e23), [`b8a0765`](https://github.com/LedgerHQ/ledger-live/commit/b8a0765d7ac1ac1a60456f9c604e7a694e38bd84), [`93a84fb`](https://github.com/LedgerHQ/ledger-live/commit/93a84fbadb2b1a0e529e2ffa08ca1de790355934), [`798081d`](https://github.com/LedgerHQ/ledger-live/commit/798081db3e427c8d2d09930ceb836703146ca1ba), [`1f11587`](https://github.com/LedgerHQ/ledger-live/commit/1f11587b4681429aa9be2dc50035f292e0394108), [`ebda9d8`](https://github.com/LedgerHQ/ledger-live/commit/ebda9d88805501f4c2c03fef0fe24f116a8a2a6c), [`4ace552`](https://github.com/LedgerHQ/ledger-live/commit/4ace55213a4f1869980aab5160683bb120c65292), [`37eba10`](https://github.com/LedgerHQ/ledger-live/commit/37eba10db15542fb7859bafac772e6d280650872), [`ca20506`](https://github.com/LedgerHQ/ledger-live/commit/ca20506c138a1cfb9c254f61e6bb930aea4c6ab8)]:
31
+ - @ledgerhq/types-live@6.113.0-next.0
32
+ - @ledgerhq/coin-evm@4.4.0-next.0
33
+ - @ledgerhq/errors@6.37.0-next.0
34
+ - @ledgerhq/live-env@2.40.0-next.0
35
+ - @ledgerhq/cryptoassets@13.53.0-next.0
36
+ - @ledgerhq/devices@8.16.0-next.0
37
+ - @ledgerhq/ledger-wallet-framework@2.2.1-next.0
38
+ - @ledgerhq/hw-app-eth@7.8.8-next.0
39
+ - @ledgerhq/live-network@2.6.6-next.0
27
40
 
28
41
  ## 2.6.0
29
42
 
@@ -1 +1 @@
1
- {"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAC;AA8BpE,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAMD,wBAAgB,yBAAyB,IAAI,UAAU,CAAC,eAAe,CAAC,CAEvE;AAED,eAAO,MAAM,kBAAkB;;CAE7B,CAAC;AAEH,eAAO,MAAM,OAAO,QAAa,OAAO,CAAC,eAAe,CAavD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,SAIpC,CAAC"}
1
+ {"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAC;AA8BpE,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAMD,wBAAgB,yBAAyB,IAAI,UAAU,CAAC,eAAe,CAAC,CAEvE;AAED,eAAO,MAAM,kBAAkB;;CAE7B,CAAC;AAEH,eAAO,MAAM,OAAO,QAAa,OAAO,CAAC,eAAe,CAiBvD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,SAIpC,CAAC"}
@@ -49,13 +49,16 @@ exports.getPreloadStrategy = getPreloadStrategy;
49
49
  const preload = async () => {
50
50
  const { validatorGroups: previousValidatorGroups } = currentCeloPreloadedData;
51
51
  let validatorGroups = previousValidatorGroups;
52
- // Always refetch (gated by preloadMaxAge); guarding on the hydrated list would pin it forever.
53
- (0, logs_1.log)("celo/preload", "refreshing celo validatorGroups...");
54
- try {
55
- validatorGroups = await (0, network_1.getValidatorGroups)();
56
- }
57
- catch (error) {
58
- (0, logs_1.log)("celo/preload", "failed to fetch validatorGroups", { error });
52
+ if (!validatorGroups || !validatorGroups.length) {
53
+ (0, logs_1.log)("celo/preload", "refreshing celo validatorGroups...");
54
+ try {
55
+ validatorGroups = await (0, network_1.getValidatorGroups)();
56
+ }
57
+ catch (error) {
58
+ (0, logs_1.log)("celo/preload", "failed to fetch validatorGroups", {
59
+ error,
60
+ });
61
+ }
59
62
  }
60
63
  return { validatorGroups };
61
64
  };
@@ -1 +1 @@
1
- {"version":3,"file":"preload.js","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":";;;AAmCA,8DAEC;AAMD,8DAEC;AA7CD,yCAAqC;AACrC,+CAAyC;AACzC,+BAA2C;AAC3C,oCAA2C;AAC3C,wCAAgD;AAGhD,IAAI,wBAAwB,GAAoB;IAC9C,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,SAAS,oBAAoB,CAC3B,iBAAkD;IAElD,OAAO;QACL,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC7C,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE;QACvC,KAAK,EAAE,IAAI,wBAAS,CAAC,iBAAiB,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAa;IAC3C,IAAI,eAAe,GAAyB,EAAE,CAAC;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACxC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,cAAO,EAAmB,CAAC;AAC/C,SAAgB,yBAAyB;IACvC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AACD,SAAS,kBAAkB,CAAC,IAAqB;IAC/C,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO;IAC9C,wBAAwB,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AACD,SAAgB,yBAAyB;IACvC,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAEM,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IACvC,aAAa,EAAE,uBAAe;CAC/B,CAAC,CAAC;AAFU,QAAA,kBAAkB,sBAE5B;AAEI,MAAM,OAAO,GAAG,KAAK,IAA8B,EAAE;IAC1D,MAAM,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,wBAAwB,CAAC;IAC9E,IAAI,eAAe,GAAG,uBAAuB,CAAC;IAE9C,+FAA+F;IAC/F,IAAA,UAAG,EAAC,cAAc,EAAE,oCAAoC,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,eAAe,GAAG,MAAM,IAAA,4BAAkB,GAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,UAAG,EAAC,cAAc,EAAE,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC,CAAC;AAbW,QAAA,OAAO,WAalB;AAEK,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;IACvC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAA,UAAG,EAAC,cAAc,EAAE,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,uBAAuB,CAAC,CAAC;IAC5F,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC,CAAC;AAJW,QAAA,OAAO,WAIlB"}
1
+ {"version":3,"file":"preload.js","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":";;;AAmCA,8DAEC;AAMD,8DAEC;AA7CD,yCAAqC;AACrC,+CAAyC;AACzC,+BAA2C;AAC3C,oCAA2C;AAC3C,wCAAgD;AAGhD,IAAI,wBAAwB,GAAoB;IAC9C,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,SAAS,oBAAoB,CAC3B,iBAAkD;IAElD,OAAO;QACL,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC7C,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE;QACvC,KAAK,EAAE,IAAI,wBAAS,CAAC,iBAAiB,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAa;IAC3C,IAAI,eAAe,GAAyB,EAAE,CAAC;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACxC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,cAAO,EAAmB,CAAC;AAC/C,SAAgB,yBAAyB;IACvC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AACD,SAAS,kBAAkB,CAAC,IAAqB;IAC/C,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO;IAC9C,wBAAwB,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AACD,SAAgB,yBAAyB;IACvC,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAEM,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IACvC,aAAa,EAAE,uBAAe;CAC/B,CAAC,CAAC;AAFU,QAAA,kBAAkB,sBAE5B;AAEI,MAAM,OAAO,GAAG,KAAK,IAA8B,EAAE;IAC1D,MAAM,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,wBAAwB,CAAC;IAC9E,IAAI,eAAe,GAAG,uBAAuB,CAAC;IAE9C,IAAI,CAAC,eAAe,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;QAChD,IAAA,UAAG,EAAC,cAAc,EAAE,oCAAoC,CAAC,CAAC;QAE1D,IAAI,CAAC;YACH,eAAe,GAAG,MAAM,IAAA,4BAAkB,GAAE,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAA,UAAG,EAAC,cAAc,EAAE,iCAAiC,EAAE;gBACrD,KAAK;aACN,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC,CAAC;AAjBW,QAAA,OAAO,WAiBlB;AAEK,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;IACvC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAA,UAAG,EAAC,cAAc,EAAE,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,uBAAuB,CAAC,CAAC;IAC5F,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC,CAAC;AAJW,QAAA,OAAO,WAIlB"}
@@ -1 +1 @@
1
- {"version":3,"file":"hubble.d.ts","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAcpD,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,kBAAkB,EAAE,CAgEvE,CAAC"}
1
+ {"version":3,"file":"hubble.d.ts","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAcpD,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,kBAAkB,EAAE,CAqDvE,CAAC"}
@@ -31,34 +31,25 @@ const getValidatorGroups = async () => {
31
31
  }),
32
32
  ]);
33
33
  const eligibleSet = new Set(eligibleGroups.map(a => a.toLowerCase()));
34
- const capacityResults = await client
35
- .multicall({
36
- allowFailure: true,
37
- contracts: rawGroups.flatMap((vg) => [
38
- {
34
+ // Check on-chain capacity for every group in parallel.
35
+ // A group must be in the eligible set and have remaining vote capacity (getNumVotesReceivable > 0),
36
+ // which matches the semantics of ContractKit's getValidatorGroupVotes { eligible, capacity }.
37
+ const canReceiveVotes = await Promise.all(rawGroups.map(async (vg) => {
38
+ try {
39
+ if (!eligibleSet.has(vg.address.toLowerCase()))
40
+ return false;
41
+ const capacity = await client.readContract({
39
42
  address: electionAddress,
40
43
  abi: abis_1.electionABI,
41
44
  functionName: "getNumVotesReceivable",
42
45
  args: [vg.address],
43
- },
44
- {
45
- address: electionAddress,
46
- abi: abis_1.electionABI,
47
- functionName: "getTotalVotesForGroup",
48
- args: [vg.address],
49
- },
50
- ]),
51
- })
52
- .catch(() => []);
53
- const canReceiveVotes = rawGroups.map((vg, index) => {
54
- if (!eligibleSet.has(vg.address.toLowerCase()))
55
- return false;
56
- const voteCap = capacityResults[index * 2];
57
- const totalVotes = capacityResults[index * 2 + 1];
58
- if (voteCap?.status !== "success" || totalVotes?.status !== "success")
46
+ });
47
+ return capacity > BigInt(0);
48
+ }
49
+ catch {
59
50
  return true;
60
- return voteCap.result > totalVotes.result;
61
- });
51
+ }
52
+ }));
62
53
  const result = rawGroups
63
54
  .filter((_, idx) => canReceiveVotes[idx])
64
55
  .map((validatorGroup) => ({
@@ -69,7 +60,13 @@ const getValidatorGroups = async () => {
69
60
  return customValidatorGroupsOrder(result);
70
61
  };
71
62
  exports.getValidatorGroups = getValidatorGroups;
72
- const customValidatorGroupsOrder = (validatorGroups) => [...validatorGroups]
73
- .filter(group => !(0, logic_1.isDefaultValidatorGroup)(group)) // Excludes the deprecated "Ledger by Figment"
74
- .sort((a, b) => b.votes.comparedTo(a.votes));
63
+ const customValidatorGroupsOrder = (validatorGroups) => {
64
+ const defaultValidatorGroup = validatorGroups.find(logic_1.isDefaultValidatorGroup);
65
+ const sortedValidatorGroups = [...validatorGroups]
66
+ .sort((a, b) => b.votes.comparedTo(a.votes))
67
+ .filter(group => !(0, logic_1.isDefaultValidatorGroup)(group));
68
+ return defaultValidatorGroup
69
+ ? [defaultValidatorGroup, ...sortedValidatorGroups]
70
+ : sortedValidatorGroups;
71
+ };
75
72
  //# sourceMappingURL=hubble.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hubble.js","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hubble.js","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAC;AA8BpE,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAMD,wBAAgB,yBAAyB,IAAI,UAAU,CAAC,eAAe,CAAC,CAEvE;AAED,eAAO,MAAM,kBAAkB;;CAE7B,CAAC;AAEH,eAAO,MAAM,OAAO,QAAa,OAAO,CAAC,eAAe,CAavD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,SAIpC,CAAC"}
1
+ {"version":3,"file":"preload.d.ts","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAC;AA8BpE,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAMD,wBAAgB,yBAAyB,IAAI,UAAU,CAAC,eAAe,CAAC,CAEvE;AAED,eAAO,MAAM,kBAAkB;;CAE7B,CAAC;AAEH,eAAO,MAAM,OAAO,QAAa,OAAO,CAAC,eAAe,CAiBvD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,SAIpC,CAAC"}
@@ -43,13 +43,16 @@ export const getPreloadStrategy = () => ({
43
43
  export const preload = async () => {
44
44
  const { validatorGroups: previousValidatorGroups } = currentCeloPreloadedData;
45
45
  let validatorGroups = previousValidatorGroups;
46
- // Always refetch (gated by preloadMaxAge); guarding on the hydrated list would pin it forever.
47
- log("celo/preload", "refreshing celo validatorGroups...");
48
- try {
49
- validatorGroups = await getValidatorGroups();
50
- }
51
- catch (error) {
52
- log("celo/preload", "failed to fetch validatorGroups", { error });
46
+ if (!validatorGroups || !validatorGroups.length) {
47
+ log("celo/preload", "refreshing celo validatorGroups...");
48
+ try {
49
+ validatorGroups = await getValidatorGroups();
50
+ }
51
+ catch (error) {
52
+ log("celo/preload", "failed to fetch validatorGroups", {
53
+ error,
54
+ });
55
+ }
53
56
  }
54
57
  return { validatorGroups };
55
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"preload.js","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,IAAI,wBAAwB,GAAoB;IAC9C,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,SAAS,oBAAoB,CAC3B,iBAAkD;IAElD,OAAO;QACL,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC7C,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE;QACvC,KAAK,EAAE,IAAI,SAAS,CAAC,iBAAiB,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAa;IAC3C,IAAI,eAAe,GAAyB,EAAE,CAAC;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACxC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAmB,CAAC;AAC/C,MAAM,UAAU,yBAAyB;IACvC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AACD,SAAS,kBAAkB,CAAC,IAAqB;IAC/C,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO;IAC9C,wBAAwB,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AACD,MAAM,UAAU,yBAAyB;IACvC,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IACvC,aAAa,EAAE,eAAe;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAA8B,EAAE;IAC1D,MAAM,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,wBAAwB,CAAC;IAC9E,IAAI,eAAe,GAAG,uBAAuB,CAAC;IAE9C,+FAA+F;IAC/F,GAAG,CAAC,cAAc,EAAE,oCAAoC,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,cAAc,EAAE,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;IACvC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,GAAG,CAAC,cAAc,EAAE,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,uBAAuB,CAAC,CAAC;IAC5F,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC,CAAC"}
1
+ {"version":3,"file":"preload.js","sourceRoot":"","sources":["../../src/bridge/preload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,IAAI,wBAAwB,GAAoB;IAC9C,eAAe,EAAE,EAAE;CACpB,CAAC;AAEF,SAAS,oBAAoB,CAC3B,iBAAkD;IAElD,OAAO;QACL,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC7C,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE;QACvC,KAAK,EAAE,IAAI,SAAS,CAAC,iBAAiB,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAa;IAC3C,IAAI,eAAe,GAAyB,EAAE,CAAC;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACxC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAmB,CAAC;AAC/C,MAAM,UAAU,yBAAyB;IACvC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AACD,SAAS,kBAAkB,CAAC,IAAqB;IAC/C,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO;IAC9C,wBAAwB,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AACD,MAAM,UAAU,yBAAyB;IACvC,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IACvC,aAAa,EAAE,eAAe;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAA8B,EAAE;IAC1D,MAAM,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,wBAAwB,CAAC;IAC9E,IAAI,eAAe,GAAG,uBAAuB,CAAC;IAE9C,IAAI,CAAC,eAAe,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;QAChD,GAAG,CAAC,cAAc,EAAE,oCAAoC,CAAC,CAAC;QAE1D,IAAI,CAAC;YACH,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,cAAc,EAAE,iCAAiC,EAAE;gBACrD,KAAK;aACN,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;IACvC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,GAAG,CAAC,cAAc,EAAE,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,uBAAuB,CAAC,CAAC;IAC5F,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hubble.d.ts","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAcpD,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,kBAAkB,EAAE,CAgEvE,CAAC"}
1
+ {"version":3,"file":"hubble.d.ts","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAcpD,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,kBAAkB,EAAE,CAqDvE,CAAC"}
@@ -25,34 +25,25 @@ export const getValidatorGroups = async () => {
25
25
  }),
26
26
  ]);
27
27
  const eligibleSet = new Set(eligibleGroups.map(a => a.toLowerCase()));
28
- const capacityResults = await client
29
- .multicall({
30
- allowFailure: true,
31
- contracts: rawGroups.flatMap((vg) => [
32
- {
28
+ // Check on-chain capacity for every group in parallel.
29
+ // A group must be in the eligible set and have remaining vote capacity (getNumVotesReceivable > 0),
30
+ // which matches the semantics of ContractKit's getValidatorGroupVotes { eligible, capacity }.
31
+ const canReceiveVotes = await Promise.all(rawGroups.map(async (vg) => {
32
+ try {
33
+ if (!eligibleSet.has(vg.address.toLowerCase()))
34
+ return false;
35
+ const capacity = await client.readContract({
33
36
  address: electionAddress,
34
37
  abi: electionABI,
35
38
  functionName: "getNumVotesReceivable",
36
39
  args: [vg.address],
37
- },
38
- {
39
- address: electionAddress,
40
- abi: electionABI,
41
- functionName: "getTotalVotesForGroup",
42
- args: [vg.address],
43
- },
44
- ]),
45
- })
46
- .catch(() => []);
47
- const canReceiveVotes = rawGroups.map((vg, index) => {
48
- if (!eligibleSet.has(vg.address.toLowerCase()))
49
- return false;
50
- const voteCap = capacityResults[index * 2];
51
- const totalVotes = capacityResults[index * 2 + 1];
52
- if (voteCap?.status !== "success" || totalVotes?.status !== "success")
40
+ });
41
+ return capacity > BigInt(0);
42
+ }
43
+ catch {
53
44
  return true;
54
- return voteCap.result > totalVotes.result;
55
- });
45
+ }
46
+ }));
56
47
  const result = rawGroups
57
48
  .filter((_, idx) => canReceiveVotes[idx])
58
49
  .map((validatorGroup) => ({
@@ -62,7 +53,13 @@ export const getValidatorGroups = async () => {
62
53
  }));
63
54
  return customValidatorGroupsOrder(result);
64
55
  };
65
- const customValidatorGroupsOrder = (validatorGroups) => [...validatorGroups]
66
- .filter(group => !isDefaultValidatorGroup(group)) // Excludes the deprecated "Ledger by Figment"
67
- .sort((a, b) => b.votes.comparedTo(a.votes));
56
+ const customValidatorGroupsOrder = (validatorGroups) => {
57
+ const defaultValidatorGroup = validatorGroups.find(isDefaultValidatorGroup);
58
+ const sortedValidatorGroups = [...validatorGroups]
59
+ .sort((a, b) => b.votes.comparedTo(a.votes))
60
+ .filter(group => !isDefaultValidatorGroup(group));
61
+ return defaultValidatorGroup
62
+ ? [defaultValidatorGroup, ...sortedValidatorGroups]
63
+ : sortedValidatorGroups;
64
+ };
68
65
  //# sourceMappingURL=hubble.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hubble.js","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hubble.js","sourceRoot":"","sources":["../../src/network/hubble.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/coin-celo",
3
- "version": "2.6.1-nightly.20260627030713",
3
+ "version": "2.7.0",
4
4
  "description": "celo coin integration",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -122,18 +122,18 @@
122
122
  "lodash": "^4.17.21",
123
123
  "rxjs": "7.8.2",
124
124
  "viem": "^2.27.0",
125
- "@ledgerhq/coin-evm": "^4.4.0-nightly.20260627030713",
126
- "@ledgerhq/cryptoassets": "^13.53.0-nightly.20260627030713",
127
- "@ledgerhq/devices": "8.16.0-nightly.20260627030713",
128
- "@ledgerhq/errors": "^6.36.1-nightly.20260627030713",
129
- "@ledgerhq/hw-app-eth": "^7.8.8-nightly.20260627030713",
130
- "@ledgerhq/ledger-wallet-framework": "^2.3.0-nightly.20260627030713",
125
+ "@ledgerhq/coin-evm": "^4.4.0",
126
+ "@ledgerhq/cryptoassets": "^13.53.0",
127
+ "@ledgerhq/devices": "8.16.0",
128
+ "@ledgerhq/errors": "^6.37.0",
129
+ "@ledgerhq/hw-app-eth": "^7.8.8",
130
+ "@ledgerhq/ledger-wallet-framework": "^2.2.1",
131
131
  "@ledgerhq/live-config": "^3.8.0",
132
- "@ledgerhq/live-env": "^2.40.0-nightly.20260627030713",
133
- "@ledgerhq/live-network": "^2.6.6-nightly.20260627030713",
134
- "@ledgerhq/live-promise": "^0.3.0-nightly.20260627030713",
132
+ "@ledgerhq/live-env": "^2.40.0",
133
+ "@ledgerhq/live-network": "^2.6.6",
134
+ "@ledgerhq/live-promise": "^0.2.3",
135
135
  "@ledgerhq/logs": "^6.17.0",
136
- "@ledgerhq/types-live": "^6.113.0-nightly.20260627030713"
136
+ "@ledgerhq/types-live": "^6.113.0"
137
137
  },
138
138
  "devDependencies": {
139
139
  "@faker-js/faker": "^9.9.0",
@@ -150,7 +150,7 @@
150
150
  "oxlint": "1.51.0",
151
151
  "typescript": "6.0.2",
152
152
  "@ledgerhq/disable-network-setup": "^0.3.0",
153
- "@ledgerhq/types-cryptoassets": "^7.39.0-nightly.20260627030713"
153
+ "@ledgerhq/types-cryptoassets": "^7.38.0"
154
154
  },
155
155
  "scripts": {
156
156
  "clean": "rimraf lib lib-es",
@@ -53,12 +53,16 @@ export const preload = async (): Promise<CeloPreloadData> => {
53
53
  const { validatorGroups: previousValidatorGroups } = currentCeloPreloadedData;
54
54
  let validatorGroups = previousValidatorGroups;
55
55
 
56
- // Always refetch (gated by preloadMaxAge); guarding on the hydrated list would pin it forever.
57
- log("celo/preload", "refreshing celo validatorGroups...");
58
- try {
59
- validatorGroups = await getValidatorGroups();
60
- } catch (error) {
61
- log("celo/preload", "failed to fetch validatorGroups", { error });
56
+ if (!validatorGroups || !validatorGroups.length) {
57
+ log("celo/preload", "refreshing celo validatorGroups...");
58
+
59
+ try {
60
+ validatorGroups = await getValidatorGroups();
61
+ } catch (error) {
62
+ log("celo/preload", "failed to fetch validatorGroups", {
63
+ error,
64
+ });
65
+ }
62
66
  }
63
67
 
64
68
  return { validatorGroups };
@@ -32,36 +32,25 @@ export const getValidatorGroups = async (): Promise<CeloValidatorGroup[]> => {
32
32
 
33
33
  const eligibleSet = new Set(eligibleGroups.map(a => a.toLowerCase()));
34
34
 
35
- // Batch all capacity reads in one Multicall3 round-trip. A group can receive votes when its
36
- // cap (getNumVotesReceivable) is above its current total votes; saturated groups are excluded.
37
- type CapacityResult = { status: "success"; result: unknown } | { status: "failure" };
38
- const capacityResults: readonly CapacityResult[] = await client
39
- .multicall({
40
- allowFailure: true,
41
- contracts: rawGroups.flatMap((vg: { address: `0x${string}` }) => [
42
- {
35
+ // Check on-chain capacity for every group in parallel.
36
+ // A group must be in the eligible set and have remaining vote capacity (getNumVotesReceivable > 0),
37
+ // which matches the semantics of ContractKit's getValidatorGroupVotes { eligible, capacity }.
38
+ const canReceiveVotes = await Promise.all(
39
+ rawGroups.map(async (vg: { address: `0x${string}` }) => {
40
+ try {
41
+ if (!eligibleSet.has(vg.address.toLowerCase())) return false;
42
+ const capacity = await client.readContract({
43
43
  address: electionAddress,
44
44
  abi: electionABI,
45
45
  functionName: "getNumVotesReceivable",
46
46
  args: [vg.address],
47
- },
48
- {
49
- address: electionAddress,
50
- abi: electionABI,
51
- functionName: "getTotalVotesForGroup",
52
- args: [vg.address],
53
- },
54
- ]),
55
- })
56
- .catch(() => []);
57
-
58
- const canReceiveVotes = rawGroups.map((vg: { address: `0x${string}` }, index: number) => {
59
- if (!eligibleSet.has(vg.address.toLowerCase())) return false;
60
- const voteCap = capacityResults[index * 2];
61
- const totalVotes = capacityResults[index * 2 + 1];
62
- if (voteCap?.status !== "success" || totalVotes?.status !== "success") return true;
63
- return (voteCap.result as bigint) > (totalVotes.result as bigint);
64
- });
47
+ });
48
+ return capacity > BigInt(0);
49
+ } catch {
50
+ return true;
51
+ }
52
+ }),
53
+ );
65
54
 
66
55
  const result = rawGroups
67
56
  .filter((_: unknown, idx: number) => canReceiveVotes[idx])
@@ -83,7 +72,16 @@ export const getValidatorGroups = async (): Promise<CeloValidatorGroup[]> => {
83
72
  return customValidatorGroupsOrder(result);
84
73
  };
85
74
 
86
- const customValidatorGroupsOrder = (validatorGroups: CeloValidatorGroup[]): CeloValidatorGroup[] =>
87
- [...validatorGroups]
88
- .filter(group => !isDefaultValidatorGroup(group)) // Excludes the deprecated "Ledger by Figment"
89
- .sort((a, b) => b.votes.comparedTo(a.votes));
75
+ const customValidatorGroupsOrder = (
76
+ validatorGroups: CeloValidatorGroup[],
77
+ ): CeloValidatorGroup[] => {
78
+ const defaultValidatorGroup = validatorGroups.find(isDefaultValidatorGroup);
79
+
80
+ const sortedValidatorGroups = [...validatorGroups]
81
+ .sort((a, b) => b.votes.comparedTo(a.votes))
82
+ .filter(group => !isDefaultValidatorGroup(group));
83
+
84
+ return defaultValidatorGroup
85
+ ? [defaultValidatorGroup, ...sortedValidatorGroups]
86
+ : sortedValidatorGroups;
87
+ };
@@ -1,136 +0,0 @@
1
- const networkMock = jest.fn();
2
- const getCeloClientMock = jest.fn();
3
- const getRegistryAddressForMock = jest.fn();
4
- const readContractMock = jest.fn();
5
- const multicallMock = jest.fn();
6
-
7
- jest.mock("@ledgerhq/live-network/network", () => ({
8
- __esModule: true,
9
- default: (...args: unknown[]) => networkMock(...args),
10
- }));
11
- jest.mock("../../network/client", () => ({
12
- getCeloClient: (...args: unknown[]) => getCeloClientMock(...args),
13
- }));
14
- jest.mock("../../network/registry", () => ({
15
- getRegistryAddressFor: (...args: unknown[]) => getRegistryAddressForMock(...args),
16
- }));
17
-
18
- import { getValidatorGroups } from "../../network/hubble";
19
-
20
- const FIGMENT = "0x0861a61Bf679A30680510EcC238ee43B82C5e843";
21
-
22
- type Group = {
23
- address: string;
24
- name: string;
25
- cap: bigint; // getNumVotesReceivable (vote cap)
26
- total: bigint; // getTotalVotesForGroup
27
- eligible: boolean;
28
- };
29
-
30
- const setup = (groups: Group[]) => {
31
- networkMock.mockResolvedValue({
32
- data: {
33
- items: groups.map(g => ({
34
- address: g.address,
35
- name: g.name,
36
- active_votes: g.total.toString(),
37
- pending_votes: "0",
38
- })),
39
- },
40
- });
41
-
42
- readContractMock.mockImplementation(async ({ functionName }: { functionName: string }) => {
43
- if (functionName === "getEligibleValidatorGroups") {
44
- return groups.filter(g => g.eligible).map(g => g.address);
45
- }
46
- return 0n;
47
- });
48
-
49
- // getValidatorGroups batches the per-group capacity reads via client.multicall, in the order
50
- // [getNumVotesReceivable, getTotalVotesForGroup] for each raw group.
51
- multicallMock.mockImplementation(async () =>
52
- groups.flatMap(g => [
53
- { status: "success", result: g.cap },
54
- { status: "success", result: g.total },
55
- ]),
56
- );
57
- };
58
-
59
- describe("network/hubble - getValidatorGroups", () => {
60
- beforeEach(() => {
61
- jest.clearAllMocks();
62
-
63
- getCeloClientMock.mockReturnValue({ readContract: readContractMock, multicall: multicallMock });
64
- getRegistryAddressForMock.mockResolvedValue("0x000000000000000000000000000000000000ce10");
65
- });
66
-
67
- it("keeps eligible groups that still have capacity, ranked by TVL", async () => {
68
- setup([
69
- { address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true },
70
- { address: "0xbbb", name: "Beta", cap: 1000n, total: 300n, eligible: true },
71
- ]);
72
-
73
- const result = await getValidatorGroups();
74
-
75
- expect(result.map(g => g.name)).toEqual(["Beta", "Alpha"]);
76
- });
77
-
78
- it("filters out saturated groups (cap <= total) so they are not offered", async () => {
79
- setup([
80
- { address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true },
81
- { address: "0xsat", name: "Saturated", cap: 100n, total: 500n, eligible: true },
82
- ]);
83
-
84
- const result = await getValidatorGroups();
85
-
86
- expect(result.map(g => g.name)).toEqual(["Alpha"]);
87
- });
88
-
89
- it("filters out groups that are not in the eligible set", async () => {
90
- setup([
91
- { address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true },
92
- { address: "0xine", name: "Ineligible", cap: 1000n, total: 100n, eligible: false },
93
- ]);
94
-
95
- const result = await getValidatorGroups();
96
-
97
- expect(result.map(g => g.name)).toEqual(["Alpha"]);
98
- });
99
-
100
- it("keeps eligible groups when the capacity multicall fails (fail open)", async () => {
101
- setup([
102
- { address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true },
103
- { address: "0xbbb", name: "Beta", cap: 1000n, total: 300n, eligible: true },
104
- { address: "0xine", name: "Ineligible", cap: 1000n, total: 100n, eligible: false },
105
- ]);
106
- multicallMock.mockRejectedValueOnce(new Error("rpc down"));
107
-
108
- const result = await getValidatorGroups();
109
-
110
- expect(result.map(g => g.name)).toEqual(["Beta", "Alpha"]);
111
- });
112
-
113
- it("keeps a group when one of its two capacity reads fails (fail open)", async () => {
114
- setup([{ address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true }]);
115
- // getNumVotesReceivable succeeds, getTotalVotesForGroup fails for the only group.
116
- multicallMock.mockResolvedValueOnce([
117
- { status: "success", result: 1000n },
118
- { status: "failure", error: new Error("revert") },
119
- ]);
120
-
121
- const result = await getValidatorGroups();
122
-
123
- expect(result.map(g => g.name)).toEqual(["Alpha"]);
124
- });
125
-
126
- it("excludes the deprecated 'Ledger by Figment' group even when it has capacity", async () => {
127
- setup([
128
- { address: "0xaaa", name: "Alpha", cap: 1000n, total: 100n, eligible: true },
129
- { address: FIGMENT, name: "Ledger by Figment", cap: 999999n, total: 0n, eligible: true },
130
- ]);
131
-
132
- const result = await getValidatorGroups();
133
-
134
- expect(result.map(g => g.name)).toEqual(["Alpha"]);
135
- });
136
- });