Contracts¶
Introduction¶
@parity/product-sdk-contracts gives your Product typed access to smart contracts deployed on Asset Hub. It calls pallet-revive (PolkaVM) contracts through the typed chain API, resolves each contract's address and ABI from a cdm.json manifest, and exposes reads, signed writes, and atomic batches on a typed handle.
It is the frontend counterpart to deploying a contract: once a contract is deployed and registered, this package turns its manifest entry into a typed object you call by name.
When to Use It¶
- To call a contract deployed on Asset Hub: reads with
query, signed writes withtx, or atomic multi-call batches withprepare. - When you have a
cdm.jsonmanifest (address and ABI per installed contract), which is the primary path viaContractManager.fromClient. - Not for deploying contracts; deployment is handled by the
cdmtoolchain, covered in Add a Smart Contract to Your Product. The target chain must expose theRevivepallet.
Core Concepts¶
ContractManager: Resolves contracts from acdm.jsonmanifest.fromClient(...)is synchronous and uses the addresses snapshotted in the manifest;getContract(name)returns a typed handle and throwsContractNotFoundErrorif the name is not in the manifest.- Contract handle: Each ABI method exposes
query,tx, andprepare. queryreturns a discriminated result: A read is a dry run that returns{ success, value, gasRequired }. It does not throw on a revert, so branch on.successrather than usingtry/catch.txreturns aResult: A signed write returns aResult(check.ok). Before signing, it dry-runs the call to size gas and fail fast on a revert.- Account mapping:
pallet-reviverequires each signing account to be mapped to its H160 address once. CallensureContractAccountMappedat startup, or everytxon a fresh account fails withAccountNotMapped. - Product-account signing: Writes are signed by your Product-scoped account, so contract calls route to the user's phone for approval like any other transaction.
Call a Contract¶
Build a manager from the manifest and the chain client, map the account once, then read and write:
import {
ContractManager,
ensureContractAccountMapped,
} from '@parity/product-sdk-contracts';
import { paseo_asset_hub } from '@parity/product-sdk-descriptors/paseo-asset-hub';
import cdmJson from './cdm.json';
const manager = ContractManager.fromClient(
cdmJson,
chain.raw.assetHub,
paseo_asset_hub,
{ signerManager },
);
await ensureContractAccountMapped(manager.getRuntime(), account.address, signer);
const counter = manager.getContract('@my-app/counter');
// Read: a dry run. Check .success, not .ok.
const count = await counter.getCount.query();
if (count.success) console.log(count.value);
// Write: signs through the Host. Check .ok.
const result = await counter.increment.tx({ signer });
if (!result.ok) console.error(result.error.message);
Limitations¶
querynever throws on a chain-side failure; it returns{ success: false, value: <error> }, so branch on.success.- A fresh signing account fails every
txwithAccountNotMappeduntilensureContractAccountMappedruns once. - Passing both
gasLimitandstorageDepositLimitskips the dry-run, including the revert pre-check, so a reverting transaction is still submitted and its gas paid. - The
/codegenand/pvmsubpaths pull in Node-only modules; keep them out of browser bundles.
Where to Go Next¶
-
Guide Add a Smart Contract to Your Product
The task-focused recipe: scaffold, deploy, and register a contract, then wire it into your frontend.
-
Learn Transactions
The submission layer this package builds on for its signed writes and batches.
-
External API Reference
The complete
contractssurface:ContractManager, contract handles, and thepvmsubpath.
| Created: September 2, 2026