Skip to content

feat: 🎸 Bump SDK to v31 and drop v7 support - #369

Merged
prashantasdeveloper merged 34 commits into
alphafrom
feat/bump-sdk-v31
Aug 24, 2026
Merged

feat: 🎸 Bump SDK to v31 and drop v7 support#369
prashantasdeveloper merged 34 commits into
alphafrom
feat/bump-sdk-v31

Conversation

@prashantasdeveloper

Copy link
Copy Markdown
Contributor

Changelog / Description

Bumps @polymeshassociation/polymesh-sdk to 31.0.0, which drops chain v7 support (chain v8 is now the only supported version). Migrates all breaking changes, adds the v30.1–v31 SDK features as new endpoints, and cleans up stale v7-era documentation.

Every new/changed endpoint was manually verified against a real local v8 chain (not just unit tests) — see the verification notes on individual commits.

⚠️ Breaking changes

  • Chain v7 is no longer supported. The SDK throws on initialization against a v7 node.
  • POST /accounts/subsidy/create removed. AccountManagement.subsidizeAccount no longer exists in the SDK. Use POST /accounts/subsidy/approve + POST /accounts/subsidy/accept instead.
  • POST /instructions/:id/withdraw and POST /instructions/:id/withdraw-as-mediator removed. Instruction.withdraw/withdrawAsMediator have no v8 equivalent. Reject the instruction instead.
  • GET /identities/:did/cdd-claims removed. Claims.getCddClaims is gone from the SDK; the endpoint was already non-functional on v8 (it threw NotSupported).
  • POST /assets/transfer-funds response shape changed. Now returns an instruction field when the transfer doesn't settle immediately (cross-identity transfer where the receiver requires manual affirmation), since Assets.transferFunds no longer requires from/to to belong to the same Identity.

Fixes

  • RegisterIdentityDto.createCdd/expiry are now optional (deprecated, no on-chain effect as of v8) instead of createCdd being a required field.
  • Fixed TransferError model referencing removed enum members (InvalidSenderCdd, ScopeClaimMissingInvalidReceiverIdentity).
  • developer-testing test admin creation now grants DID Registrar status via didRegistrars.addMember (was silently a no-op on v8 due to a dead context.isV7 branch).

New endpoints

  • Portfolio-level asset pre-approval: POST /identities/:did/portfolios/:id/pre-approve-asset, POST .../remove-pre-approval, GET .../is-pre-approved, GET .../pre-approved-assets
  • Instruction lock/unlock: POST /instructions/:id/lock, POST /instructions/:id/unlock, GET /instructions/:id/relock-status
  • Instruction leg status: GET /instructions/:id/legs/:legId/status
  • DID registration: POST /identities/register-did (registrar-gated, minimal — no secondary keys/CDD)
  • Venue signer count: GET /venues/:id/signer-count
  • Funding round issuance: GET /assets/:asset/funding-rounds/:round/issued
  • Next checkpoint: GET /assets/:asset/checkpoints/schedules/next
  • Corporate action documents: GET /assets/:asset/corporate-actions/:id/documents
  • Ticker registration config: GET /ticker-reservations/config
  • CreateInstructionDto gained endAfterLock, so a SettleAfterLock instruction (required for the lock/unlock endpoints above) can actually be created through the API.

Cleanup

  • Removed unreferenced ScopeClaimProofDto (backed an SDK type deleted in v31).
  • Removed stale "chain v7/v8" wording from swagger descriptions across accounts, identities, assets, and settlements.
  • Updated README's supported chain-version range.

Checklist

  • New Feature? — several new endpoints (see above)
  • Updated swagger annotation (if API structure is changed)? — yes, all new/changed endpoints documented
  • Unit Test (if possible)? — yes, 100% coverage on every touched file; full suite is 1071 passing
  • Updated the Readme.md (if required)? — supported chain-version line updated

Drops chain v7 support; the SDK now targets chain v8 only. Also bumps
polymesh-types to ^7.5.0, which the SDK requires.

BREAKING CHANGE: chain v7 is no longer supported. The SDK throws on
initialization when pointed at a v7 node, so deployments must run a
chain 8.0.x or 8.1.x node.
AccountManagement.subsidizeAccount is removed in SDK v31. The
approve/accept subsidy pair replaces the authorization based flow.

