You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
dashrate: ratings show "No reviews yet" after evo-sdk 5.0 bump (grouped-count key encoding changed in PV14) #119
Since the @dashevo/evo-sdk 5.0.0 bump (#118), the DashRate Resources sidebar shows "No reviews yet" for every resource, including resources that have reviews and ratings on testnet.
Likely cause
reviewCountLine (example-apps/dashrate/src/lib/ratings.ts) shows "No reviews yet" whenever summary.average is null. The average is computed in JS from the grouped rating distribution (summaryFromDistribution), and getRatingDistribution (example-apps/dashrate/src/dash/queries.ts) looks up each rating in the grouped count result by ratingKeyHex(r) = (0x80 | r).toString(16), i.e. keys "81".."85".
Protocol version 14 (which evo-sdk 5.0 targets) includes dashpay/platform#5350 "fix(platform)!: key unsigned integer index values in value order" (listed as BREAKING in the platform CHANGELOG, 5.0.0-beta.5). rating (integer, min 1, max 5) maps to a U8 property, and under PV14 unsigned integer index keys are no longer sign-bit-flipped:
Protocol
Grouped-count key for rating 5
≤ PV13
"85" (0x80 | 5)
PV14
"05"
PV14's transition rekeys existing index values, and the exceptions (system $ fields, contested vote-poll paths, properties ending a rangeSummable index) don't apply to the rangeCountableresourceRatingDistribution index. So every lookup misses, every per-star count is 0, the average is null, and the UI reports no reviews.
The total count (ungrouped, keyed "") and the review list queries don't depend on this encoding, which is why the app is only partially broken.
The result shape itself (Map<string, bigint> with hex keys) and the count query options (groupBy, between, orderBy) are unchanged since 4.1.1.
Affected code
example-apps/dashrate/src/dash/queries.ts — ratingKeyHex and its doc comment
example-apps/dashrate/CLAUDE.md — "Grouped-count map keys" gotcha documents the old "85" form
To confirm
Log the keys returned by one grouped count (["resourceId","==",id], ["rating","between",[1,5]], groupBy: ["rating"]) against testnet: "01".."05" confirms; "81".."85" rules it out. sdk.version() after a proof-bearing read shows the negotiated protocol version.
Suggested fix
Decode the returned keys rather than encoding expected ones: parse the hex as a big-endian unsigned integer, clearing the top bit for a single byte ≥ 0x80. That handles both PV13 and PV14 networks. Update the lite page and the CLAUDE.md gotcha to match, and consider whether other example apps (e.g. dashnames, still on 4.1.1) rely on the same encoding.
Unit tests (example-apps/dashrate/test/queries.test.ts) pin the old encoding: ratingKeyHex(1) → "81", ratingKeyHex(5) → "85" (lines ~145–146). The getRatingDistribution test builds its stubbed SDK response with ratingKeyHex itself (lines ~150–180), so the stub writes keys with the same function the code reads them with — it passes no matter what format the network returns.
Hook test (test/useResourceRatings.test.tsx) mocks getRatingDistribution entirely.
E2E (test/e2e/) is read-only smoke coverage that asserts rendering, not live rating data, so "No reviews yet" on every resource passes.
Live read-only invariant (testnet): for each resource, the sum of the grouped per-star counts must equal the ungrouped total from getRatingCount. With the current bug the total is > 0 while the distribution sum is 0, so this fails. It's independent of how many reviews exist, needs no signing or credits, and would fit in the e2e suite or a small live-query test.
Unit test with literal network-format keys: feed a hardcoded map in the PV14 format (e.g. new Map([["05", 8n], ["03", 2n]])) and assert the decoded distribution ({5: 8n, 3: 2n, ...}), rather than building the stub with the app's own encoder. Optionally a second case with legacy "85"-style keys if the fix supports both.
Activity
thephez commentedon Oct 29, 2026
Why existing tests didn't catch this
example-apps/dashrate/test/queries.test.ts) pin the old encoding:ratingKeyHex(1)→"81",ratingKeyHex(5)→"85"(lines ~145–146). ThegetRatingDistributiontest builds its stubbed SDK response withratingKeyHexitself (lines ~150–180), so the stub writes keys with the same function the code reads them with — it passes no matter what format the network returns.test/useResourceRatings.test.tsx) mocksgetRatingDistributionentirely.test/e2e/) is read-only smoke coverage that asserts rendering, not live rating data, so "No reviews yet" on every resource passes.Suggested test additions
getRatingCount. With the current bug the total is > 0 while the distribution sum is 0, so this fails. It's independent of how many reviews exist, needs no signing or credits, and would fit in the e2e suite or a small live-query test.new Map([["05", 8n], ["03", 2n]])) and assert the decoded distribution ({5: 8n, 3: 2n, ...}), rather than building the stub with the app's own encoder. Optionally a second case with legacy"85"-style keys if the fix supports both.