paritytech / paritytech/contract-dependency-manager

TypeScript version pinning: honor the cdm.json pin in ContractManager calls (needs ~20 lines in product-sdk)

Open
#78 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4
Forks
3
Avg merge
4d 13h
Merged PRs (30d)
3

Description

Problem

Since #76, cdm install pins an exact version per dependency — cdm.json carries {version: "1.2.1", address: <stable proxy>, abi} and the ABI is version-exact. But TypeScript consumers still get latest execution: ContractManager encodes calldata from the pinned ABI and sends it plain, and the per-name proxy routes plain calldata to the latest implementation. Result today: "1.2.1's ABI, latest's implementation" — safe only as long as publishers honor semver.

The on-chain side is fully deployed and e2e-proven: prefixing calldata with [MAGIC 0xa2264d53][u128 versionKey] makes the proxy execute exactly that version (UnsupportedVersion() below the owner's minSupported floor). What's missing is only the last-mile wiring in the TS call path.

Where the work lives

~20 lines in product-sdk-contracts, ~0 lines here. ContractManager's buildReviveCall assembles [selector][args] and sends it through exactly two choke points — the ReviveApi.call dry-run and the Revive.call transaction. Prefix injection belongs at those two sites (an optional calldata-prefix threaded through, inert when unset). Doing it CDM-side would mean duplicating product-sdk's call pipeline (weight estimation, revert decoding) in a wrapper.

Better still: ContractManager.fromClient(cdmJson, …) is already CDM-aware — it reads each entry's address from cdm.json. It can read the pinned version from the same entry and derive the 20-byte prefix itself (keccak256("cdm.proxy.call.v1")[..4] ++ major<<64|minor<<32|patch as big-endian u128 — mirrored with tests in @parity/cdm-builder/proxy).

End-user surface

Unchanged — the pin becomes true instead of cosmetic:

const contracts = ContractManager.fromClient(cdmJson, chain.raw.assetHub, paseo_asset_hub);
const counter = contracts.getContract("@yourorg/counter"); // cdm.json pins 1.2.1
await counter.increment.tx();                              // executes 1.2.1, not latest

with following-latest becoming the explicit opt-in:

contracts.getContract("@yourorg/counter", { version: "latest" });

Tasks

  • product-sdk: optional calldata prefix through buildReviveCall's dry-run + tx sites (or native cdm.json version awareness deriving it)
  • product-sdk: { version: "latest" } opt-out on getContract
  • here: catalog bump once released; docs + a pinned-execution e2e case (the wire helpers and proxy routing are already covered by proxy.e2e.test.ts)

References

  • #76 — wire format (contract-registry-core::versioning, mirrored in src/lib/contracts/src/proxy.ts); proxy.e2e.test.ts proves versioned routing + UnsupportedVersion gating on-chain.
  • Rust consumers have the same gap with a different blocker (upstream CallBuilder preamble in cargo-pvm-contract); Solidity's counterpart is tracked separately.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in product-sdk-contracts at ContractManager.buildReviveCall and trace the ReviveApi.call dry-run and Revive.call transaction sites. Compare the version-prefix helpers and tests in @parity/cdm-builder/proxy and proxy.e2e.test.ts. Done means pinned cdm.json versions execute correctly, latest is an explicit opt-out, and the catalog, docs, and pinned-execution e2e case are updated here.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, blockchain
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.