BREAKING CHANGE: POST /accounts/subsidy/create is removed. Use
POST /accounts/subsidy/approve followed by POST /accounts/subsidy/accept.
Instruction.withdraw and withdrawAsMediator are removed in SDK v31 with
no v8 equivalent.

BREAKING CHANGE: POST /instructions/:id/withdraw and
POST /instructions/:id/withdraw-as-mediator are removed. Reject the
instruction instead, via POST /instructions/:id/reject or
POST /instructions/:id/reject-as-mediator.
Claims.getCddClaims is removed in SDK v31.

BREAKING CHANGE: GET /identities/:did/cdd-claims is removed. It already
threw NotSupported against a v8 chain, so it has not been functional
since the v8 migration.
InvalidSenderCdd and ScopeClaimMissing are removed, as transfers are no
longer CDD gated on v8. Use InvalidReceiverIdentity, a new member the
chain now reports for an inactive receiving Identity.
Assets.transferFunds now resolves to Instruction | undefined, since the
holders may belong to different Identities. It settles in the same
transaction when the receiver affirms automatically, otherwise a pending
Instruction is returned for the receiver to affirm.
Context.isV7 is removed in v31, so the v7 branches are dropped. The
cddServiceProviders pallet no longer exists either, which would have
thrown at runtime, so test admins are now added via didRegistrars.

This branch was previously gated on isChainV7, meaning create-test-admins
granted nothing at all on a v8 chain.
TxGroup.RelayerManagement is removed, since every relayer extrinsic is
ensure_signed only and the group never gated anything. DidRegistration
and InstructionMediation are new.
AccountBalance gained reserved and frozen fields in SDK v30.2, and
locked now includes held funds (e.g. bonded for staking) rather than
only the chain's frozen value. Add a dedicated AccountBalanceModel for
GET /accounts/:account/balance so these are documented and serialized,
rather than reusing the generic asset BalanceModel which has no
staking-specific semantics.
Transfers are no longer CDD gated on chain v8, so the receiver can no
longer fail a POLYX transfer for lacking a CDD claim.
As of chain v8, createCdd and expiry no longer have any on-chain effect
on identity.cddRegisterDid/cddRegisterDidWithCdd, so requiring createCdd
in the request body no longer reflects reality. Both fields are now
optional and marked deprecated, and the stale "Expiry cannot be set
unless a CDD claim is being created" failure doc is dropped.
Chain v8 is now the only supported chain, so qualifiers like "on chain
v8" and references to v7-only behavior no longer add information.
ScopeClaimProof was removed from the SDK in v31, since Investor
Uniqueness has been removed from the chain for some time. The DTO
was unreferenced anywhere in this codebase.
A Portfolio can now pre-approve receiving a specific Asset, so incoming
transfers of it auto-affirm without a manual affirm step. Adds
POST /identities/:did/portfolios/:id/pre-approve-asset,
POST .../remove-pre-approval, GET .../is-pre-approved and
GET .../pre-approved-assets, mirroring the existing Identity-level
pre-approval endpoints.
Instruction.lockForExecution existed in the SDK since v30 but was never
wired up, and unlockForExecution/getRelockStatus are new in v31. Adds
POST /instructions/:id/lock, POST /instructions/:id/unlock and
GET /instructions/:id/relock-status, completing the lock/relock cycle
a mediator uses to pause and resume execution of a pending Instruction.
Adds GET /instructions/:id/legs/:legId/status, returning the execution
status of a specific leg (PendingTokenLock, ExecutionPending, or
ExecutionToBeSkipped with the skipping signer and receipt UID).
Adds POST /identities/register-did, wrapping the new SDK
Identities.registerDid procedure. Unlike the existing register
endpoint, this only takes a targetAccount and does not support
secondary keys or CDD claims.
Adds GET /venues/:id/signer-count, wrapping the new SDK
Venue.getSignerCount procedure.
Adds GET /assets/:asset/funding-rounds/:round/issued, wrapping the new
SDK BaseAsset.getIssuedInFundingRound procedure.
Adds GET /assets/:asset/checkpoints/schedules/next, wrapping the new SDK
Schedules.getNextCheckpoint procedure. Returns the closest upcoming
Checkpoint across all of an Asset's active Schedules in a single query,
or null if the Asset has no active Schedules.
Adds GET /assets/:asset/corporate-actions/:id/documents, wrapping the
new SDK CorporateActionBase.getDocuments procedure. This is the missing
read-side counterpart to the existing documents/link endpoint.
Dropped during commit splitting; this mock class isn't currently
referenced by any spec (they use an inline mock object instead), so
this had no test impact, but it belongs alongside the rest of the
class's methods.
Adds GET /ticker-reservations/config, wrapping the new SDK
Assets.getTickerRegistrationConfig procedure. Returns the chain-wide
maxTickerLength and registrationLength rules used to validate ticker
registrations.
CreateInstructionDto only exposed endBlock/endAfterBlock, so there was
no way to create a SettleAfterLock Instruction through the REST API,
meaning the lock/unlock/relock-status endpoints had no reachable happy
path. Adds endAfterLock, matching the SDK's AddInstructionParams.

