Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion changelogs/v31.0.0-next.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: SDK Changelog - v31.0.0 to next release
description: Pending changes since Polymesh SDK v31.0.0. Adds Ethereum wallet signing and address mapping, broadcasting a transaction without waiting for it, issuing NFTs to an Account, connecting from runtimes that disallow WASM compilation, ordering POLYX transaction history, an optional middleware API key, and staking coverage for chill, rebond, era progress, historical era data, the validator set, commission and total issuance. Fixes BigNumber checks across duplicate package copies, ignored authorization expiry options, unbounded Portfolio scans, on-chain failure reporting, staking permission checks, withdrawing unbonded POLYX where the controller is not the stash, and the units of the total staked amount.
description: Pending changes since Polymesh SDK v31.0.0. Adds Ethereum wallet signing and address mapping, broadcasting a transaction without waiting for it, issuing NFTs to an Account, connecting from runtimes that disallow WASM compilation, ordering POLYX transaction history, an optional middleware API key, and staking coverage for chill, rebond, era progress, historical era data, the validator set, commission and total issuance. Fixes BigNumber checks across duplicate package copies, ignored authorization expiry options, unbounded Portfolio scans, on-chain failure reporting, staking permission checks, withdrawing unbonded POLYX where the controller is not the stash, the units of the total staked amount, and a false "not included" rejection when claiming dividends.
sidebar_label: v31.0.0 → next
id: v31-0-to-next
tags:
Expand Down Expand Up @@ -383,6 +383,14 @@ All seven now return `permissions: true`: it short-circuits both checks, makes n

The count now comes from the stash named in the controller's ledger. An Account that is its own controller is unaffected.

### Claiming dividends could reject a genuine participant as "not included"

`DividendDistribution.claim()` checks a Distribution's participants by calling `getParticipant()` with no arguments, which defaults the Identity to check to whatever `Context.getSigningIdentity()` returns. `prepareClaimDividends` called it on `distribution` — the `DividendDistribution` entity — rather than on the Procedure's own `Context`. Those are not always the same object: `distribution` carries whichever `Context` it happened to be fetched with, while the Procedure runs against a fresh clone scoped to this call's `signingAccount`.

For a consumer that fetches entities off one shared, long-lived `Context` while overriding `signingAccount` per call — the REST API is the clearest example — `claim()` checked participation against whatever Identity that shared `Context`'s signing Account last happened to be, not the Identity actually signing the claim. The result was a deterministic `'The signing Identity is not included in this Distribution'`, even for a real, funded participant.

`prepareClaimDividends` now resolves the signing Identity from its own `Context` explicitly and passes it into `getParticipant()`, so the Identity checked always matches the one signing the call.

---

## Other changes
Expand Down
13 changes: 12 additions & 1 deletion src/api/procedures/claimDividends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,18 @@ export async function prepareClaimDividends(

assertDistributionOpen(paymentDate, expiryDate);

const participant = await distribution.getParticipant();
// `distribution` was fetched through (and carries) whatever Context it happened to be
// constructed with, which is *not* necessarily this Procedure's own Context (`context` above,
// scoped to this call's `signingAccount`). Since `getParticipant` defaults its `identity` by
// reading the *signing* Identity off whichever Context it's given, calling it with no args here
// would resolve against `distribution`'s Context instead of this one, silently checking the
// wrong Identity's participation (and balance) whenever the two differ - e.g. any multi-account
// consumer, such as the REST API, that fetches entities off a shared Context while overriding
// `signingAccount` per call. Resolve the signing Identity from this Procedure's Context
// explicitly and pass it through so the correct Identity is always the one checked.
const signingIdentity = await context.getSigningIdentity();

const participant = await distribution.getParticipant({ identity: signingIdentity });

if (!participant) {
throw new PolymeshError({
Expand Down
Loading