Verified end-to-end against a local chain: create with endAfterLock,
affirm, lock, check relock-status, unlock, and confirm the cooldown
window populates correctly.
31.0.0-beta.8 was promoted to the stable v31.0.0 release with no code
changes beyond the version bump itself (confirmed by diffing the two
published packages). No other dependency versions changed.
Between beta.7 and the stable v31.0.0 release, the SDK made expiresAt
required (previously optional) on Instruction.generateOffChainAffirmationReceipt
and OffChainAffirmationReceipt, for both the server-generated and the
already-signed passthrough case. OffChainAffirmationReceiptDto now
mirrors that.

BREAKING CHANGE: expiresAt on a receipt in AffirmInstructionDto.receipts
is now required; previously it could be omitted.
@socket-security

socket-security Bot commented Aug 19, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​polymeshassociation/​polymesh-sdk@​30.0.0 ⏵ 31.0.087 +610010096 +2100
Updated@​polymeshassociation/​polymesh-types@​7.4.0 ⏵ 7.5.09810010089 -2100

View full report

@socket-security

socket-security Bot commented Aug 19, 2026

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

…ints

SonarCloud flagged a 31-line duplicate block between preApproveAsset and
removeAssetPreApproval (PR #369) - their ApiParam/ApiTransactionResponse/
ApiTransactionFailedResponse decorators were identical apart from two
short strings. Extracted into ApiPortfolioAssetPreApprovalResponses,
parameterized by the id description and the unprocessable entity
message, following the applyDecorators pattern already used elsewhere
in this codebase (e.g. ApiTransactionResponse itself).

No behavior change: same decorators applied with the same arguments,
just composed rather than stacked inline. Full suite still 1071/1071
passing with unchanged coverage.
Returning null from a Nest controller produces a zero-length response
body, not the JSON literal "null" - any client doing response.json()
or JSON.parse() on it throws.
…ength

The shared @FromBigNumber() decorator does value?.toString(), which
turns null into undefined - and undefined-valued properties are
dropped by JSON serialization entirely. That silently defeats the
`nullable: true` swagger annotation: clients can no longer distinguish
"registrations never expire" (null) from "field not supported"
(absent). Replaced with a dedicated transform that preserves null,
verified through the actual class-transformer serialization pipeline
rather than plain object construction, which wouldn't have caught this.
The final image stage's `COPY --chown=node:node . /home/node` copies the
whole build context over the top of the fresh `./dist` the builder stage
just produced. `dist` is gitignored but wasn't dockerignored, so a stale
local `dist/` (e.g. from a prior `yarn build`) silently wins over the
actual build with no warning - same image digest whether cached or
--no-cache, since the COPY step's content hash matches.
@sonarqubecloud

Copy link
Copy Markdown

@prashantasdeveloper

Copy link
Copy Markdown
Contributor Author

/fast-forward

@prashantasdeveloper
prashantasdeveloper merged commit d83b488 into alpha Aug 24, 2026
10 checks passed
@prashantasdeveloper
prashantasdeveloper deleted the feat/bump-sdk-v31 branch August 24, 2026 15:52
@polymesh-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.0.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants