@parity/product-sdk-contracts 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +224 -0
- package/dist/chunk-E7AP65D4.js +2 -173
- package/dist/chunk-E7AP65D4.js.map +1 -1
- package/dist/{codegen-Apg73XJX.d.ts → codegen-BPDBGrJC.d.ts} +50 -3
- package/dist/codegen.d.ts +1 -1
- package/dist/codegen.js +2 -6
- package/dist/codegen.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +27 -191
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# @parity/product-sdk-contracts
|
|
2
|
+
|
|
3
|
+
Typed contract interactions on Polkadot Asset Hub. Resolve deployed contracts from a `cdm.json` manifest, get fully-typed handles for `query`, `tx`, and batched `prepare` calls — all backed by the ink SDK.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @parity/product-sdk-contracts
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start (with cdm.json)
|
|
12
|
+
|
|
13
|
+
The `cdm.json` flow is the primary path. A `cdm.json` manifest in your project root pins each contract to an address + ABI per target chain; `ContractManager.fromClient(cdm, api)` resolves them at runtime.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createChainClient } from "@parity/product-sdk-chain-client";
|
|
17
|
+
import { paseo_asset_hub } from "@parity/product-sdk-descriptors/paseo-asset-hub";
|
|
18
|
+
import { ContractManager } from "@parity/product-sdk-contracts";
|
|
19
|
+
import { SignerManager } from "@parity/product-sdk-signer";
|
|
20
|
+
import cdmJson from "./cdm.json";
|
|
21
|
+
|
|
22
|
+
const client = await createChainClient({
|
|
23
|
+
chains: { assetHub: paseo_asset_hub },
|
|
24
|
+
rpcs: { assetHub: ["wss://asset-hub-paseo-rpc.n.dwellir.com"] },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const signerManager = new SignerManager();
|
|
28
|
+
await signerManager.connect();
|
|
29
|
+
|
|
30
|
+
const manager = await ContractManager.fromClient(cdmJson, client.raw.assetHub, {
|
|
31
|
+
signerManager,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Resolve by library name — typed handle returned.
|
|
35
|
+
const registry = manager.getContract("@w3s/playground-registry");
|
|
36
|
+
|
|
37
|
+
// Read state
|
|
38
|
+
const { value } = await registry.publish.query("my-app00", "ipfs://...", 0);
|
|
39
|
+
|
|
40
|
+
// Submit a tx (uses signerManager's logged-in account)
|
|
41
|
+
await registry.publish.tx("my-app00", "ipfs://...", 0);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## `ContractManager` API
|
|
45
|
+
|
|
46
|
+
### `ContractManager.fromClient(cdmJson, client, options?)`
|
|
47
|
+
|
|
48
|
+
Async factory. Lazy-imports `@polkadot-api/sdk-ink` (~4 MB) only when called, so the install footprint stays small for callers who never resolve contracts.
|
|
49
|
+
|
|
50
|
+
| Param | Type | Notes |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| `cdmJson` | `CdmJson` | Imported `cdm.json` |
|
|
53
|
+
| `client` | `PolkadotClient` | E.g. `client.raw.assetHub` |
|
|
54
|
+
| `options.signerManager?` | `SignerManager` | Resolves signer + origin from the logged-in account |
|
|
55
|
+
| `options.defaultOrigin?` | `SS58String` | Static fallback origin for queries |
|
|
56
|
+
| `options.defaultSigner?` | `PolkadotSigner` | Static fallback signer for txs |
|
|
57
|
+
| `options.targetHash?` | `string` | Pin to a specific target. Defaults to first target in the manifest. |
|
|
58
|
+
|
|
59
|
+
### `manager.getContract(library)`
|
|
60
|
+
|
|
61
|
+
Returns a typed `Contract<C>` handle. Each ABI method exposes:
|
|
62
|
+
|
|
63
|
+
- `.query(...args, opts?)` — read-only dry-run; returns `{ success, value, gasRequired }`
|
|
64
|
+
- `.tx(...args, opts?)` — sign, submit, and watch; resolves at best-block
|
|
65
|
+
- `.prepare(...args, opts?)` — batch-ready handle (see *Batching* below)
|
|
66
|
+
|
|
67
|
+
When codegen-generated types are present, the call is fully typed:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const registry = manager.getContract("@w3s/playground-registry");
|
|
71
|
+
// ^ autocompletes from cdm.json
|
|
72
|
+
await registry.publish.tx("domain", "ipfs://cid", 0);
|
|
73
|
+
// ^ method name typed
|
|
74
|
+
// ^ args typed
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Throws `ContractNotFoundError` if the library name isn't in the manifest for the active target.
|
|
78
|
+
|
|
79
|
+
### `manager.getAddress(library)`
|
|
80
|
+
|
|
81
|
+
Returns the on-chain address. Useful for logging or display.
|
|
82
|
+
|
|
83
|
+
### `manager.setDefaults(defaults)`
|
|
84
|
+
|
|
85
|
+
Update `origin`, `signer`, or `signerManager` after construction. Only the fields you pass are updated.
|
|
86
|
+
|
|
87
|
+
## Signer / origin resolution
|
|
88
|
+
|
|
89
|
+
Order, highest wins:
|
|
90
|
+
|
|
91
|
+
1. Explicit `{ signer }` / `{ origin }` in the call options
|
|
92
|
+
2. `signerManager`'s currently selected account
|
|
93
|
+
3. Static `defaultSigner` / `defaultOrigin`
|
|
94
|
+
4. (Queries only) Dev fallback (Alice) for dry-run gas estimation
|
|
95
|
+
|
|
96
|
+
Throws `ContractSignerMissingError` from `.tx()` if no signer is available. `.query()` and `.prepare()` never need a signer.
|
|
97
|
+
|
|
98
|
+
## Batching with `.prepare()`
|
|
99
|
+
|
|
100
|
+
Use `.prepare()` to build `BatchableCall` handles consumable by `batchSubmitAndWatch` from `@parity/product-sdk-tx`. Combine multiple contract calls — or contract calls mixed with other Asset Hub transactions — into a single atomic `Utility.batch_all` extrinsic.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { batchSubmitAndWatch } from "@parity/product-sdk-tx";
|
|
104
|
+
|
|
105
|
+
const a = registry.publish.prepare("app-one00", "ipfs://...", 0);
|
|
106
|
+
const b = registry.publish.prepare("app-two00", "ipfs://...", 0);
|
|
107
|
+
|
|
108
|
+
await batchSubmitAndWatch([a, b], client.raw.assetHub, signer);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**`.prepare()` doesn't require a signer.** The resolved origin is used purely for dry-run gas estimation; the batch submission's signer is the dispatched origin at submission time.
|
|
112
|
+
|
|
113
|
+
`PrepareOptions` accepts: `origin`, `value`, `gasLimit`, `storageDepositLimit`. Signer and submission lifecycle options (`signer`, `waitFor`, etc.) are intentionally absent — those belong to the batch submit, not the individual prepared call.
|
|
114
|
+
|
|
115
|
+
## Without cdm.json — manual path
|
|
116
|
+
|
|
117
|
+
If you don't have a `cdm.json` (or want to test against a contract not yet in your manifest), use `createContract` / `createContractFromClient` with an explicit address and ABI:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { createContractFromClient } from "@parity/product-sdk-contracts";
|
|
121
|
+
|
|
122
|
+
const counter = await createContractFromClient(
|
|
123
|
+
client.raw.assetHub,
|
|
124
|
+
"0xC472...",
|
|
125
|
+
counterAbi,
|
|
126
|
+
{ signerManager },
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const { value } = await counter.getCount.query();
|
|
130
|
+
await counter.increment.tx();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`createContract` is the same but takes a pre-created `InkSdk` if you want to control when `@polkadot-api/sdk-ink` loads.
|
|
134
|
+
|
|
135
|
+
## cdm.json schema
|
|
136
|
+
|
|
137
|
+
Top-level shape:
|
|
138
|
+
|
|
139
|
+
```jsonc
|
|
140
|
+
{
|
|
141
|
+
"targets": {
|
|
142
|
+
"<targetHash>": {
|
|
143
|
+
"asset-hub": "wss://asset-hub-paseo-rpc.n.dwellir.com",
|
|
144
|
+
"bulletin": "https://paseo-ipfs.polkadot.io/ipfs"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"dependencies": {
|
|
148
|
+
"<targetHash>": {
|
|
149
|
+
"@org/contract-name": "latest"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"contracts": {
|
|
153
|
+
"<targetHash>": {
|
|
154
|
+
"@org/contract-name": {
|
|
155
|
+
"version": 6,
|
|
156
|
+
"address": "0x4A37B123b0BA2A894cA5953f472264921d44e298",
|
|
157
|
+
"abi": [ /* Solidity-compatible ABI entries */ ]
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`<targetHash>` is a 16-character hex string identifying a chain runtime + Bulletin gateway pairing. A manifest can declare multiple targets; `ContractManager` defaults to the first, or pin one via `options.targetHash`.
|
|
165
|
+
|
|
166
|
+
A real-world example: [`paritytech/playground-cli/cdm.json`](https://github.com/paritytech/playground-cli/blob/main/cdm.json).
|
|
167
|
+
|
|
168
|
+
## Type generation
|
|
169
|
+
|
|
170
|
+
`generateContractTypes(...)` (from `@parity/product-sdk-contracts/codegen`) emits a `.d.ts` that augments the package's `Contracts` interface so `manager.getContract("@org/name")` returns a fully-typed handle:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { generateContractTypes } from "@parity/product-sdk-contracts/codegen";
|
|
174
|
+
import cdm from "./cdm.json";
|
|
175
|
+
import { writeFileSync } from "node:fs";
|
|
176
|
+
|
|
177
|
+
const src = generateContractTypes(cdm);
|
|
178
|
+
writeFileSync(".cdm/contracts.d.ts", src);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Wire `.cdm/contracts.d.ts` into your `tsconfig.json`'s `include` and the next time you call `getContract("@org/name")`, the method names, parameter types, and return types come straight from the ABI.
|
|
182
|
+
|
|
183
|
+
Without codegen, `getContract()` still works — methods are accessible but untyped (`Contract<ContractDef>`).
|
|
184
|
+
|
|
185
|
+
## Errors
|
|
186
|
+
|
|
187
|
+
| Error | When |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| `ContractNotFoundError` | `getContract(name)` and `name` isn't in the manifest for the active target |
|
|
190
|
+
| `ContractSignerMissingError` | `.tx()` called with no signer + no signerManager + no defaultSigner |
|
|
191
|
+
| Generic | ABI decode failures, RPC errors, gas estimation failures — surface from the underlying ink SDK |
|
|
192
|
+
|
|
193
|
+
## Public API
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
export {
|
|
197
|
+
ContractManager,
|
|
198
|
+
createContract,
|
|
199
|
+
createContractFromClient,
|
|
200
|
+
generateContractTypes,
|
|
201
|
+
ContractError,
|
|
202
|
+
ContractSignerMissingError,
|
|
203
|
+
ContractNotFoundError,
|
|
204
|
+
};
|
|
205
|
+
export type {
|
|
206
|
+
CdmJson,
|
|
207
|
+
CdmJsonTarget,
|
|
208
|
+
CdmJsonContract,
|
|
209
|
+
AbiParam,
|
|
210
|
+
AbiEntry,
|
|
211
|
+
Contract,
|
|
212
|
+
ContractDef,
|
|
213
|
+
Contracts,
|
|
214
|
+
QueryResult,
|
|
215
|
+
QueryOptions,
|
|
216
|
+
TxOptions,
|
|
217
|
+
TxResult,
|
|
218
|
+
PrepareOptions,
|
|
219
|
+
BatchableCall,
|
|
220
|
+
ContractDefaults,
|
|
221
|
+
ContractManagerOptions,
|
|
222
|
+
ContractOptions,
|
|
223
|
+
};
|
|
224
|
+
```
|
package/dist/chunk-E7AP65D4.js
CHANGED
|
@@ -67,178 +67,7 @@ function generateContractTypes(contracts) {
|
|
|
67
67
|
lines.push("");
|
|
68
68
|
return lines.join("\n");
|
|
69
69
|
}
|
|
70
|
-
if (void 0) {
|
|
71
|
-
const { test, expect, describe } = void 0;
|
|
72
|
-
describe("mapSolidityType", () => {
|
|
73
|
-
const cases = [
|
|
74
|
-
[{ name: "x", type: "uint8" }, "number"],
|
|
75
|
-
[{ name: "x", type: "uint16" }, "number"],
|
|
76
|
-
[{ name: "x", type: "uint32" }, "number"],
|
|
77
|
-
[{ name: "x", type: "uint64" }, "bigint"],
|
|
78
|
-
[{ name: "x", type: "uint128" }, "bigint"],
|
|
79
|
-
[{ name: "x", type: "uint256" }, "bigint"],
|
|
80
|
-
[{ name: "x", type: "int8" }, "number"],
|
|
81
|
-
[{ name: "x", type: "int32" }, "number"],
|
|
82
|
-
[{ name: "x", type: "int64" }, "bigint"],
|
|
83
|
-
[{ name: "x", type: "int256" }, "bigint"],
|
|
84
|
-
[{ name: "x", type: "address" }, "HexString"],
|
|
85
|
-
[{ name: "x", type: "bool" }, "boolean"],
|
|
86
|
-
[{ name: "x", type: "string" }, "string"],
|
|
87
|
-
[{ name: "x", type: "bytes" }, "Binary"],
|
|
88
|
-
[{ name: "x", type: "bytes32" }, "FixedSizeBinary<32>"],
|
|
89
|
-
[{ name: "x", type: "bytes4" }, "FixedSizeBinary<4>"],
|
|
90
|
-
[{ name: "x", type: "uint256[]" }, "bigint[]"],
|
|
91
|
-
[{ name: "x", type: "address[]" }, "HexString[]"],
|
|
92
|
-
[{ name: "x", type: "uint256[3]" }, "bigint[]"],
|
|
93
|
-
[{ name: "x", type: "somethingWeird" }, "unknown"]
|
|
94
|
-
];
|
|
95
|
-
for (const [param, expected] of cases) {
|
|
96
|
-
test(`${param.type} \u2192 ${expected}`, () => {
|
|
97
|
-
expect(mapSolidityType(param)).toBe(expected);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
test("tuple with components", () => {
|
|
101
|
-
const param = {
|
|
102
|
-
name: "info",
|
|
103
|
-
type: "tuple",
|
|
104
|
-
components: [
|
|
105
|
-
{ name: "addr", type: "address" },
|
|
106
|
-
{ name: "amount", type: "uint256" }
|
|
107
|
-
]
|
|
108
|
-
};
|
|
109
|
-
expect(mapSolidityType(param)).toBe("{ addr: HexString; amount: bigint }");
|
|
110
|
-
});
|
|
111
|
-
test("nested array of tuples", () => {
|
|
112
|
-
const param = {
|
|
113
|
-
name: "items",
|
|
114
|
-
type: "tuple[]",
|
|
115
|
-
components: [
|
|
116
|
-
{ name: "id", type: "uint32" },
|
|
117
|
-
{ name: "name", type: "string" }
|
|
118
|
-
]
|
|
119
|
-
};
|
|
120
|
-
expect(mapSolidityType(param)).toBe("{ id: number; name: string }[]");
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
describe("generateMethodArgsType", () => {
|
|
124
|
-
test("empty inputs", () => {
|
|
125
|
-
expect(generateMethodArgsType([])).toBe("[]");
|
|
126
|
-
});
|
|
127
|
-
test("single input", () => {
|
|
128
|
-
expect(generateMethodArgsType([{ name: "to", type: "address" }])).toBe(
|
|
129
|
-
"[to: HexString]"
|
|
130
|
-
);
|
|
131
|
-
});
|
|
132
|
-
test("multiple inputs", () => {
|
|
133
|
-
const result = generateMethodArgsType([
|
|
134
|
-
{ name: "to", type: "address" },
|
|
135
|
-
{ name: "amount", type: "uint256" }
|
|
136
|
-
]);
|
|
137
|
-
expect(result).toBe("[to: HexString, amount: bigint]");
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
describe("generateMethodResponseType", () => {
|
|
141
|
-
test("no outputs", () => {
|
|
142
|
-
expect(generateMethodResponseType(void 0)).toBe("undefined");
|
|
143
|
-
expect(generateMethodResponseType([])).toBe("undefined");
|
|
144
|
-
});
|
|
145
|
-
test("single output", () => {
|
|
146
|
-
expect(generateMethodResponseType([{ name: "", type: "uint32" }])).toBe("number");
|
|
147
|
-
});
|
|
148
|
-
test("multiple outputs", () => {
|
|
149
|
-
const result = generateMethodResponseType([
|
|
150
|
-
{ name: "balance", type: "uint256" },
|
|
151
|
-
{ name: "nonce", type: "uint32" }
|
|
152
|
-
]);
|
|
153
|
-
expect(result).toBe("{ balance: bigint; nonce: number }");
|
|
154
|
-
});
|
|
155
|
-
test("unnamed outputs get positional names", () => {
|
|
156
|
-
const result = generateMethodResponseType([
|
|
157
|
-
{ name: "", type: "bool" },
|
|
158
|
-
{ name: "", type: "uint256" }
|
|
159
|
-
]);
|
|
160
|
-
expect(result).toBe("{ _0: boolean; _1: bigint }");
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
describe("generateContractTypes", () => {
|
|
164
|
-
test("generates valid module augmentation", () => {
|
|
165
|
-
const result = generateContractTypes([
|
|
166
|
-
{
|
|
167
|
-
library: "@example/counter",
|
|
168
|
-
abi: [
|
|
169
|
-
{
|
|
170
|
-
type: "constructor",
|
|
171
|
-
inputs: [],
|
|
172
|
-
stateMutability: "nonpayable"
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
type: "function",
|
|
176
|
-
name: "getCount",
|
|
177
|
-
inputs: [],
|
|
178
|
-
outputs: [{ name: "", type: "uint32" }],
|
|
179
|
-
stateMutability: "view"
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
type: "function",
|
|
183
|
-
name: "increment",
|
|
184
|
-
inputs: [],
|
|
185
|
-
outputs: [],
|
|
186
|
-
stateMutability: "nonpayable"
|
|
187
|
-
}
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
]);
|
|
191
|
-
expect(result).toContain('declare module "@parity/product-sdk-contracts"');
|
|
192
|
-
expect(result).toContain("interface Contracts");
|
|
193
|
-
expect(result).toContain('"@example/counter"');
|
|
194
|
-
expect(result).toContain("getCount: { args: []; response: number };");
|
|
195
|
-
expect(result).toContain("increment: { args: []; response: undefined };");
|
|
196
|
-
expect(result).not.toContain("constructor");
|
|
197
|
-
});
|
|
198
|
-
test("handles multiple contracts", () => {
|
|
199
|
-
const result = generateContractTypes([
|
|
200
|
-
{
|
|
201
|
-
library: "@a/one",
|
|
202
|
-
abi: [
|
|
203
|
-
{
|
|
204
|
-
type: "function",
|
|
205
|
-
name: "foo",
|
|
206
|
-
inputs: [{ name: "x", type: "uint256" }],
|
|
207
|
-
outputs: [{ name: "", type: "bool" }]
|
|
208
|
-
}
|
|
209
|
-
]
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
library: "@b/two",
|
|
213
|
-
abi: [
|
|
214
|
-
{
|
|
215
|
-
type: "function",
|
|
216
|
-
name: "bar",
|
|
217
|
-
inputs: [],
|
|
218
|
-
outputs: [{ name: "", type: "address" }]
|
|
219
|
-
}
|
|
220
|
-
]
|
|
221
|
-
}
|
|
222
|
-
]);
|
|
223
|
-
expect(result).toContain('"@a/one"');
|
|
224
|
-
expect(result).toContain('"@b/two"');
|
|
225
|
-
expect(result).toContain("foo: { args: [x: bigint]; response: boolean };");
|
|
226
|
-
expect(result).toContain("bar: { args: []; response: HexString };");
|
|
227
|
-
});
|
|
228
|
-
test("empty contracts list", () => {
|
|
229
|
-
const result = generateContractTypes([]);
|
|
230
|
-
expect(result).toContain("interface Contracts {");
|
|
231
|
-
expect(result).toContain("}");
|
|
232
|
-
});
|
|
233
|
-
test("includes polkadot-api type imports", () => {
|
|
234
|
-
const result = generateContractTypes([]);
|
|
235
|
-
expect(result).toContain("import type { HexString, Binary, FixedSizeBinary }");
|
|
236
|
-
expect(result).toContain('from "polkadot-api"');
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
70
|
|
|
241
|
-
export {
|
|
242
|
-
|
|
243
|
-
};
|
|
71
|
+
export { generateContractTypes };
|
|
72
|
+
//# sourceMappingURL=chunk-E7AP65D4.js.map
|
|
244
73
|
//# sourceMappingURL=chunk-E7AP65D4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/codegen.ts"],"sourcesContent":["import type { AbiEntry, AbiParam } from \"./types.js\";\n\n/** Map a Solidity ABI type to its TypeScript equivalent. */\nfunction mapSolidityType(param: AbiParam): string {\n const t = param.type;\n\n // Dynamic arrays — e.g. uint256[]\n if (t.endsWith(\"[]\")) {\n const inner = { ...param, type: t.slice(0, -2) };\n return `${mapSolidityType(inner)}[]`;\n }\n\n // Fixed-size arrays — e.g. uint256[3]\n const fixedArrayMatch = t.match(/^(.+)\\[(\\d+)\\]$/);\n if (fixedArrayMatch) {\n const inner = { ...param, type: fixedArrayMatch[1] };\n return `${mapSolidityType(inner)}[]`;\n }\n\n // Tuple\n if (t === \"tuple\" && param.components) {\n const fields = param.components.map((c) => `${c.name}: ${mapSolidityType(c)}`);\n return `{ ${fields.join(\"; \")} }`;\n }\n\n // Unsigned integers — uint8/16/32 fit in JS number\n if (/^uint(8|16|32)$/.test(t)) return \"number\";\n if (/^uint\\d*$/.test(t)) return \"bigint\";\n\n // Signed integers\n if (/^int(8|16|32)$/.test(t)) return \"number\";\n if (/^int\\d*$/.test(t)) return \"bigint\";\n\n // Address\n if (t === \"address\") return \"HexString\";\n\n // Bytes\n if (t === \"bytes\") return \"Binary\";\n const bytesMatch = t.match(/^bytes(\\d+)$/);\n if (bytesMatch) return `FixedSizeBinary<${bytesMatch[1]}>`;\n\n // Primitives\n if (t === \"bool\") return \"boolean\";\n if (t === \"string\") return \"string\";\n\n return \"unknown\";\n}\n\nfunction generateMethodArgsType(inputs: AbiParam[]): string {\n if (inputs.length === 0) return \"[]\";\n const parts = inputs.map((p) => `${p.name}: ${mapSolidityType(p)}`);\n return `[${parts.join(\", \")}]`;\n}\n\nfunction generateMethodResponseType(outputs: AbiParam[] | undefined): string {\n if (!outputs || outputs.length === 0) return \"undefined\";\n if (outputs.length === 1) return mapSolidityType(outputs[0]);\n const fields = outputs.map((o, i) => {\n const name = o.name || `_${i}`;\n return `${name}: ${mapSolidityType(o)}`;\n });\n return `{ ${fields.join(\"; \")} }`;\n}\n\n/**\n * Generate a TypeScript module augmentation that extends the\n * {@link Contracts} interface with typed method signatures for each\n * installed contract.\n *\n * The output is written to `.cdm/contracts.d.ts` (or equivalent) and\n * augments `\"@parity/product-sdk-contracts\"` so that\n * `ContractManager.getContract()` returns fully-typed handles.\n *\n * @example\n * ```ts\n * const src = generateContractTypes([\n * { library: \"@example/counter\", abi },\n * ]);\n * writeFileSync(\".cdm/contracts.d.ts\", src);\n * ```\n */\nexport function generateContractTypes(contracts: { library: string; abi: AbiEntry[] }[]): string {\n const lines: string[] = [\n \"// Auto-generated by cdm install — do not edit\",\n 'import type { HexString, Binary, FixedSizeBinary } from \"polkadot-api\";',\n \"\",\n 'declare module \"@parity/product-sdk-contracts\" {',\n \" interface Contracts {\",\n ];\n\n for (const contract of contracts) {\n const methods = contract.abi.filter((e) => e.type === \"function\" && e.name);\n lines.push(` \"${contract.library}\": {`);\n lines.push(\" methods: {\");\n for (const method of methods) {\n const args = generateMethodArgsType(method.inputs);\n const response = generateMethodResponseType(method.outputs);\n lines.push(\n ` ${method.name!}: { args: ${args}; response: ${response} };`,\n );\n }\n lines.push(\" };\");\n lines.push(\" };\");\n }\n\n lines.push(\" }\");\n lines.push(\"}\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"mapSolidityType\", () => {\n const cases: [AbiParam, string][] = [\n [{ name: \"x\", type: \"uint8\" }, \"number\"],\n [{ name: \"x\", type: \"uint16\" }, \"number\"],\n [{ name: \"x\", type: \"uint32\" }, \"number\"],\n [{ name: \"x\", type: \"uint64\" }, \"bigint\"],\n [{ name: \"x\", type: \"uint128\" }, \"bigint\"],\n [{ name: \"x\", type: \"uint256\" }, \"bigint\"],\n [{ name: \"x\", type: \"int8\" }, \"number\"],\n [{ name: \"x\", type: \"int32\" }, \"number\"],\n [{ name: \"x\", type: \"int64\" }, \"bigint\"],\n [{ name: \"x\", type: \"int256\" }, \"bigint\"],\n [{ name: \"x\", type: \"address\" }, \"HexString\"],\n [{ name: \"x\", type: \"bool\" }, \"boolean\"],\n [{ name: \"x\", type: \"string\" }, \"string\"],\n [{ name: \"x\", type: \"bytes\" }, \"Binary\"],\n [{ name: \"x\", type: \"bytes32\" }, \"FixedSizeBinary<32>\"],\n [{ name: \"x\", type: \"bytes4\" }, \"FixedSizeBinary<4>\"],\n [{ name: \"x\", type: \"uint256[]\" }, \"bigint[]\"],\n [{ name: \"x\", type: \"address[]\" }, \"HexString[]\"],\n [{ name: \"x\", type: \"uint256[3]\" }, \"bigint[]\"],\n [{ name: \"x\", type: \"somethingWeird\" }, \"unknown\"],\n ];\n\n for (const [param, expected] of cases) {\n test(`${param.type} → ${expected}`, () => {\n expect(mapSolidityType(param)).toBe(expected);\n });\n }\n\n test(\"tuple with components\", () => {\n const param: AbiParam = {\n name: \"info\",\n type: \"tuple\",\n components: [\n { name: \"addr\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n };\n expect(mapSolidityType(param)).toBe(\"{ addr: HexString; amount: bigint }\");\n });\n\n test(\"nested array of tuples\", () => {\n const param: AbiParam = {\n name: \"items\",\n type: \"tuple[]\",\n components: [\n { name: \"id\", type: \"uint32\" },\n { name: \"name\", type: \"string\" },\n ],\n };\n expect(mapSolidityType(param)).toBe(\"{ id: number; name: string }[]\");\n });\n });\n\n describe(\"generateMethodArgsType\", () => {\n test(\"empty inputs\", () => {\n expect(generateMethodArgsType([])).toBe(\"[]\");\n });\n\n test(\"single input\", () => {\n expect(generateMethodArgsType([{ name: \"to\", type: \"address\" }])).toBe(\n \"[to: HexString]\",\n );\n });\n\n test(\"multiple inputs\", () => {\n const result = generateMethodArgsType([\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ]);\n expect(result).toBe(\"[to: HexString, amount: bigint]\");\n });\n });\n\n describe(\"generateMethodResponseType\", () => {\n test(\"no outputs\", () => {\n expect(generateMethodResponseType(undefined)).toBe(\"undefined\");\n expect(generateMethodResponseType([])).toBe(\"undefined\");\n });\n\n test(\"single output\", () => {\n expect(generateMethodResponseType([{ name: \"\", type: \"uint32\" }])).toBe(\"number\");\n });\n\n test(\"multiple outputs\", () => {\n const result = generateMethodResponseType([\n { name: \"balance\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint32\" },\n ]);\n expect(result).toBe(\"{ balance: bigint; nonce: number }\");\n });\n\n test(\"unnamed outputs get positional names\", () => {\n const result = generateMethodResponseType([\n { name: \"\", type: \"bool\" },\n { name: \"\", type: \"uint256\" },\n ]);\n expect(result).toBe(\"{ _0: boolean; _1: bigint }\");\n });\n });\n\n describe(\"generateContractTypes\", () => {\n test(\"generates valid module augmentation\", () => {\n const result = generateContractTypes([\n {\n library: \"@example/counter\",\n abi: [\n {\n type: \"constructor\",\n inputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"getCount\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"increment\",\n inputs: [],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n ],\n },\n ]);\n\n expect(result).toContain('declare module \"@parity/product-sdk-contracts\"');\n expect(result).toContain(\"interface Contracts\");\n expect(result).toContain('\"@example/counter\"');\n expect(result).toContain(\"getCount: { args: []; response: number };\");\n expect(result).toContain(\"increment: { args: []; response: undefined };\");\n // Should not include constructor\n expect(result).not.toContain(\"constructor\");\n });\n\n test(\"handles multiple contracts\", () => {\n const result = generateContractTypes([\n {\n library: \"@a/one\",\n abi: [\n {\n type: \"function\",\n name: \"foo\",\n inputs: [{ name: \"x\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n ],\n },\n {\n library: \"@b/two\",\n abi: [\n {\n type: \"function\",\n name: \"bar\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n ],\n },\n ]);\n\n expect(result).toContain('\"@a/one\"');\n expect(result).toContain('\"@b/two\"');\n expect(result).toContain(\"foo: { args: [x: bigint]; response: boolean };\");\n expect(result).toContain(\"bar: { args: []; response: HexString };\");\n });\n\n test(\"empty contracts list\", () => {\n const result = generateContractTypes([]);\n expect(result).toContain(\"interface Contracts {\");\n expect(result).toContain(\"}\");\n });\n\n test(\"includes polkadot-api type imports\", () => {\n const result = generateContractTypes([]);\n expect(result).toContain(\"import type { HexString, Binary, FixedSizeBinary }\");\n expect(result).toContain('from \"polkadot-api\"');\n });\n });\n}\n"],"mappings":";AAGA,SAAS,gBAAgB,OAAyB;AAC9C,QAAM,IAAI,MAAM;AAGhB,MAAI,EAAE,SAAS,IAAI,GAAG;AAClB,UAAM,QAAQ,EAAE,GAAG,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE;AAC/C,WAAO,GAAG,gBAAgB,KAAK,CAAC;AAAA,EACpC;AAGA,QAAM,kBAAkB,EAAE,MAAM,iBAAiB;AACjD,MAAI,iBAAiB;AACjB,UAAM,QAAQ,EAAE,GAAG,OAAO,MAAM,gBAAgB,CAAC,EAAE;AACnD,WAAO,GAAG,gBAAgB,KAAK,CAAC;AAAA,EACpC;AAGA,MAAI,MAAM,WAAW,MAAM,YAAY;AACnC,UAAM,SAAS,MAAM,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,gBAAgB,CAAC,CAAC,EAAE;AAC7E,WAAO,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,EACjC;AAGA,MAAI,kBAAkB,KAAK,CAAC,EAAG,QAAO;AACtC,MAAI,YAAY,KAAK,CAAC,EAAG,QAAO;AAGhC,MAAI,iBAAiB,KAAK,CAAC,EAAG,QAAO;AACrC,MAAI,WAAW,KAAK,CAAC,EAAG,QAAO;AAG/B,MAAI,MAAM,UAAW,QAAO;AAG5B,MAAI,MAAM,QAAS,QAAO;AAC1B,QAAM,aAAa,EAAE,MAAM,cAAc;AACzC,MAAI,WAAY,QAAO,mBAAmB,WAAW,CAAC,CAAC;AAGvD,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,MAAM,SAAU,QAAO;AAE3B,SAAO;AACX;AAEA,SAAS,uBAAuB,QAA4B;AACxD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,gBAAgB,CAAC,CAAC,EAAE;AAClE,SAAO,IAAI,MAAM,KAAK,IAAI,CAAC;AAC/B;AAEA,SAAS,2BAA2B,SAAyC;AACzE,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO;AAC7C,MAAI,QAAQ,WAAW,EAAG,QAAO,gBAAgB,QAAQ,CAAC,CAAC;AAC3D,QAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,MAAM;AACjC,UAAM,OAAO,EAAE,QAAQ,IAAI,CAAC;AAC5B,WAAO,GAAG,IAAI,KAAK,gBAAgB,CAAC,CAAC;AAAA,EACzC,CAAC;AACD,SAAO,KAAK,OAAO,KAAK,IAAI,CAAC;AACjC;AAmBO,SAAS,sBAAsB,WAA2D;AAC7F,QAAM,QAAkB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,aAAW,YAAY,WAAW;AAC9B,UAAM,UAAU,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,IAAI;AAC1E,UAAM,KAAK,YAAY,SAAS,OAAO,MAAM;AAC7C,UAAM,KAAK,wBAAwB;AACnC,eAAW,UAAU,SAAS;AAC1B,YAAM,OAAO,uBAAuB,OAAO,MAAM;AACjD,YAAM,WAAW,2BAA2B,OAAO,OAAO;AAC1D,YAAM;AAAA,QACF,mBAAmB,OAAO,IAAK,aAAa,IAAI,eAAe,QAAQ;AAAA,MAC3E;AAAA,IACJ;AACA,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,YAAY;AAAA,EAC3B;AAEA,QAAM,KAAK,OAAO;AAClB,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AAC1B;AAEA,IAAI,QAAoB;AACpB,QAAM,EAAE,MAAM,QAAQ,SAAS,IAAI;AAEnC,WAAS,mBAAmB,MAAM;AAC9B,UAAM,QAA8B;AAAA,MAChC,CAAC,EAAE,MAAM,KAAK,MAAM,QAAQ,GAAG,QAAQ;AAAA,MACvC,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACxC,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACxC,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACxC,CAAC,EAAE,MAAM,KAAK,MAAM,UAAU,GAAG,QAAQ;AAAA,MACzC,CAAC,EAAE,MAAM,KAAK,MAAM,UAAU,GAAG,QAAQ;AAAA,MACzC,CAAC,EAAE,MAAM,KAAK,MAAM,OAAO,GAAG,QAAQ;AAAA,MACtC,CAAC,EAAE,MAAM,KAAK,MAAM,QAAQ,GAAG,QAAQ;AAAA,MACvC,CAAC,EAAE,MAAM,KAAK,MAAM,QAAQ,GAAG,QAAQ;AAAA,MACvC,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACxC,CAAC,EAAE,MAAM,KAAK,MAAM,UAAU,GAAG,WAAW;AAAA,MAC5C,CAAC,EAAE,MAAM,KAAK,MAAM,OAAO,GAAG,SAAS;AAAA,MACvC,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACxC,CAAC,EAAE,MAAM,KAAK,MAAM,QAAQ,GAAG,QAAQ;AAAA,MACvC,CAAC,EAAE,MAAM,KAAK,MAAM,UAAU,GAAG,qBAAqB;AAAA,MACtD,CAAC,EAAE,MAAM,KAAK,MAAM,SAAS,GAAG,oBAAoB;AAAA,MACpD,CAAC,EAAE,MAAM,KAAK,MAAM,YAAY,GAAG,UAAU;AAAA,MAC7C,CAAC,EAAE,MAAM,KAAK,MAAM,YAAY,GAAG,aAAa;AAAA,MAChD,CAAC,EAAE,MAAM,KAAK,MAAM,aAAa,GAAG,UAAU;AAAA,MAC9C,CAAC,EAAE,MAAM,KAAK,MAAM,iBAAiB,GAAG,SAAS;AAAA,IACrD;AAEA,eAAW,CAAC,OAAO,QAAQ,KAAK,OAAO;AACnC,WAAK,GAAG,MAAM,IAAI,WAAM,QAAQ,IAAI,MAAM;AACtC,eAAO,gBAAgB,KAAK,CAAC,EAAE,KAAK,QAAQ;AAAA,MAChD,CAAC;AAAA,IACL;AAEA,SAAK,yBAAyB,MAAM;AAChC,YAAM,QAAkB;AAAA,QACpB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACR,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,UAChC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,QACtC;AAAA,MACJ;AACA,aAAO,gBAAgB,KAAK,CAAC,EAAE,KAAK,qCAAqC;AAAA,IAC7E,CAAC;AAED,SAAK,0BAA0B,MAAM;AACjC,YAAM,QAAkB;AAAA,QACpB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACR,EAAE,MAAM,MAAM,MAAM,SAAS;AAAA,UAC7B,EAAE,MAAM,QAAQ,MAAM,SAAS;AAAA,QACnC;AAAA,MACJ;AACA,aAAO,gBAAgB,KAAK,CAAC,EAAE,KAAK,gCAAgC;AAAA,IACxE,CAAC;AAAA,EACL,CAAC;AAED,WAAS,0BAA0B,MAAM;AACrC,SAAK,gBAAgB,MAAM;AACvB,aAAO,uBAAuB,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAAA,IAChD,CAAC;AAED,SAAK,gBAAgB,MAAM;AACvB,aAAO,uBAAuB,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE;AAAA,QAC9D;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,SAAK,mBAAmB,MAAM;AAC1B,YAAM,SAAS,uBAAuB;AAAA,QAClC,EAAE,MAAM,MAAM,MAAM,UAAU;AAAA,QAC9B,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MACtC,CAAC;AACD,aAAO,MAAM,EAAE,KAAK,iCAAiC;AAAA,IACzD,CAAC;AAAA,EACL,CAAC;AAED,WAAS,8BAA8B,MAAM;AACzC,SAAK,cAAc,MAAM;AACrB,aAAO,2BAA2B,MAAS,CAAC,EAAE,KAAK,WAAW;AAC9D,aAAO,2BAA2B,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW;AAAA,IAC3D,CAAC;AAED,SAAK,iBAAiB,MAAM;AACxB,aAAO,2BAA2B,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ;AAAA,IACpF,CAAC;AAED,SAAK,oBAAoB,MAAM;AAC3B,YAAM,SAAS,2BAA2B;AAAA,QACtC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,QACnC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MACpC,CAAC;AACD,aAAO,MAAM,EAAE,KAAK,oCAAoC;AAAA,IAC5D,CAAC;AAED,SAAK,wCAAwC,MAAM;AAC/C,YAAM,SAAS,2BAA2B;AAAA,QACtC,EAAE,MAAM,IAAI,MAAM,OAAO;AAAA,QACzB,EAAE,MAAM,IAAI,MAAM,UAAU;AAAA,MAChC,CAAC;AACD,aAAO,MAAM,EAAE,KAAK,6BAA6B;AAAA,IACrD,CAAC;AAAA,EACL,CAAC;AAED,WAAS,yBAAyB,MAAM;AACpC,SAAK,uCAAuC,MAAM;AAC9C,YAAM,SAAS,sBAAsB;AAAA,QACjC;AAAA,UACI,SAAS;AAAA,UACT,KAAK;AAAA,YACD;AAAA,cACI,MAAM;AAAA,cACN,QAAQ,CAAC;AAAA,cACT,iBAAiB;AAAA,YACrB;AAAA,YACA;AAAA,cACI,MAAM;AAAA,cACN,MAAM;AAAA,cACN,QAAQ,CAAC;AAAA,cACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,cACtC,iBAAiB;AAAA,YACrB;AAAA,YACA;AAAA,cACI,MAAM;AAAA,cACN,MAAM;AAAA,cACN,QAAQ,CAAC;AAAA,cACT,SAAS,CAAC;AAAA,cACV,iBAAiB;AAAA,YACrB;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,aAAO,MAAM,EAAE,UAAU,gDAAgD;AACzE,aAAO,MAAM,EAAE,UAAU,qBAAqB;AAC9C,aAAO,MAAM,EAAE,UAAU,oBAAoB;AAC7C,aAAO,MAAM,EAAE,UAAU,2CAA2C;AACpE,aAAO,MAAM,EAAE,UAAU,+CAA+C;AAExE,aAAO,MAAM,EAAE,IAAI,UAAU,aAAa;AAAA,IAC9C,CAAC;AAED,SAAK,8BAA8B,MAAM;AACrC,YAAM,SAAS,sBAAsB;AAAA,QACjC;AAAA,UACI,SAAS;AAAA,UACT,KAAK;AAAA,YACD;AAAA,cACI,MAAM;AAAA,cACN,MAAM;AAAA,cACN,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,UAAU,CAAC;AAAA,cACvC,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,YACxC;AAAA,UACJ;AAAA,QACJ;AAAA,QACA;AAAA,UACI,SAAS;AAAA,UACT,KAAK;AAAA,YACD;AAAA,cACI,MAAM;AAAA,cACN,MAAM;AAAA,cACN,QAAQ,CAAC;AAAA,cACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,YAC3C;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,aAAO,MAAM,EAAE,UAAU,UAAU;AACnC,aAAO,MAAM,EAAE,UAAU,UAAU;AACnC,aAAO,MAAM,EAAE,UAAU,gDAAgD;AACzE,aAAO,MAAM,EAAE,UAAU,yCAAyC;AAAA,IACtE,CAAC;AAED,SAAK,wBAAwB,MAAM;AAC/B,YAAM,SAAS,sBAAsB,CAAC,CAAC;AACvC,aAAO,MAAM,EAAE,UAAU,uBAAuB;AAChD,aAAO,MAAM,EAAE,UAAU,GAAG;AAAA,IAChC,CAAC;AAED,SAAK,sCAAsC,MAAM;AAC7C,YAAM,SAAS,sBAAsB,CAAC,CAAC;AACvC,aAAO,MAAM,EAAE,UAAU,oDAAoD;AAC7E,aAAO,MAAM,EAAE,UAAU,qBAAqB;AAAA,IAClD,CAAC;AAAA,EACL,CAAC;AACL;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/codegen.ts"],"names":[],"mappings":";AAGA,SAAS,gBAAgB,KAAA,EAAyB;AAC9C,EAAA,MAAM,IAAI,KAAA,CAAM,IAAA;AAGhB,EAAA,IAAI,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,EAAG;AAClB,IAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,KAAA,EAAO,MAAM,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAE;AAC/C,IAAA,OAAO,CAAA,EAAG,eAAA,CAAgB,KAAK,CAAC,CAAA,EAAA,CAAA;AAAA,EACpC;AAGA,EAAA,MAAM,eAAA,GAAkB,CAAA,CAAE,KAAA,CAAM,iBAAiB,CAAA;AACjD,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,MAAM,QAAQ,EAAE,GAAG,OAAO,IAAA,EAAM,eAAA,CAAgB,CAAC,CAAA,EAAE;AACnD,IAAA,OAAO,CAAA,EAAG,eAAA,CAAgB,KAAK,CAAC,CAAA,EAAA,CAAA;AAAA,EACpC;AAGA,EAAA,IAAI,CAAA,KAAM,OAAA,IAAW,KAAA,CAAM,UAAA,EAAY;AACnC,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,eAAA,CAAgB,CAAC,CAAC,CAAA,CAAE,CAAA;AAC7E,IAAA,OAAO,CAAA,EAAA,EAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AAAA,EACjC;AAGA,EAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,QAAA;AACtC,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,QAAA;AAGhC,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,QAAA;AACrC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,QAAA;AAG/B,EAAA,IAAI,CAAA,KAAM,WAAW,OAAO,WAAA;AAG5B,EAAA,IAAI,CAAA,KAAM,SAAS,OAAO,QAAA;AAC1B,EAAA,MAAM,UAAA,GAAa,CAAA,CAAE,KAAA,CAAM,cAAc,CAAA;AACzC,EAAA,IAAI,UAAA,EAAY,OAAO,CAAA,gBAAA,EAAmB,UAAA,CAAW,CAAC,CAAC,CAAA,CAAA,CAAA;AAGvD,EAAA,IAAI,CAAA,KAAM,QAAQ,OAAO,SAAA;AACzB,EAAA,IAAI,CAAA,KAAM,UAAU,OAAO,QAAA;AAE3B,EAAA,OAAO,SAAA;AACX;AAEA,SAAS,uBAAuB,MAAA,EAA4B;AACxD,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,eAAA,CAAgB,CAAC,CAAC,CAAA,CAAE,CAAA;AAClE,EAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAC/B;AAEA,SAAS,2BAA2B,OAAA,EAAyC;AACzE,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,GAAG,OAAO,WAAA;AAC7C,EAAA,IAAI,QAAQ,MAAA,KAAW,CAAA,SAAU,eAAA,CAAgB,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC3D,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACjC,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAC5B,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,eAAA,CAAgB,CAAC,CAAC,CAAA,CAAA;AAAA,EACzC,CAAC,CAAA;AACD,EAAA,OAAO,CAAA,EAAA,EAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AACjC;AAmBO,SAAS,sBAAsB,SAAA,EAA2D;AAC7F,EAAA,MAAM,KAAA,GAAkB;AAAA,IACpB,qDAAA;AAAA,IACA,yEAAA;AAAA,IACA,EAAA;AAAA,IACA,kDAAA;AAAA,IACA;AAAA,GACJ;AAEA,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAC9B,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,CAAA,CAAE,IAAI,CAAA;AAC1E,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,QAAA,CAAS,OAAO,CAAA,IAAA,CAAM,CAAA;AAC7C,IAAA,KAAA,CAAM,KAAK,wBAAwB,CAAA;AACnC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC1B,MAAA,MAAM,IAAA,GAAO,sBAAA,CAAuB,MAAA,CAAO,MAAM,CAAA;AACjD,MAAA,MAAM,QAAA,GAAW,0BAAA,CAA2B,MAAA,CAAO,OAAO,CAAA;AAC1D,MAAA,KAAA,CAAM,IAAA;AAAA,QACF,mBAAmB,MAAA,CAAO,IAAK,CAAA,UAAA,EAAa,IAAI,eAAe,QAAQ,CAAA,GAAA;AAAA,OAC3E;AAAA,IACJ;AACA,IAAA,KAAA,CAAM,KAAK,gBAAgB,CAAA;AAC3B,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,EAC3B;AAEA,EAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,EAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B","file":"chunk-E7AP65D4.js","sourcesContent":["import type { AbiEntry, AbiParam } from \"./types.js\";\n\n/** Map a Solidity ABI type to its TypeScript equivalent. */\nfunction mapSolidityType(param: AbiParam): string {\n const t = param.type;\n\n // Dynamic arrays — e.g. uint256[]\n if (t.endsWith(\"[]\")) {\n const inner = { ...param, type: t.slice(0, -2) };\n return `${mapSolidityType(inner)}[]`;\n }\n\n // Fixed-size arrays — e.g. uint256[3]\n const fixedArrayMatch = t.match(/^(.+)\\[(\\d+)\\]$/);\n if (fixedArrayMatch) {\n const inner = { ...param, type: fixedArrayMatch[1] };\n return `${mapSolidityType(inner)}[]`;\n }\n\n // Tuple\n if (t === \"tuple\" && param.components) {\n const fields = param.components.map((c) => `${c.name}: ${mapSolidityType(c)}`);\n return `{ ${fields.join(\"; \")} }`;\n }\n\n // Unsigned integers — uint8/16/32 fit in JS number\n if (/^uint(8|16|32)$/.test(t)) return \"number\";\n if (/^uint\\d*$/.test(t)) return \"bigint\";\n\n // Signed integers\n if (/^int(8|16|32)$/.test(t)) return \"number\";\n if (/^int\\d*$/.test(t)) return \"bigint\";\n\n // Address\n if (t === \"address\") return \"HexString\";\n\n // Bytes\n if (t === \"bytes\") return \"Binary\";\n const bytesMatch = t.match(/^bytes(\\d+)$/);\n if (bytesMatch) return `FixedSizeBinary<${bytesMatch[1]}>`;\n\n // Primitives\n if (t === \"bool\") return \"boolean\";\n if (t === \"string\") return \"string\";\n\n return \"unknown\";\n}\n\nfunction generateMethodArgsType(inputs: AbiParam[]): string {\n if (inputs.length === 0) return \"[]\";\n const parts = inputs.map((p) => `${p.name}: ${mapSolidityType(p)}`);\n return `[${parts.join(\", \")}]`;\n}\n\nfunction generateMethodResponseType(outputs: AbiParam[] | undefined): string {\n if (!outputs || outputs.length === 0) return \"undefined\";\n if (outputs.length === 1) return mapSolidityType(outputs[0]);\n const fields = outputs.map((o, i) => {\n const name = o.name || `_${i}`;\n return `${name}: ${mapSolidityType(o)}`;\n });\n return `{ ${fields.join(\"; \")} }`;\n}\n\n/**\n * Generate a TypeScript module augmentation that extends the\n * {@link Contracts} interface with typed method signatures for each\n * installed contract.\n *\n * The output is written to `.cdm/contracts.d.ts` (or equivalent) and\n * augments `\"@parity/product-sdk-contracts\"` so that\n * `ContractManager.getContract()` returns fully-typed handles.\n *\n * @example\n * ```ts\n * const src = generateContractTypes([\n * { library: \"@example/counter\", abi },\n * ]);\n * writeFileSync(\".cdm/contracts.d.ts\", src);\n * ```\n */\nexport function generateContractTypes(contracts: { library: string; abi: AbiEntry[] }[]): string {\n const lines: string[] = [\n \"// Auto-generated by cdm install — do not edit\",\n 'import type { HexString, Binary, FixedSizeBinary } from \"polkadot-api\";',\n \"\",\n 'declare module \"@parity/product-sdk-contracts\" {',\n \" interface Contracts {\",\n ];\n\n for (const contract of contracts) {\n const methods = contract.abi.filter((e) => e.type === \"function\" && e.name);\n lines.push(` \"${contract.library}\": {`);\n lines.push(\" methods: {\");\n for (const method of methods) {\n const args = generateMethodArgsType(method.inputs);\n const response = generateMethodResponseType(method.outputs);\n lines.push(\n ` ${method.name!}: { args: ${args}; response: ${response} };`,\n );\n }\n lines.push(\" };\");\n lines.push(\" };\");\n }\n\n lines.push(\" }\");\n lines.push(\"}\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"mapSolidityType\", () => {\n const cases: [AbiParam, string][] = [\n [{ name: \"x\", type: \"uint8\" }, \"number\"],\n [{ name: \"x\", type: \"uint16\" }, \"number\"],\n [{ name: \"x\", type: \"uint32\" }, \"number\"],\n [{ name: \"x\", type: \"uint64\" }, \"bigint\"],\n [{ name: \"x\", type: \"uint128\" }, \"bigint\"],\n [{ name: \"x\", type: \"uint256\" }, \"bigint\"],\n [{ name: \"x\", type: \"int8\" }, \"number\"],\n [{ name: \"x\", type: \"int32\" }, \"number\"],\n [{ name: \"x\", type: \"int64\" }, \"bigint\"],\n [{ name: \"x\", type: \"int256\" }, \"bigint\"],\n [{ name: \"x\", type: \"address\" }, \"HexString\"],\n [{ name: \"x\", type: \"bool\" }, \"boolean\"],\n [{ name: \"x\", type: \"string\" }, \"string\"],\n [{ name: \"x\", type: \"bytes\" }, \"Binary\"],\n [{ name: \"x\", type: \"bytes32\" }, \"FixedSizeBinary<32>\"],\n [{ name: \"x\", type: \"bytes4\" }, \"FixedSizeBinary<4>\"],\n [{ name: \"x\", type: \"uint256[]\" }, \"bigint[]\"],\n [{ name: \"x\", type: \"address[]\" }, \"HexString[]\"],\n [{ name: \"x\", type: \"uint256[3]\" }, \"bigint[]\"],\n [{ name: \"x\", type: \"somethingWeird\" }, \"unknown\"],\n ];\n\n for (const [param, expected] of cases) {\n test(`${param.type} → ${expected}`, () => {\n expect(mapSolidityType(param)).toBe(expected);\n });\n }\n\n test(\"tuple with components\", () => {\n const param: AbiParam = {\n name: \"info\",\n type: \"tuple\",\n components: [\n { name: \"addr\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n };\n expect(mapSolidityType(param)).toBe(\"{ addr: HexString; amount: bigint }\");\n });\n\n test(\"nested array of tuples\", () => {\n const param: AbiParam = {\n name: \"items\",\n type: \"tuple[]\",\n components: [\n { name: \"id\", type: \"uint32\" },\n { name: \"name\", type: \"string\" },\n ],\n };\n expect(mapSolidityType(param)).toBe(\"{ id: number; name: string }[]\");\n });\n });\n\n describe(\"generateMethodArgsType\", () => {\n test(\"empty inputs\", () => {\n expect(generateMethodArgsType([])).toBe(\"[]\");\n });\n\n test(\"single input\", () => {\n expect(generateMethodArgsType([{ name: \"to\", type: \"address\" }])).toBe(\n \"[to: HexString]\",\n );\n });\n\n test(\"multiple inputs\", () => {\n const result = generateMethodArgsType([\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ]);\n expect(result).toBe(\"[to: HexString, amount: bigint]\");\n });\n });\n\n describe(\"generateMethodResponseType\", () => {\n test(\"no outputs\", () => {\n expect(generateMethodResponseType(undefined)).toBe(\"undefined\");\n expect(generateMethodResponseType([])).toBe(\"undefined\");\n });\n\n test(\"single output\", () => {\n expect(generateMethodResponseType([{ name: \"\", type: \"uint32\" }])).toBe(\"number\");\n });\n\n test(\"multiple outputs\", () => {\n const result = generateMethodResponseType([\n { name: \"balance\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint32\" },\n ]);\n expect(result).toBe(\"{ balance: bigint; nonce: number }\");\n });\n\n test(\"unnamed outputs get positional names\", () => {\n const result = generateMethodResponseType([\n { name: \"\", type: \"bool\" },\n { name: \"\", type: \"uint256\" },\n ]);\n expect(result).toBe(\"{ _0: boolean; _1: bigint }\");\n });\n });\n\n describe(\"generateContractTypes\", () => {\n test(\"generates valid module augmentation\", () => {\n const result = generateContractTypes([\n {\n library: \"@example/counter\",\n abi: [\n {\n type: \"constructor\",\n inputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"getCount\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"increment\",\n inputs: [],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n ],\n },\n ]);\n\n expect(result).toContain('declare module \"@parity/product-sdk-contracts\"');\n expect(result).toContain(\"interface Contracts\");\n expect(result).toContain('\"@example/counter\"');\n expect(result).toContain(\"getCount: { args: []; response: number };\");\n expect(result).toContain(\"increment: { args: []; response: undefined };\");\n // Should not include constructor\n expect(result).not.toContain(\"constructor\");\n });\n\n test(\"handles multiple contracts\", () => {\n const result = generateContractTypes([\n {\n library: \"@a/one\",\n abi: [\n {\n type: \"function\",\n name: \"foo\",\n inputs: [{ name: \"x\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n ],\n },\n {\n library: \"@b/two\",\n abi: [\n {\n type: \"function\",\n name: \"bar\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n ],\n },\n ]);\n\n expect(result).toContain('\"@a/one\"');\n expect(result).toContain('\"@b/two\"');\n expect(result).toContain(\"foo: { args: [x: bigint]; response: boolean };\");\n expect(result).toContain(\"bar: { args: []; response: HexString };\");\n });\n\n test(\"empty contracts list\", () => {\n const result = generateContractTypes([]);\n expect(result).toContain(\"interface Contracts {\");\n expect(result).toContain(\"}\");\n });\n\n test(\"includes polkadot-api type imports\", () => {\n const result = generateContractTypes([]);\n expect(result).toContain(\"import type { HexString, Binary, FixedSizeBinary }\");\n expect(result).toContain('from \"polkadot-api\"');\n });\n });\n}\n"]}
|
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
import { HexString, SS58String, PolkadotSigner } from 'polkadot-api';
|
|
2
|
-
import { SubmitOptions, Weight, TxResult } from '@parity/product-sdk-tx';
|
|
2
|
+
import { SubmitOptions, Weight, TxResult, BatchableCall } from '@parity/product-sdk-tx';
|
|
3
3
|
import { SignerManager } from '@parity/product-sdk-signer';
|
|
4
4
|
|
|
5
|
+
/** Pins a target to specific asset-hub and Bulletin chain hashes in `cdm.json`. */
|
|
5
6
|
interface CdmJsonTarget {
|
|
6
7
|
"asset-hub": string;
|
|
7
8
|
bulletin: string;
|
|
8
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* A deployed contract's on-chain address, ABI, and optional metadata CID.
|
|
12
|
+
*
|
|
13
|
+
* `metadataCid` is optional because real-world cdm.json files (e.g.
|
|
14
|
+
* `paritytech/playground-cli/cdm.json`) don't always include it — only
|
|
15
|
+
* `version`, `address`, and `abi` are load-bearing for `getContract()`.
|
|
16
|
+
*/
|
|
9
17
|
interface CdmJsonContract {
|
|
10
18
|
version: number;
|
|
11
19
|
address: HexString;
|
|
12
20
|
abi: AbiEntry[];
|
|
13
|
-
metadataCid
|
|
21
|
+
metadataCid?: string;
|
|
14
22
|
}
|
|
23
|
+
/** A project's `cdm.json` manifest: declared targets, runtime dependencies, and per-target contract deployments. */
|
|
15
24
|
interface CdmJson {
|
|
16
25
|
targets: Record<string, CdmJsonTarget>;
|
|
17
26
|
dependencies: Record<string, Record<string, number | string>>;
|
|
18
27
|
contracts?: Record<string, Record<string, CdmJsonContract>>;
|
|
19
28
|
}
|
|
29
|
+
/** An ABI parameter or return value, with support for nested tuple and struct types. */
|
|
20
30
|
interface AbiParam {
|
|
21
31
|
name: string;
|
|
22
32
|
type: string;
|
|
23
33
|
components?: AbiParam[];
|
|
24
34
|
}
|
|
35
|
+
/** One function, constructor, or event in a contract's ABI. */
|
|
25
36
|
interface AbiEntry {
|
|
26
37
|
type: string;
|
|
27
38
|
name?: string;
|
|
@@ -64,6 +75,19 @@ interface TxOptions extends SubmitOptions {
|
|
|
64
75
|
gasLimit?: Weight;
|
|
65
76
|
storageDepositLimit?: bigint;
|
|
66
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Options for `.prepare()` — subset of {@link TxOptions}.
|
|
80
|
+
*
|
|
81
|
+
* Signer and submission lifecycle options (`signer`, `waitFor`, `timeoutMs`,
|
|
82
|
+
* `mortalityPeriod`, `onStatus`) are intentionally absent — those belong to
|
|
83
|
+
* the batch submission, not the individual prepared call.
|
|
84
|
+
*/
|
|
85
|
+
interface PrepareOptions {
|
|
86
|
+
origin?: SS58String;
|
|
87
|
+
value?: bigint;
|
|
88
|
+
gasLimit?: Weight;
|
|
89
|
+
storageDepositLimit?: bigint;
|
|
90
|
+
}
|
|
67
91
|
/** Mutable defaults shared across all contract handles from a manager. */
|
|
68
92
|
interface ContractDefaults {
|
|
69
93
|
origin?: SS58String;
|
|
@@ -120,6 +144,29 @@ type Contract<C extends ContractDef> = {
|
|
|
120
144
|
* defaultSigner. Throws {@link ContractSignerMissingError} if none available.
|
|
121
145
|
*/
|
|
122
146
|
tx: (...args: [...C["methods"][K]["args"], opts?: TxOptions]) => Promise<TxResult>;
|
|
147
|
+
/**
|
|
148
|
+
* Prepare the method as a {@link BatchableCall} — returns a handle
|
|
149
|
+
* consumable by `batchSubmitAndWatch` from `@parity/product-sdk-tx`
|
|
150
|
+
* without signing or submitting.
|
|
151
|
+
*
|
|
152
|
+
* Use this to group multiple contract calls (or contract calls mixed
|
|
153
|
+
* with other transactions on the same chain) into a single atomic
|
|
154
|
+
* `Utility.batch_all` transaction:
|
|
155
|
+
*
|
|
156
|
+
* ```ts
|
|
157
|
+
* import { batchSubmitAndWatch } from "@parity/product-sdk-tx";
|
|
158
|
+
*
|
|
159
|
+
* const a = contract.transfer.prepare(addr1, 100n);
|
|
160
|
+
* const b = contract.transfer.prepare(addr2, 200n);
|
|
161
|
+
* await batchSubmitAndWatch([a, b], api, signer);
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* Origin is resolved the same way as `.tx()` but falls back to the
|
|
165
|
+
* dev address for dry-run gas estimation if no signer context is
|
|
166
|
+
* available (prepare does not require a signer; the batch submission
|
|
167
|
+
* does).
|
|
168
|
+
*/
|
|
169
|
+
prepare: (...args: [...C["methods"][K]["args"], opts?: PrepareOptions]) => BatchableCall;
|
|
123
170
|
};
|
|
124
171
|
};
|
|
125
172
|
|
|
@@ -145,4 +192,4 @@ declare function generateContractTypes(contracts: {
|
|
|
145
192
|
abi: AbiEntry[];
|
|
146
193
|
}[]): string;
|
|
147
194
|
|
|
148
|
-
export { type AbiEntry as A, type CdmJson as C, type QueryOptions as Q, type TxOptions as T, type ContractManagerOptions as a, type ContractDefaults as b, type Contracts as c, type Contract as d, type ContractDef as e, type ContractOptions as f, type AbiParam as g, type CdmJsonContract as h, type CdmJsonTarget as i, type QueryResult as j, generateContractTypes as k };
|
|
195
|
+
export { type AbiEntry as A, type CdmJson as C, type PrepareOptions as P, type QueryOptions as Q, type TxOptions as T, type ContractManagerOptions as a, type ContractDefaults as b, type Contracts as c, type Contract as d, type ContractDef as e, type ContractOptions as f, type AbiParam as g, type CdmJsonContract as h, type CdmJsonTarget as i, type QueryResult as j, generateContractTypes as k };
|
package/dist/codegen.d.ts
CHANGED
package/dist/codegen.js
CHANGED
package/dist/codegen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"codegen.js"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PolkadotClient, HexString } from 'polkadot-api';
|
|
2
2
|
import { InkSdk } from '@polkadot-api/sdk-ink';
|
|
3
|
-
import { C as CdmJson, a as ContractManagerOptions, b as ContractDefaults, c as Contracts, d as Contract, e as ContractDef, A as AbiEntry, f as ContractOptions } from './codegen-
|
|
4
|
-
export { g as AbiParam, h as CdmJsonContract, i as CdmJsonTarget, Q as QueryOptions, j as QueryResult, T as TxOptions, k as generateContractTypes } from './codegen-
|
|
5
|
-
export { TxResult } from '@parity/product-sdk-tx';
|
|
3
|
+
import { C as CdmJson, a as ContractManagerOptions, b as ContractDefaults, c as Contracts, d as Contract, e as ContractDef, A as AbiEntry, f as ContractOptions } from './codegen-BPDBGrJC.js';
|
|
4
|
+
export { g as AbiParam, h as CdmJsonContract, i as CdmJsonTarget, P as PrepareOptions, Q as QueryOptions, j as QueryResult, T as TxOptions, k as generateContractTypes } from './codegen-BPDBGrJC.js';
|
|
5
|
+
export { BatchableCall, TxResult } from '@parity/product-sdk-tx';
|
|
6
6
|
import '@parity/product-sdk-signer';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
} from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { submitAndWatch } from "@parity/product-sdk-tx";
|
|
7
|
-
import { seedToAccount } from "@parity/product-sdk-keys";
|
|
8
|
-
import { createLogger } from "@parity/product-sdk-logger";
|
|
9
|
-
import { DEV_PHRASE, ss58Address } from "@polkadot-labs/hdkd-helpers";
|
|
1
|
+
export { generateContractTypes } from './chunk-E7AP65D4.js';
|
|
2
|
+
import { submitAndWatch } from '@parity/product-sdk-tx';
|
|
3
|
+
import { seedToAccount } from '@parity/product-sdk-keys';
|
|
4
|
+
import { createLogger } from '@parity/product-sdk-logger';
|
|
5
|
+
import { DEV_PHRASE, ss58Address } from '@polkadot-labs/hdkd-helpers';
|
|
10
6
|
|
|
11
7
|
// src/errors.ts
|
|
12
8
|
var ContractError = class extends Error {
|
|
@@ -33,37 +29,6 @@ var ContractNotFoundError = class extends ContractError {
|
|
|
33
29
|
this.targetHash = targetHash;
|
|
34
30
|
}
|
|
35
31
|
};
|
|
36
|
-
if (void 0) {
|
|
37
|
-
const { test, expect, describe } = void 0;
|
|
38
|
-
describe("ContractError", () => {
|
|
39
|
-
test("base error has correct name", () => {
|
|
40
|
-
const err = new ContractError("test");
|
|
41
|
-
expect(err.name).toBe("ContractError");
|
|
42
|
-
expect(err).toBeInstanceOf(Error);
|
|
43
|
-
});
|
|
44
|
-
test("instanceof catches all contract errors", () => {
|
|
45
|
-
expect(new ContractSignerMissingError()).toBeInstanceOf(ContractError);
|
|
46
|
-
expect(new ContractNotFoundError("@a/b", "abc")).toBeInstanceOf(ContractError);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
describe("ContractSignerMissingError", () => {
|
|
50
|
-
test("message mentions signer options", () => {
|
|
51
|
-
const err = new ContractSignerMissingError();
|
|
52
|
-
expect(err.message).toContain("signer");
|
|
53
|
-
expect(err.message).toContain("signerManager");
|
|
54
|
-
expect(err.name).toBe("ContractSignerMissingError");
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
describe("ContractNotFoundError", () => {
|
|
58
|
-
test("includes library and target", () => {
|
|
59
|
-
const err = new ContractNotFoundError("@test/foo", "abc123");
|
|
60
|
-
expect(err.library).toBe("@test/foo");
|
|
61
|
-
expect(err.targetHash).toBe("abc123");
|
|
62
|
-
expect(err.message).toContain("@test/foo");
|
|
63
|
-
expect(err.message).toContain("abc123");
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
32
|
|
|
68
33
|
// src/wrap.ts
|
|
69
34
|
var log = createLogger("contracts");
|
|
@@ -159,151 +124,28 @@ function wrapContract(inkContract, abi, defaults) {
|
|
|
159
124
|
mortalityPeriod: overrides?.mortalityPeriod,
|
|
160
125
|
onStatus: overrides?.onStatus
|
|
161
126
|
});
|
|
127
|
+
},
|
|
128
|
+
prepare: (...args) => {
|
|
129
|
+
const { positionalArgs, overrides } = extractOverrides(
|
|
130
|
+
argNames,
|
|
131
|
+
args
|
|
132
|
+
);
|
|
133
|
+
const data = positionalToNamed(argNames, positionalArgs);
|
|
134
|
+
const origin = resolveOrigin(defaults, overrides?.origin, true);
|
|
135
|
+
return inkContract.send(methodName, {
|
|
136
|
+
data,
|
|
137
|
+
origin,
|
|
138
|
+
...overrides?.value !== void 0 && { value: overrides.value },
|
|
139
|
+
...overrides?.gasLimit && { gasLimit: overrides.gasLimit },
|
|
140
|
+
...overrides?.storageDepositLimit !== void 0 && {
|
|
141
|
+
storageDepositLimit: overrides.storageDepositLimit
|
|
142
|
+
}
|
|
143
|
+
});
|
|
162
144
|
}
|
|
163
145
|
};
|
|
164
146
|
}
|
|
165
147
|
});
|
|
166
148
|
}
|
|
167
|
-
if (void 0) {
|
|
168
|
-
let mockSigner = function(opts) {
|
|
169
|
-
return {
|
|
170
|
-
getSigner: () => opts.signer ?? null,
|
|
171
|
-
getState: () => ({
|
|
172
|
-
selectedAccount: opts.address ? { address: opts.address } : null
|
|
173
|
-
})
|
|
174
|
-
};
|
|
175
|
-
};
|
|
176
|
-
mockSigner2 = mockSigner;
|
|
177
|
-
const { test, expect, describe } = void 0;
|
|
178
|
-
describe("buildMethodArgMap", () => {
|
|
179
|
-
test("extracts function parameter names from ABI", () => {
|
|
180
|
-
const abi = [
|
|
181
|
-
{ type: "constructor", inputs: [], stateMutability: "nonpayable" },
|
|
182
|
-
{
|
|
183
|
-
type: "function",
|
|
184
|
-
name: "transfer",
|
|
185
|
-
inputs: [
|
|
186
|
-
{ name: "to", type: "address" },
|
|
187
|
-
{ name: "amount", type: "uint256" }
|
|
188
|
-
],
|
|
189
|
-
outputs: [{ name: "", type: "bool" }]
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
type: "function",
|
|
193
|
-
name: "balanceOf",
|
|
194
|
-
inputs: [{ name: "owner", type: "address" }],
|
|
195
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
196
|
-
},
|
|
197
|
-
{ type: "event", name: "Transfer", inputs: [] }
|
|
198
|
-
];
|
|
199
|
-
const map = buildMethodArgMap(abi);
|
|
200
|
-
expect(map).toEqual({
|
|
201
|
-
transfer: ["to", "amount"],
|
|
202
|
-
balanceOf: ["owner"]
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
test("returns empty map for ABI with no functions", () => {
|
|
206
|
-
const abi = [
|
|
207
|
-
{ type: "constructor", inputs: [] },
|
|
208
|
-
{ type: "event", name: "Evt", inputs: [] }
|
|
209
|
-
];
|
|
210
|
-
expect(buildMethodArgMap(abi)).toEqual({});
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
describe("positionalToNamed", () => {
|
|
214
|
-
test("maps positional values to named keys", () => {
|
|
215
|
-
expect(positionalToNamed(["a", "b"], [1, 2])).toEqual({ a: 1, b: 2 });
|
|
216
|
-
});
|
|
217
|
-
test("handles empty args", () => {
|
|
218
|
-
expect(positionalToNamed([], [])).toEqual({});
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
describe("extractOverrides", () => {
|
|
222
|
-
test("returns overrides when extra object arg is present", () => {
|
|
223
|
-
const result = extractOverrides(["a"], [42, { origin: "0x1" }]);
|
|
224
|
-
expect(result.positionalArgs).toEqual([42]);
|
|
225
|
-
expect(result.overrides).toEqual({ origin: "0x1" });
|
|
226
|
-
});
|
|
227
|
-
test("returns no overrides when arg count matches", () => {
|
|
228
|
-
const result = extractOverrides(["a", "b"], [1, 2]);
|
|
229
|
-
expect(result.positionalArgs).toEqual([1, 2]);
|
|
230
|
-
expect(result.overrides).toBeUndefined();
|
|
231
|
-
});
|
|
232
|
-
test("does not treat array as overrides", () => {
|
|
233
|
-
const result = extractOverrides(["a"], [1, [2, 3]]);
|
|
234
|
-
expect(result.positionalArgs).toEqual([1, [2, 3]]);
|
|
235
|
-
expect(result.overrides).toBeUndefined();
|
|
236
|
-
});
|
|
237
|
-
test("does not treat primitive as overrides", () => {
|
|
238
|
-
const result = extractOverrides(["a"], [1, "extra"]);
|
|
239
|
-
expect(result.positionalArgs).toEqual([1, "extra"]);
|
|
240
|
-
expect(result.overrides).toBeUndefined();
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
describe("resolveOrigin", () => {
|
|
244
|
-
test("explicit override wins", () => {
|
|
245
|
-
const defaults = {
|
|
246
|
-
origin: "5Static",
|
|
247
|
-
signerManager: mockSigner({ address: "5Source" })
|
|
248
|
-
};
|
|
249
|
-
expect(resolveOrigin(defaults, "5Override")).toBe("5Override");
|
|
250
|
-
});
|
|
251
|
-
test("signerManager wins over static default", () => {
|
|
252
|
-
const defaults = {
|
|
253
|
-
origin: "5Static",
|
|
254
|
-
signerManager: mockSigner({ address: "5Source" })
|
|
255
|
-
};
|
|
256
|
-
expect(resolveOrigin(defaults)).toBe("5Source");
|
|
257
|
-
});
|
|
258
|
-
test("falls back to static default", () => {
|
|
259
|
-
const defaults = { origin: "5Static" };
|
|
260
|
-
expect(resolveOrigin(defaults)).toBe("5Static");
|
|
261
|
-
});
|
|
262
|
-
test("returns undefined when nothing available", () => {
|
|
263
|
-
expect(resolveOrigin({})).toBeUndefined();
|
|
264
|
-
});
|
|
265
|
-
test("skips signerManager when no account selected", () => {
|
|
266
|
-
const defaults = {
|
|
267
|
-
origin: "5Static",
|
|
268
|
-
signerManager: mockSigner({ address: null })
|
|
269
|
-
};
|
|
270
|
-
expect(resolveOrigin(defaults)).toBe("5Static");
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
describe("resolveSigner", () => {
|
|
274
|
-
const fakeSigner = { id: "fake" };
|
|
275
|
-
const sourceSigner = { id: "source" };
|
|
276
|
-
test("explicit override wins", () => {
|
|
277
|
-
const defaults = {
|
|
278
|
-
signer: { id: "static" },
|
|
279
|
-
signerManager: mockSigner({ signer: sourceSigner })
|
|
280
|
-
};
|
|
281
|
-
expect(resolveSigner(defaults, fakeSigner)).toBe(fakeSigner);
|
|
282
|
-
});
|
|
283
|
-
test("signerManager wins over static default", () => {
|
|
284
|
-
const defaults = {
|
|
285
|
-
signer: { id: "static" },
|
|
286
|
-
signerManager: mockSigner({ signer: sourceSigner })
|
|
287
|
-
};
|
|
288
|
-
expect(resolveSigner(defaults)).toBe(sourceSigner);
|
|
289
|
-
});
|
|
290
|
-
test("falls back to static default", () => {
|
|
291
|
-
const defaults = { signer: fakeSigner };
|
|
292
|
-
expect(resolveSigner(defaults)).toBe(fakeSigner);
|
|
293
|
-
});
|
|
294
|
-
test("returns undefined when nothing available", () => {
|
|
295
|
-
expect(resolveSigner({})).toBeUndefined();
|
|
296
|
-
});
|
|
297
|
-
test("skips signerManager when getSigner returns null", () => {
|
|
298
|
-
const defaults = {
|
|
299
|
-
signer: fakeSigner,
|
|
300
|
-
signerManager: mockSigner({})
|
|
301
|
-
};
|
|
302
|
-
expect(resolveSigner(defaults)).toBe(fakeSigner);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
var mockSigner2;
|
|
307
149
|
|
|
308
150
|
// src/manager.ts
|
|
309
151
|
var ContractManager = class _ContractManager {
|
|
@@ -364,7 +206,7 @@ var ContractManager = class _ContractManager {
|
|
|
364
206
|
* ```
|
|
365
207
|
*/
|
|
366
208
|
static async fromClient(cdmJson, client, options) {
|
|
367
|
-
const { createInkSdk } = await import(
|
|
209
|
+
const { createInkSdk } = await import('@polkadot-api/sdk-ink');
|
|
368
210
|
const inkSdk = createInkSdk(client, { atBest: true });
|
|
369
211
|
return new _ContractManager(cdmJson, inkSdk, options);
|
|
370
212
|
}
|
|
@@ -396,17 +238,11 @@ function createContract(inkSdk, address, abi, options) {
|
|
|
396
238
|
return wrapContract(inkContract, abi, defaults);
|
|
397
239
|
}
|
|
398
240
|
async function createContractFromClient(client, address, abi, options) {
|
|
399
|
-
const { createInkSdk } = await import(
|
|
241
|
+
const { createInkSdk } = await import('@polkadot-api/sdk-ink');
|
|
400
242
|
const inkSdk = createInkSdk(client, { atBest: true });
|
|
401
243
|
return createContract(inkSdk, address, abi, options);
|
|
402
244
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
ContractNotFoundError,
|
|
407
|
-
ContractSignerMissingError,
|
|
408
|
-
createContract,
|
|
409
|
-
createContractFromClient,
|
|
410
|
-
generateContractTypes
|
|
411
|
-
};
|
|
245
|
+
|
|
246
|
+
export { ContractError, ContractManager, ContractNotFoundError, ContractSignerMissingError, createContract, createContractFromClient };
|
|
247
|
+
//# sourceMappingURL=index.js.map
|
|
412
248
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wrap.ts","../src/errors.ts","../src/manager.ts"],"sourcesContent":["import type { PolkadotSigner, SS58String } from \"polkadot-api\";\nimport { submitAndWatch } from \"@parity/product-sdk-tx\";\nimport { seedToAccount } from \"@parity/product-sdk-keys\";\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { DEV_PHRASE, ss58Address } from \"@polkadot-labs/hdkd-helpers\";\nimport { ContractSignerMissingError } from \"./errors.js\";\nimport type {\n AbiEntry,\n Contract,\n ContractDef,\n ContractDefaults,\n QueryOptions,\n TxOptions,\n} from \"./types.js\";\n\nconst log = createLogger(\"contracts\");\n\n/**\n * Ink SDK contract instance returned by `inkSdk.getContract()`.\n *\n * Typed as `any` because we call `.query()` / `.send()` with runtime method\n * names — the SDK's `ContractSdk<D>` requires compile-time descriptor\n * knowledge that runtime ABIs can't provide.\n */\ntype InkContract = any;\n\n/** Extract method name → ordered parameter names from the ABI. */\nfunction buildMethodArgMap(abi: AbiEntry[]): Record<string, string[]> {\n const map: Record<string, string[]> = {};\n for (const entry of abi) {\n if (entry.type === \"function\" && entry.name) {\n map[entry.name] = entry.inputs.map((p) => p.name);\n }\n }\n return map;\n}\n\n/** Convert positional arguments to a named object matching the ABI parameter names. */\nfunction positionalToNamed(argNames: string[], values: unknown[]): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (let i = 0; i < argNames.length; i++) {\n data[argNames[i]] = values[i];\n }\n return data;\n}\n\n/**\n * If the caller passed more arguments than the ABI expects and the last\n * argument is a plain object, treat it as an options override.\n */\nfunction extractOverrides<T>(\n argNames: string[],\n args: unknown[],\n): { positionalArgs: unknown[]; overrides?: T } {\n if (args.length > argNames.length && args.length > 0) {\n const last = args[args.length - 1];\n if (last && typeof last === \"object\" && !Array.isArray(last)) {\n return { positionalArgs: args.slice(0, -1), overrides: last as T };\n }\n }\n return { positionalArgs: args };\n}\n\n/**\n * Dev address (Alice) used as fallback origin for read-only queries when no\n * wallet is connected. Queries are dry-run simulations — the origin only\n * affects gas estimation and is safe to stub.\n *\n * This is a development convenience. In production, the origin is resolved\n * from the signerManager (logged-in account) or an explicit defaultOrigin.\n */\nconst QUERY_FALLBACK_ORIGIN = seedToAccount(DEV_PHRASE, \"//Alice\").ss58Address as SS58String;\n\n/**\n * Resolve the origin address: explicit override → signerManager → static default.\n * For queries, pass `forQuery: true` to enable the dev-address fallback.\n */\nfunction resolveOrigin(\n defaults: ContractDefaults,\n override?: SS58String,\n forQuery?: boolean,\n): SS58String | undefined {\n if (override) return override;\n const sourceAddr = defaults.signerManager?.getState().selectedAccount?.address;\n if (sourceAddr) return sourceAddr as SS58String;\n if (defaults.origin) return defaults.origin;\n if (forQuery) {\n log.warn(\"No origin configured — using dev fallback (Alice) for query dry-run\");\n return QUERY_FALLBACK_ORIGIN;\n }\n return undefined;\n}\n\n/**\n * Resolve the signer: explicit override → signerManager → static default.\n */\nfunction resolveSigner(\n defaults: ContractDefaults,\n override?: PolkadotSigner,\n): PolkadotSigner | undefined {\n return override ?? defaults.signerManager?.getSigner() ?? defaults.signer;\n}\n\n/**\n * Wrap an ink SDK contract instance with a proxy that exposes each ABI\n * method as `{ query, tx }` — converting positional arguments to the\n * named-parameter format the SDK expects.\n */\nexport function wrapContract(\n inkContract: InkContract,\n abi: AbiEntry[],\n defaults: ContractDefaults,\n): Contract<ContractDef> {\n const methodArgs = buildMethodArgMap(abi);\n\n return new Proxy({} as any, {\n get(_, methodName: string) {\n if (typeof methodName !== \"string\") return undefined;\n const argNames = methodArgs[methodName];\n if (!argNames) return undefined;\n\n return {\n query: async (...args: unknown[]) => {\n const { positionalArgs, overrides } = extractOverrides<QueryOptions>(\n argNames,\n args,\n );\n const data = positionalToNamed(argNames, positionalArgs);\n const origin = resolveOrigin(defaults, overrides?.origin, true)!;\n\n const result = await inkContract.query(methodName, {\n origin,\n data,\n ...(overrides?.value !== undefined && { value: overrides.value }),\n });\n return {\n success: result.success,\n value: result.success ? result.value.response : undefined,\n gasRequired: result.value?.gasRequired,\n };\n },\n\n tx: async (...args: unknown[]) => {\n const { positionalArgs, overrides } = extractOverrides<TxOptions>(\n argNames,\n args,\n );\n const data = positionalToNamed(argNames, positionalArgs);\n const signer = resolveSigner(defaults, overrides?.signer);\n if (!signer) {\n throw new ContractSignerMissingError();\n }\n\n const origin =\n resolveOrigin(defaults, overrides?.origin) ??\n (ss58Address(signer.publicKey) as SS58String);\n const inkTx = inkContract.send(methodName, {\n data,\n origin,\n ...(overrides?.value !== undefined && { value: overrides.value }),\n ...(overrides?.gasLimit && { gasLimit: overrides.gasLimit }),\n ...(overrides?.storageDepositLimit !== undefined && {\n storageDepositLimit: overrides.storageDepositLimit,\n }),\n });\n return submitAndWatch(inkTx, signer, {\n waitFor: overrides?.waitFor,\n timeoutMs: overrides?.timeoutMs,\n mortalityPeriod: overrides?.mortalityPeriod,\n onStatus: overrides?.onStatus,\n });\n },\n };\n },\n });\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"buildMethodArgMap\", () => {\n test(\"extracts function parameter names from ABI\", () => {\n const abi: AbiEntry[] = [\n { type: \"constructor\", inputs: [], stateMutability: \"nonpayable\" },\n {\n type: \"function\",\n name: \"transfer\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"balanceOf\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n { type: \"event\", name: \"Transfer\", inputs: [] },\n ];\n const map = buildMethodArgMap(abi);\n expect(map).toEqual({\n transfer: [\"to\", \"amount\"],\n balanceOf: [\"owner\"],\n });\n });\n\n test(\"returns empty map for ABI with no functions\", () => {\n const abi: AbiEntry[] = [\n { type: \"constructor\", inputs: [] },\n { type: \"event\", name: \"Evt\", inputs: [] },\n ];\n expect(buildMethodArgMap(abi)).toEqual({});\n });\n });\n\n describe(\"positionalToNamed\", () => {\n test(\"maps positional values to named keys\", () => {\n expect(positionalToNamed([\"a\", \"b\"], [1, 2])).toEqual({ a: 1, b: 2 });\n });\n\n test(\"handles empty args\", () => {\n expect(positionalToNamed([], [])).toEqual({});\n });\n });\n\n describe(\"extractOverrides\", () => {\n test(\"returns overrides when extra object arg is present\", () => {\n const result = extractOverrides<{ origin: string }>([\"a\"], [42, { origin: \"0x1\" }]);\n expect(result.positionalArgs).toEqual([42]);\n expect(result.overrides).toEqual({ origin: \"0x1\" });\n });\n\n test(\"returns no overrides when arg count matches\", () => {\n const result = extractOverrides([\"a\", \"b\"], [1, 2]);\n expect(result.positionalArgs).toEqual([1, 2]);\n expect(result.overrides).toBeUndefined();\n });\n\n test(\"does not treat array as overrides\", () => {\n const result = extractOverrides([\"a\"], [1, [2, 3]]);\n expect(result.positionalArgs).toEqual([1, [2, 3]]);\n expect(result.overrides).toBeUndefined();\n });\n\n test(\"does not treat primitive as overrides\", () => {\n const result = extractOverrides([\"a\"], [1, \"extra\"]);\n expect(result.positionalArgs).toEqual([1, \"extra\"]);\n expect(result.overrides).toBeUndefined();\n });\n });\n\n /** Build a partial SignerManager mock for tests. */\n function mockSigner(opts: {\n address?: string | null;\n signer?: any;\n }): import(\"@parity/product-sdk-signer\").SignerManager {\n return {\n getSigner: () => opts.signer ?? null,\n getState: () => ({\n selectedAccount: opts.address ? ({ address: opts.address } as any) : null,\n }),\n } as any;\n }\n\n describe(\"resolveOrigin\", () => {\n test(\"explicit override wins\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: \"5Source\" }),\n };\n expect(resolveOrigin(defaults, \"5Override\" as SS58String)).toBe(\"5Override\");\n });\n\n test(\"signerManager wins over static default\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: \"5Source\" }),\n };\n expect(resolveOrigin(defaults)).toBe(\"5Source\");\n });\n\n test(\"falls back to static default\", () => {\n const defaults: ContractDefaults = { origin: \"5Static\" as SS58String };\n expect(resolveOrigin(defaults)).toBe(\"5Static\");\n });\n\n test(\"returns undefined when nothing available\", () => {\n expect(resolveOrigin({})).toBeUndefined();\n });\n\n test(\"skips signerManager when no account selected\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: null }),\n };\n expect(resolveOrigin(defaults)).toBe(\"5Static\");\n });\n });\n\n describe(\"resolveSigner\", () => {\n const fakeSigner = { id: \"fake\" } as any;\n const sourceSigner = { id: \"source\" } as any;\n\n test(\"explicit override wins\", () => {\n const defaults: ContractDefaults = {\n signer: { id: \"static\" } as any,\n signerManager: mockSigner({ signer: sourceSigner }),\n };\n expect(resolveSigner(defaults, fakeSigner)).toBe(fakeSigner);\n });\n\n test(\"signerManager wins over static default\", () => {\n const defaults: ContractDefaults = {\n signer: { id: \"static\" } as any,\n signerManager: mockSigner({ signer: sourceSigner }),\n };\n expect(resolveSigner(defaults)).toBe(sourceSigner);\n });\n\n test(\"falls back to static default\", () => {\n const defaults: ContractDefaults = { signer: fakeSigner };\n expect(resolveSigner(defaults)).toBe(fakeSigner);\n });\n\n test(\"returns undefined when nothing available\", () => {\n expect(resolveSigner({})).toBeUndefined();\n });\n\n test(\"skips signerManager when getSigner returns null\", () => {\n const defaults: ContractDefaults = {\n signer: fakeSigner,\n signerManager: mockSigner({}),\n };\n expect(resolveSigner(defaults)).toBe(fakeSigner);\n });\n });\n}\n","/** Base class for all contract errors. Use `instanceof ContractError` to catch any contract-related error. */\nexport class ContractError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ContractError\";\n }\n}\n\n/** No signer was available for a transaction call. */\nexport class ContractSignerMissingError extends ContractError {\n constructor() {\n super(\n \"No signer available. Pass { signer } in call options, \" +\n \"set defaultSigner, or provide a signerManager.\",\n );\n this.name = \"ContractSignerMissingError\";\n }\n}\n\n/** A contract was not found in the cdm.json manifest. */\nexport class ContractNotFoundError extends ContractError {\n readonly library: string;\n readonly targetHash: string;\n\n constructor(library: string, targetHash: string) {\n super(`Contract \"${library}\" not found in cdm.json for target ${targetHash}`);\n this.name = \"ContractNotFoundError\";\n this.library = library;\n this.targetHash = targetHash;\n }\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"ContractError\", () => {\n test(\"base error has correct name\", () => {\n const err = new ContractError(\"test\");\n expect(err.name).toBe(\"ContractError\");\n expect(err).toBeInstanceOf(Error);\n });\n\n test(\"instanceof catches all contract errors\", () => {\n expect(new ContractSignerMissingError()).toBeInstanceOf(ContractError);\n expect(new ContractNotFoundError(\"@a/b\", \"abc\")).toBeInstanceOf(ContractError);\n });\n });\n\n describe(\"ContractSignerMissingError\", () => {\n test(\"message mentions signer options\", () => {\n const err = new ContractSignerMissingError();\n expect(err.message).toContain(\"signer\");\n expect(err.message).toContain(\"signerManager\");\n expect(err.name).toBe(\"ContractSignerMissingError\");\n });\n });\n\n describe(\"ContractNotFoundError\", () => {\n test(\"includes library and target\", () => {\n const err = new ContractNotFoundError(\"@test/foo\", \"abc123\");\n expect(err.library).toBe(\"@test/foo\");\n expect(err.targetHash).toBe(\"abc123\");\n expect(err.message).toContain(\"@test/foo\");\n expect(err.message).toContain(\"abc123\");\n });\n });\n}\n","import type { HexString, PolkadotClient } from \"polkadot-api\";\nimport type { InkSdk } from \"@polkadot-api/sdk-ink\";\nimport { wrapContract } from \"./wrap.js\";\nimport { ContractNotFoundError } from \"./errors.js\";\nimport type {\n AbiEntry,\n CdmJson,\n CdmJsonContract,\n Contract,\n ContractDef,\n ContractDefaults,\n ContractManagerOptions,\n ContractOptions,\n Contracts,\n} from \"./types.js\";\n\n/**\n * Manages typed contract interactions backed by a `cdm.json` manifest.\n *\n * Pass a `signerManager` (e.g. a `SignerManager` from `@parity/product-sdk-signer`)\n * so the currently logged-in account is used automatically — no manual\n * signer/origin wiring needed.\n *\n * @example\n * ```ts\n * import { createChainClient } from \"@parity/product-sdk-chain-client\";\n * import { createInkSdk } from \"@polkadot-api/sdk-ink\";\n * import { paseo_asset_hub } from \"@parity/product-sdk-descriptors/paseo-asset-hub\";\n * import { ContractManager } from \"@parity/product-sdk-contracts\";\n * import cdmJson from \"./cdm.json\";\n *\n * const client = await createChainClient({\n * chains: { assetHub: paseo_asset_hub },\n * rpcs: { assetHub: [\"wss://sys.ibp.network/asset-hub-paseo\"] },\n * });\n * const inkSdk = createInkSdk(client.raw.assetHub, { atBest: true });\n * const manager = new ContractManager(cdmJson, inkSdk, {\n * signerManager: signerManager, // from @parity/product-sdk-signer\n * });\n *\n * // Uses the host's logged-in account automatically\n * const counter = manager.getContract(\"@example/counter\");\n * const { value } = await counter.getCount.query();\n * await counter.increment.tx();\n * ```\n */\nexport class ContractManager {\n private cdmJson: CdmJson;\n private targetHash: string;\n private inkSdk: InkSdk;\n private defaults: ContractDefaults;\n\n constructor(cdmJson: CdmJson, inkSdk: InkSdk, options?: ContractManagerOptions) {\n this.cdmJson = cdmJson;\n this.inkSdk = inkSdk;\n\n if (options?.targetHash) {\n this.targetHash = options.targetHash;\n } else {\n const targets = Object.keys(cdmJson.targets);\n if (targets.length === 0) throw new Error(\"No targets found in cdm.json\");\n this.targetHash = targets[0];\n }\n\n this.defaults = {\n signerManager: options?.signerManager,\n origin: options?.defaultOrigin,\n signer: options?.defaultSigner,\n };\n }\n\n /** Update the default origin, signer, or signerManager used by all contract handles. */\n setDefaults(defaults: ContractDefaults): void {\n if (defaults.signerManager !== undefined)\n this.defaults.signerManager = defaults.signerManager;\n if (defaults.origin !== undefined) this.defaults.origin = defaults.origin;\n if (defaults.signer !== undefined) this.defaults.signer = defaults.signer;\n }\n\n /**\n * Create a ContractManager from a raw `PolkadotClient`.\n *\n * Convenience factory that creates the InkSdk internally via dynamic import\n * of `@polkadot-api/sdk-ink`. The ~4 MB sdk-ink metadata is loaded lazily\n * only when this method is called.\n *\n * For size-sensitive apps, prefer the constructor with a pre-created `InkSdk`\n * to control exactly when `@polkadot-api/sdk-ink` is loaded.\n *\n * @param cdmJson - The CDM manifest.\n * @param client - A `PolkadotClient` for the chain where contracts are deployed (e.g., `client.raw.assetHub`).\n * @param options - Optional configuration (signerManager, defaults).\n *\n * @example\n * ```ts\n * import { createChainClient } from \"@parity/product-sdk-chain-client\";\n * import { paseo_asset_hub } from \"@parity/product-sdk-descriptors/paseo-asset-hub\";\n * import { ContractManager } from \"@parity/product-sdk-contracts\";\n *\n * const client = await createChainClient({\n * chains: { assetHub: paseo_asset_hub },\n * rpcs: { assetHub: [\"wss://sys.ibp.network/asset-hub-paseo\"] },\n * });\n * const manager = await ContractManager.fromClient(cdmJson, client.raw.assetHub, {\n * signerManager,\n * });\n * ```\n */\n static async fromClient(\n cdmJson: CdmJson,\n client: PolkadotClient,\n options?: ContractManagerOptions,\n ): Promise<ContractManager> {\n const { createInkSdk } = await import(\"@polkadot-api/sdk-ink\");\n const inkSdk = createInkSdk(client, { atBest: true });\n return new ContractManager(cdmJson, inkSdk, options);\n }\n\n private getContractData(library: string): CdmJsonContract {\n const contractsForTarget = this.cdmJson.contracts?.[this.targetHash];\n if (!contractsForTarget || !(library in contractsForTarget)) {\n throw new ContractNotFoundError(library, this.targetHash);\n }\n return contractsForTarget[library];\n }\n\n /**\n * Get a typed contract handle.\n *\n * Each method on the returned object has `.query()` for read-only calls\n * and `.tx()` for signed transactions. When codegen augments\n * {@link Contracts}, passing a known library name returns a fully-typed\n * handle. Without codegen the generic overload still works — methods are\n * accessible but untyped.\n */\n getContract<K extends string & keyof Contracts>(library: K): Contract<Contracts[K]>;\n getContract(library: string): Contract<ContractDef>;\n getContract(library: string): Contract<ContractDef> {\n const data = this.getContractData(library);\n const descriptor = { abi: data.abi };\n const inkContract = this.inkSdk.getContract(descriptor as any, data.address);\n return wrapContract(inkContract, data.abi, this.defaults);\n }\n\n /** Get the on-chain address of an installed contract. */\n getAddress(library: string): HexString {\n return this.getContractData(library).address;\n }\n}\n\n/**\n * Create a contract handle from a raw address and ABI — no `cdm.json` needed.\n *\n * @example\n * ```ts\n * import { createInkSdk } from \"@polkadot-api/sdk-ink\";\n *\n * const inkSdk = createInkSdk(client.raw.assetHub, { atBest: true });\n * const counter = createContract(inkSdk, \"0xC472...\", abi, {\n * signerManager: signerManager,\n * });\n * await counter.getCount.query();\n * await counter.increment.tx();\n * ```\n */\nexport function createContract(\n inkSdk: InkSdk,\n address: HexString,\n abi: AbiEntry[],\n options?: ContractOptions,\n): Contract<ContractDef> {\n const inkContract = inkSdk.getContract({ abi } as any, address);\n const defaults: ContractDefaults = {\n signerManager: options?.signerManager,\n origin: options?.defaultOrigin,\n signer: options?.defaultSigner,\n };\n return wrapContract(inkContract, abi, defaults);\n}\n\n/**\n * Create a contract handle from a raw `PolkadotClient`, address, and ABI.\n *\n * Convenience wrapper that creates the InkSdk internally via dynamic import.\n * For size-sensitive apps, use {@link createContract} with a pre-created `InkSdk`.\n *\n * @example\n * ```ts\n * const counter = await createContractFromClient(client.raw.assetHub, \"0xC472...\", abi);\n * const { value } = await counter.getCount.query();\n * ```\n */\nexport async function createContractFromClient(\n client: PolkadotClient,\n address: HexString,\n abi: AbiEntry[],\n options?: ContractOptions,\n): Promise<Contract<ContractDef>> {\n const { createInkSdk } = await import(\"@polkadot-api/sdk-ink\");\n const inkSdk = createInkSdk(client, { atBest: true });\n return createContract(inkSdk, address, abi, options);\n}\n"],"mappings":"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","names":["mockSigner"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/wrap.ts","../src/manager.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/** Base class for all contract errors. Use `instanceof ContractError` to catch any contract-related error. */\nexport class ContractError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ContractError\";\n }\n}\n\n/** No signer was available for a transaction call. */\nexport class ContractSignerMissingError extends ContractError {\n constructor() {\n super(\n \"No signer available. Pass { signer } in call options, \" +\n \"set defaultSigner, or provide a signerManager.\",\n );\n this.name = \"ContractSignerMissingError\";\n }\n}\n\n/** A contract was not found in the cdm.json manifest. */\nexport class ContractNotFoundError extends ContractError {\n readonly library: string;\n readonly targetHash: string;\n\n constructor(library: string, targetHash: string) {\n super(`Contract \"${library}\" not found in cdm.json for target ${targetHash}`);\n this.name = \"ContractNotFoundError\";\n this.library = library;\n this.targetHash = targetHash;\n }\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"ContractError\", () => {\n test(\"base error has correct name\", () => {\n const err = new ContractError(\"test\");\n expect(err.name).toBe(\"ContractError\");\n expect(err).toBeInstanceOf(Error);\n });\n\n test(\"instanceof catches all contract errors\", () => {\n expect(new ContractSignerMissingError()).toBeInstanceOf(ContractError);\n expect(new ContractNotFoundError(\"@a/b\", \"abc\")).toBeInstanceOf(ContractError);\n });\n });\n\n describe(\"ContractSignerMissingError\", () => {\n test(\"message mentions signer options\", () => {\n const err = new ContractSignerMissingError();\n expect(err.message).toContain(\"signer\");\n expect(err.message).toContain(\"signerManager\");\n expect(err.name).toBe(\"ContractSignerMissingError\");\n });\n });\n\n describe(\"ContractNotFoundError\", () => {\n test(\"includes library and target\", () => {\n const err = new ContractNotFoundError(\"@test/foo\", \"abc123\");\n expect(err.library).toBe(\"@test/foo\");\n expect(err.targetHash).toBe(\"abc123\");\n expect(err.message).toContain(\"@test/foo\");\n expect(err.message).toContain(\"abc123\");\n });\n });\n}\n","import type { PolkadotSigner, SS58String } from \"polkadot-api\";\nimport { submitAndWatch } from \"@parity/product-sdk-tx\";\nimport { seedToAccount } from \"@parity/product-sdk-keys\";\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { DEV_PHRASE, ss58Address } from \"@polkadot-labs/hdkd-helpers\";\nimport { ContractSignerMissingError } from \"./errors.js\";\nimport type {\n AbiEntry,\n BatchableCall,\n Contract,\n ContractDef,\n ContractDefaults,\n PrepareOptions,\n QueryOptions,\n TxOptions,\n} from \"./types.js\";\n\nconst log = createLogger(\"contracts\");\n\n/**\n * Ink SDK contract instance returned by `inkSdk.getContract()`.\n *\n * Typed as `any` because we call `.query()` / `.send()` with runtime method\n * names — the SDK's `ContractSdk<D>` requires compile-time descriptor\n * knowledge that runtime ABIs can't provide.\n */\ntype InkContract = any;\n\n/** Extract method name → ordered parameter names from the ABI. */\nfunction buildMethodArgMap(abi: AbiEntry[]): Record<string, string[]> {\n const map: Record<string, string[]> = {};\n for (const entry of abi) {\n if (entry.type === \"function\" && entry.name) {\n map[entry.name] = entry.inputs.map((p) => p.name);\n }\n }\n return map;\n}\n\n/** Convert positional arguments to a named object matching the ABI parameter names. */\nfunction positionalToNamed(argNames: string[], values: unknown[]): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (let i = 0; i < argNames.length; i++) {\n data[argNames[i]] = values[i];\n }\n return data;\n}\n\n/**\n * If the caller passed more arguments than the ABI expects and the last\n * argument is a plain object, treat it as an options override.\n */\nfunction extractOverrides<T>(\n argNames: string[],\n args: unknown[],\n): { positionalArgs: unknown[]; overrides?: T } {\n if (args.length > argNames.length && args.length > 0) {\n const last = args[args.length - 1];\n if (last && typeof last === \"object\" && !Array.isArray(last)) {\n return { positionalArgs: args.slice(0, -1), overrides: last as T };\n }\n }\n return { positionalArgs: args };\n}\n\n/**\n * Dev address (Alice) used as fallback origin for read-only queries when no\n * wallet is connected. Queries are dry-run simulations — the origin only\n * affects gas estimation and is safe to stub.\n *\n * This is a development convenience. In production, the origin is resolved\n * from the signerManager (logged-in account) or an explicit defaultOrigin.\n */\nconst QUERY_FALLBACK_ORIGIN = seedToAccount(DEV_PHRASE, \"//Alice\").ss58Address as SS58String;\n\n/**\n * Resolve the origin address: explicit override → signerManager → static default.\n * For queries, pass `forQuery: true` to enable the dev-address fallback.\n */\nfunction resolveOrigin(\n defaults: ContractDefaults,\n override?: SS58String,\n forQuery?: boolean,\n): SS58String | undefined {\n if (override) return override;\n const sourceAddr = defaults.signerManager?.getState().selectedAccount?.address;\n if (sourceAddr) return sourceAddr as SS58String;\n if (defaults.origin) return defaults.origin;\n if (forQuery) {\n log.warn(\"No origin configured — using dev fallback (Alice) for query dry-run\");\n return QUERY_FALLBACK_ORIGIN;\n }\n return undefined;\n}\n\n/**\n * Resolve the signer: explicit override → signerManager → static default.\n */\nfunction resolveSigner(\n defaults: ContractDefaults,\n override?: PolkadotSigner,\n): PolkadotSigner | undefined {\n return override ?? defaults.signerManager?.getSigner() ?? defaults.signer;\n}\n\n/**\n * Wrap an ink SDK contract instance with a proxy that exposes each ABI\n * method as `{ query, tx }` — converting positional arguments to the\n * named-parameter format the SDK expects.\n */\nexport function wrapContract(\n inkContract: InkContract,\n abi: AbiEntry[],\n defaults: ContractDefaults,\n): Contract<ContractDef> {\n const methodArgs = buildMethodArgMap(abi);\n\n return new Proxy({} as any, {\n get(_, methodName: string) {\n if (typeof methodName !== \"string\") return undefined;\n const argNames = methodArgs[methodName];\n if (!argNames) return undefined;\n\n return {\n query: async (...args: unknown[]) => {\n const { positionalArgs, overrides } = extractOverrides<QueryOptions>(\n argNames,\n args,\n );\n const data = positionalToNamed(argNames, positionalArgs);\n const origin = resolveOrigin(defaults, overrides?.origin, true)!;\n\n const result = await inkContract.query(methodName, {\n origin,\n data,\n ...(overrides?.value !== undefined && { value: overrides.value }),\n });\n return {\n success: result.success,\n value: result.success ? result.value.response : undefined,\n gasRequired: result.value?.gasRequired,\n };\n },\n\n tx: async (...args: unknown[]) => {\n const { positionalArgs, overrides } = extractOverrides<TxOptions>(\n argNames,\n args,\n );\n const data = positionalToNamed(argNames, positionalArgs);\n const signer = resolveSigner(defaults, overrides?.signer);\n if (!signer) {\n throw new ContractSignerMissingError();\n }\n\n const origin =\n resolveOrigin(defaults, overrides?.origin) ??\n (ss58Address(signer.publicKey) as SS58String);\n const inkTx = inkContract.send(methodName, {\n data,\n origin,\n ...(overrides?.value !== undefined && { value: overrides.value }),\n ...(overrides?.gasLimit && { gasLimit: overrides.gasLimit }),\n ...(overrides?.storageDepositLimit !== undefined && {\n storageDepositLimit: overrides.storageDepositLimit,\n }),\n });\n return submitAndWatch(inkTx, signer, {\n waitFor: overrides?.waitFor,\n timeoutMs: overrides?.timeoutMs,\n mortalityPeriod: overrides?.mortalityPeriod,\n onStatus: overrides?.onStatus,\n });\n },\n\n prepare: (...args: unknown[]): BatchableCall => {\n const { positionalArgs, overrides } = extractOverrides<PrepareOptions>(\n argNames,\n args,\n );\n const data = positionalToNamed(argNames, positionalArgs);\n // prepare() doesn't require a signer — origin here is for\n // dry-run gas estimation; the batch's signer replaces it\n // as the dispatched origin at submission.\n const origin = resolveOrigin(defaults, overrides?.origin, true)!;\n return inkContract.send(methodName, {\n data,\n origin,\n ...(overrides?.value !== undefined && { value: overrides.value }),\n ...(overrides?.gasLimit && { gasLimit: overrides.gasLimit }),\n ...(overrides?.storageDepositLimit !== undefined && {\n storageDepositLimit: overrides.storageDepositLimit,\n }),\n });\n },\n };\n },\n });\n}\n\nif (import.meta.vitest) {\n const { test, expect, describe } = import.meta.vitest;\n\n describe(\"buildMethodArgMap\", () => {\n test(\"extracts function parameter names from ABI\", () => {\n const abi: AbiEntry[] = [\n { type: \"constructor\", inputs: [], stateMutability: \"nonpayable\" },\n {\n type: \"function\",\n name: \"transfer\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"balanceOf\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n { type: \"event\", name: \"Transfer\", inputs: [] },\n ];\n const map = buildMethodArgMap(abi);\n expect(map).toEqual({\n transfer: [\"to\", \"amount\"],\n balanceOf: [\"owner\"],\n });\n });\n\n test(\"returns empty map for ABI with no functions\", () => {\n const abi: AbiEntry[] = [\n { type: \"constructor\", inputs: [] },\n { type: \"event\", name: \"Evt\", inputs: [] },\n ];\n expect(buildMethodArgMap(abi)).toEqual({});\n });\n });\n\n describe(\"positionalToNamed\", () => {\n test(\"maps positional values to named keys\", () => {\n expect(positionalToNamed([\"a\", \"b\"], [1, 2])).toEqual({ a: 1, b: 2 });\n });\n\n test(\"handles empty args\", () => {\n expect(positionalToNamed([], [])).toEqual({});\n });\n });\n\n describe(\"extractOverrides\", () => {\n test(\"returns overrides when extra object arg is present\", () => {\n const result = extractOverrides<{ origin: string }>([\"a\"], [42, { origin: \"0x1\" }]);\n expect(result.positionalArgs).toEqual([42]);\n expect(result.overrides).toEqual({ origin: \"0x1\" });\n });\n\n test(\"returns no overrides when arg count matches\", () => {\n const result = extractOverrides([\"a\", \"b\"], [1, 2]);\n expect(result.positionalArgs).toEqual([1, 2]);\n expect(result.overrides).toBeUndefined();\n });\n\n test(\"does not treat array as overrides\", () => {\n const result = extractOverrides([\"a\"], [1, [2, 3]]);\n expect(result.positionalArgs).toEqual([1, [2, 3]]);\n expect(result.overrides).toBeUndefined();\n });\n\n test(\"does not treat primitive as overrides\", () => {\n const result = extractOverrides([\"a\"], [1, \"extra\"]);\n expect(result.positionalArgs).toEqual([1, \"extra\"]);\n expect(result.overrides).toBeUndefined();\n });\n });\n\n /** Build a partial SignerManager mock for tests. */\n function mockSigner(opts: {\n address?: string | null;\n signer?: any;\n }): import(\"@parity/product-sdk-signer\").SignerManager {\n return {\n getSigner: () => opts.signer ?? null,\n getState: () => ({\n selectedAccount: opts.address ? ({ address: opts.address } as any) : null,\n }),\n } as any;\n }\n\n describe(\"resolveOrigin\", () => {\n test(\"explicit override wins\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: \"5Source\" }),\n };\n expect(resolveOrigin(defaults, \"5Override\" as SS58String)).toBe(\"5Override\");\n });\n\n test(\"signerManager wins over static default\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: \"5Source\" }),\n };\n expect(resolveOrigin(defaults)).toBe(\"5Source\");\n });\n\n test(\"falls back to static default\", () => {\n const defaults: ContractDefaults = { origin: \"5Static\" as SS58String };\n expect(resolveOrigin(defaults)).toBe(\"5Static\");\n });\n\n test(\"returns undefined when nothing available\", () => {\n expect(resolveOrigin({})).toBeUndefined();\n });\n\n test(\"skips signerManager when no account selected\", () => {\n const defaults: ContractDefaults = {\n origin: \"5Static\" as SS58String,\n signerManager: mockSigner({ address: null }),\n };\n expect(resolveOrigin(defaults)).toBe(\"5Static\");\n });\n });\n\n describe(\"resolveSigner\", () => {\n const fakeSigner = { id: \"fake\" } as any;\n const sourceSigner = { id: \"source\" } as any;\n\n test(\"explicit override wins\", () => {\n const defaults: ContractDefaults = {\n signer: { id: \"static\" } as any,\n signerManager: mockSigner({ signer: sourceSigner }),\n };\n expect(resolveSigner(defaults, fakeSigner)).toBe(fakeSigner);\n });\n\n test(\"signerManager wins over static default\", () => {\n const defaults: ContractDefaults = {\n signer: { id: \"static\" } as any,\n signerManager: mockSigner({ signer: sourceSigner }),\n };\n expect(resolveSigner(defaults)).toBe(sourceSigner);\n });\n\n test(\"falls back to static default\", () => {\n const defaults: ContractDefaults = { signer: fakeSigner };\n expect(resolveSigner(defaults)).toBe(fakeSigner);\n });\n\n test(\"returns undefined when nothing available\", () => {\n expect(resolveSigner({})).toBeUndefined();\n });\n\n test(\"skips signerManager when getSigner returns null\", () => {\n const defaults: ContractDefaults = {\n signer: fakeSigner,\n signerManager: mockSigner({}),\n };\n expect(resolveSigner(defaults)).toBe(fakeSigner);\n });\n });\n\n describe(\"wrapContract — prepare\", () => {\n // .prepare() port from polkadot-apps@4b60d19. Asserts that the\n // method returns a BatchableCall consumable by batchSubmitAndWatch\n // without going through submission, doesn't require a signer, and\n // forwards the gas/value overrides the same way `.tx()` does.\n\n const abi: AbiEntry[] = [\n {\n type: \"function\",\n name: \"increment\",\n inputs: [],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"add\",\n inputs: [{ name: \"n\", type: \"uint32\" }],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n ];\n\n test(\"prepare returns ink send result without submitting\", () => {\n let sendCapture: any;\n const fakeSendResult = { waited: Promise.resolve({ decodedCall: { pallet: \"X\" } }) };\n const fakeInk = {\n send: (method: string, args: any) => {\n sendCapture = { method, args };\n return fakeSendResult;\n },\n };\n const wrapped = wrapContract(fakeInk, abi, { origin: \"5Alice\" as any });\n\n const result = wrapped.add.prepare(42);\n expect(sendCapture.method).toBe(\"add\");\n expect(sendCapture.args.data).toEqual({ n: 42 });\n expect(sendCapture.args.origin).toBe(\"5Alice\");\n expect(result).toBe(fakeSendResult);\n });\n\n test(\"prepare does not require a signer\", () => {\n const fakeInk = {\n send: () => ({ waited: Promise.resolve({ decodedCall: {} }) }),\n };\n const wrapped = wrapContract(fakeInk, abi, {});\n // No signer, no signerManager, no default origin — should still work\n expect(() => wrapped.increment.prepare()).not.toThrow();\n });\n\n test(\"prepare uses fallback origin for dry-run gas estimation\", () => {\n let captured: any;\n const fakeInk = {\n send: (_: string, args: any) => {\n captured = args;\n return { waited: Promise.resolve({ decodedCall: {} }) };\n },\n };\n const wrapped = wrapContract(fakeInk, abi, {});\n\n wrapped.increment.prepare();\n expect(captured.origin).toBe(QUERY_FALLBACK_ORIGIN);\n });\n\n test(\"prepare forwards value, gasLimit, storageDepositLimit\", () => {\n let captured: any;\n const fakeInk = {\n send: (_: string, args: any) => {\n captured = args;\n return { waited: Promise.resolve({ decodedCall: {} }) };\n },\n };\n const wrapped = wrapContract(fakeInk, abi, { origin: \"5A\" as any });\n\n const gasLimit = { ref_time: 1_000_000n, proof_size: 1024n };\n wrapped.add.prepare(7, {\n value: 500n,\n gasLimit,\n storageDepositLimit: 999n,\n });\n expect(captured.data).toEqual({ n: 7 });\n expect(captured.value).toBe(500n);\n expect(captured.gasLimit).toBe(gasLimit);\n expect(captured.storageDepositLimit).toBe(999n);\n });\n\n test(\"prepare override origin wins over signerManager and default\", () => {\n let captured: any;\n const fakeInk = {\n send: (_: string, args: any) => {\n captured = args;\n return { waited: Promise.resolve({ decodedCall: {} }) };\n },\n };\n const wrapped = wrapContract(fakeInk, abi, {\n origin: \"5Default\" as any,\n signerManager: mockSigner({ address: \"5Source\" }),\n });\n\n wrapped.increment.prepare({ origin: \"5Override\" as any });\n expect(captured.origin).toBe(\"5Override\");\n });\n\n test(\"prepare result is consumable by batchSubmitAndWatch\", async () => {\n const { batchSubmitAndWatch } = await import(\"@parity/product-sdk-tx\");\n const prepared = [\n { waited: Promise.resolve({ decodedCall: { call: \"one\" } }) },\n { waited: Promise.resolve({ decodedCall: { call: \"two\" } }) },\n ];\n const fakeInk = {\n send: (_: string, _args: any) => prepared.shift()!,\n };\n const wrapped = wrapContract(fakeInk, abi, { origin: \"5A\" as any });\n\n const a = wrapped.increment.prepare();\n const b = wrapped.add.prepare(1);\n\n const captured: unknown[][] = [];\n const fakeApi = {\n tx: {\n Utility: {\n batch_all: (args: { calls: unknown[] }) => {\n captured.push(args.calls);\n return {\n signSubmitAndWatch: () => ({\n subscribe: (h: any) => {\n h.next({ type: \"signed\", txHash: \"0xb\" });\n h.next({\n type: \"txBestBlocksState\",\n txHash: \"0xb\",\n found: true,\n ok: true,\n events: [],\n block: { hash: \"0xblk\", number: 1, index: 0 },\n });\n return { unsubscribe: () => {} };\n },\n }),\n };\n },\n },\n },\n } as any;\n\n const result = await batchSubmitAndWatch([a, b], fakeApi, {\n publicKey: new Uint8Array(32),\n } as any);\n expect(result.ok).toBe(true);\n expect(captured[0]).toEqual([{ call: \"one\" }, { call: \"two\" }]);\n });\n });\n}\n","import type { HexString, PolkadotClient } from \"polkadot-api\";\nimport type { InkSdk } from \"@polkadot-api/sdk-ink\";\nimport { wrapContract } from \"./wrap.js\";\nimport { ContractNotFoundError } from \"./errors.js\";\nimport type {\n AbiEntry,\n CdmJson,\n CdmJsonContract,\n Contract,\n ContractDef,\n ContractDefaults,\n ContractManagerOptions,\n ContractOptions,\n Contracts,\n} from \"./types.js\";\n\n/**\n * Manages typed contract interactions backed by a `cdm.json` manifest.\n *\n * Pass a `signerManager` (e.g. a `SignerManager` from `@parity/product-sdk-signer`)\n * so the currently logged-in account is used automatically — no manual\n * signer/origin wiring needed.\n *\n * @example\n * ```ts\n * import { createChainClient } from \"@parity/product-sdk-chain-client\";\n * import { createInkSdk } from \"@polkadot-api/sdk-ink\";\n * import { paseo_asset_hub } from \"@parity/product-sdk-descriptors/paseo-asset-hub\";\n * import { ContractManager } from \"@parity/product-sdk-contracts\";\n * import cdmJson from \"./cdm.json\";\n *\n * const client = await createChainClient({\n * chains: { assetHub: paseo_asset_hub },\n * rpcs: { assetHub: [\"wss://sys.ibp.network/asset-hub-paseo\"] },\n * });\n * const inkSdk = createInkSdk(client.raw.assetHub, { atBest: true });\n * const manager = new ContractManager(cdmJson, inkSdk, {\n * signerManager: signerManager, // from @parity/product-sdk-signer\n * });\n *\n * // Uses the host's logged-in account automatically\n * const counter = manager.getContract(\"@example/counter\");\n * const { value } = await counter.getCount.query();\n * await counter.increment.tx();\n * ```\n */\nexport class ContractManager {\n private cdmJson: CdmJson;\n private targetHash: string;\n private inkSdk: InkSdk;\n private defaults: ContractDefaults;\n\n constructor(cdmJson: CdmJson, inkSdk: InkSdk, options?: ContractManagerOptions) {\n this.cdmJson = cdmJson;\n this.inkSdk = inkSdk;\n\n if (options?.targetHash) {\n this.targetHash = options.targetHash;\n } else {\n const targets = Object.keys(cdmJson.targets);\n if (targets.length === 0) throw new Error(\"No targets found in cdm.json\");\n this.targetHash = targets[0];\n }\n\n this.defaults = {\n signerManager: options?.signerManager,\n origin: options?.defaultOrigin,\n signer: options?.defaultSigner,\n };\n }\n\n /** Update the default origin, signer, or signerManager used by all contract handles. */\n setDefaults(defaults: ContractDefaults): void {\n if (defaults.signerManager !== undefined)\n this.defaults.signerManager = defaults.signerManager;\n if (defaults.origin !== undefined) this.defaults.origin = defaults.origin;\n if (defaults.signer !== undefined) this.defaults.signer = defaults.signer;\n }\n\n /**\n * Create a ContractManager from a raw `PolkadotClient`.\n *\n * Convenience factory that creates the InkSdk internally via dynamic import\n * of `@polkadot-api/sdk-ink`. The ~4 MB sdk-ink metadata is loaded lazily\n * only when this method is called.\n *\n * For size-sensitive apps, prefer the constructor with a pre-created `InkSdk`\n * to control exactly when `@polkadot-api/sdk-ink` is loaded.\n *\n * @param cdmJson - The CDM manifest.\n * @param client - A `PolkadotClient` for the chain where contracts are deployed (e.g., `client.raw.assetHub`).\n * @param options - Optional configuration (signerManager, defaults).\n *\n * @example\n * ```ts\n * import { createChainClient } from \"@parity/product-sdk-chain-client\";\n * import { paseo_asset_hub } from \"@parity/product-sdk-descriptors/paseo-asset-hub\";\n * import { ContractManager } from \"@parity/product-sdk-contracts\";\n *\n * const client = await createChainClient({\n * chains: { assetHub: paseo_asset_hub },\n * rpcs: { assetHub: [\"wss://sys.ibp.network/asset-hub-paseo\"] },\n * });\n * const manager = await ContractManager.fromClient(cdmJson, client.raw.assetHub, {\n * signerManager,\n * });\n * ```\n */\n static async fromClient(\n cdmJson: CdmJson,\n client: PolkadotClient,\n options?: ContractManagerOptions,\n ): Promise<ContractManager> {\n const { createInkSdk } = await import(\"@polkadot-api/sdk-ink\");\n const inkSdk = createInkSdk(client, { atBest: true });\n return new ContractManager(cdmJson, inkSdk, options);\n }\n\n private getContractData(library: string): CdmJsonContract {\n const contractsForTarget = this.cdmJson.contracts?.[this.targetHash];\n if (!contractsForTarget || !(library in contractsForTarget)) {\n throw new ContractNotFoundError(library, this.targetHash);\n }\n return contractsForTarget[library];\n }\n\n /**\n * Get a typed contract handle.\n *\n * Each method on the returned object has `.query()` for read-only calls\n * and `.tx()` for signed transactions. When codegen augments\n * {@link Contracts}, passing a known library name returns a fully-typed\n * handle. Without codegen the generic overload still works — methods are\n * accessible but untyped.\n */\n getContract<K extends string & keyof Contracts>(library: K): Contract<Contracts[K]>;\n getContract(library: string): Contract<ContractDef>;\n getContract(library: string): Contract<ContractDef> {\n const data = this.getContractData(library);\n const descriptor = { abi: data.abi };\n const inkContract = this.inkSdk.getContract(descriptor as any, data.address);\n return wrapContract(inkContract, data.abi, this.defaults);\n }\n\n /** Get the on-chain address of an installed contract. */\n getAddress(library: string): HexString {\n return this.getContractData(library).address;\n }\n}\n\n/**\n * Create a contract handle from a raw address and ABI — no `cdm.json` needed.\n *\n * @example\n * ```ts\n * import { createInkSdk } from \"@polkadot-api/sdk-ink\";\n *\n * const inkSdk = createInkSdk(client.raw.assetHub, { atBest: true });\n * const counter = createContract(inkSdk, \"0xC472...\", abi, {\n * signerManager: signerManager,\n * });\n * await counter.getCount.query();\n * await counter.increment.tx();\n * ```\n */\nexport function createContract(\n inkSdk: InkSdk,\n address: HexString,\n abi: AbiEntry[],\n options?: ContractOptions,\n): Contract<ContractDef> {\n const inkContract = inkSdk.getContract({ abi } as any, address);\n const defaults: ContractDefaults = {\n signerManager: options?.signerManager,\n origin: options?.defaultOrigin,\n signer: options?.defaultSigner,\n };\n return wrapContract(inkContract, abi, defaults);\n}\n\n/**\n * Create a contract handle from a raw `PolkadotClient`, address, and ABI.\n *\n * Convenience wrapper that creates the InkSdk internally via dynamic import.\n * For size-sensitive apps, use {@link createContract} with a pre-created `InkSdk`.\n *\n * @example\n * ```ts\n * const counter = await createContractFromClient(client.raw.assetHub, \"0xC472...\", abi);\n * const { value } = await counter.getCount.query();\n * ```\n */\nexport async function createContractFromClient(\n client: PolkadotClient,\n address: HexString,\n abi: AbiEntry[],\n options?: ContractOptions,\n): Promise<Contract<ContractDef>> {\n const { createInkSdk } = await import(\"@polkadot-api/sdk-ink\");\n const inkSdk = createInkSdk(client, { atBest: true });\n return createContract(inkSdk, address, abi, options);\n}\n\nif (import.meta.vitest) {\n const { describe, test, expect } = import.meta.vitest;\n\n /**\n * Real-world cdm.json structure as it appears in\n * `paritytech/playground-cli/cdm.json`. Used here as the reproducer\n * for the cdm-resolution flow: if `getContract()` works against\n * this manifest shape, it works against any consumer's manifest.\n *\n * Notable shape differences from the generated examples:\n * - `metadataCid` is absent (made optional in 0.2.1)\n * - target hash is a single 16-char hex string\n * - `dependencies` uses `\"latest\"` for version\n * - contract addresses are 20-byte EVM-shaped (Polkadot Asset Hub\n * uses Solidity-compatible addresses for Revive contracts)\n */\n const playgroundCdm: CdmJson = {\n targets: {\n acc2c3b5e912b762: {\n \"asset-hub\": \"wss://asset-hub-paseo-rpc.n.dwellir.com\",\n bulletin: \"https://paseo-ipfs.polkadot.io/ipfs\",\n },\n },\n dependencies: {\n acc2c3b5e912b762: {\n \"@w3s/playground-registry\": \"latest\",\n },\n },\n contracts: {\n acc2c3b5e912b762: {\n \"@w3s/playground-registry\": {\n version: 6,\n address: \"0x4A37B123b0BA2A894cA5953f472264921d44e298\",\n abi: [\n { type: \"constructor\", inputs: [], stateMutability: \"nonpayable\" },\n {\n type: \"function\",\n name: \"publish\",\n inputs: [\n { name: \"domain\", type: \"string\" },\n { name: \"metadata_uri\", type: \"string\" },\n { name: \"visibility\", type: \"uint8\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"unpublish\",\n inputs: [{ name: \"domain\", type: \"string\" }],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n ],\n },\n },\n },\n };\n\n /**\n * Minimal InkSdk stub — `getContract()` is the only method\n * `ContractManager.getContract()` calls. Everything else on the SDK\n * is left undefined so a misroute through any other method would\n * throw and surface in the test.\n */\n function fakeInkSdk(): InkSdk {\n return {\n getContract: (descriptor: unknown, address: unknown) => ({\n __descriptor: descriptor,\n __address: address,\n // Each method on a real ink contract has `query` + `send`.\n // We don't invoke them in the smoke test — just need the\n // shape to flow through `wrapContract`'s proxy.\n query: async () => ({ success: true, value: { response: undefined } }),\n send: () => ({ waited: Promise.resolve({}) }),\n }),\n } as unknown as InkSdk;\n }\n\n describe(\"ContractManager — cdm.json resolution\", () => {\n test(\"constructs from a real-world cdm.json without errors\", () => {\n const manager = new ContractManager(playgroundCdm, fakeInkSdk());\n expect(manager.getAddress(\"@w3s/playground-registry\")).toBe(\n \"0x4A37B123b0BA2A894cA5953f472264921d44e298\",\n );\n });\n\n test(\"getContract returns a typed handle for a library in the manifest\", () => {\n const manager = new ContractManager(playgroundCdm, fakeInkSdk());\n const registry = manager.getContract(\"@w3s/playground-registry\");\n\n // Methods from the abi are accessible\n expect(typeof registry.publish.query).toBe(\"function\");\n expect(typeof registry.publish.tx).toBe(\"function\");\n expect(typeof registry.publish.prepare).toBe(\"function\");\n expect(typeof registry.unpublish.query).toBe(\"function\");\n });\n\n test(\"getContract throws ContractNotFoundError for an unknown library\", () => {\n const manager = new ContractManager(playgroundCdm, fakeInkSdk());\n expect(() => manager.getContract(\"@nonexistent/contract\")).toThrow(\n /not found in cdm\\.json/,\n );\n });\n\n test(\"auto-selects the first target when no targetHash is provided\", () => {\n const manager = new ContractManager(playgroundCdm, fakeInkSdk());\n // Single-target manifest — should resolve cleanly without\n // requiring an explicit targetHash.\n expect(() => manager.getContract(\"@w3s/playground-registry\")).not.toThrow();\n });\n\n test(\"getContract passes the right address to inkSdk\", () => {\n let capturedAddress: unknown;\n const inkSdk = {\n getContract: (_descriptor: unknown, address: unknown) => {\n capturedAddress = address;\n return {\n query: async () => ({ success: true, value: { response: undefined } }),\n send: () => ({ waited: Promise.resolve({}) }),\n };\n },\n } as unknown as InkSdk;\n\n const manager = new ContractManager(playgroundCdm, inkSdk);\n manager.getContract(\"@w3s/playground-registry\");\n expect(capturedAddress).toBe(\"0x4A37B123b0BA2A894cA5953f472264921d44e298\");\n });\n\n test(\"explicit targetHash option selects the right contracts subtree\", () => {\n // Multi-target manifest: we should be able to pin to a specific\n // target hash and have getContract resolve against it.\n const multiTargetCdm: CdmJson = {\n targets: {\n target_a: { \"asset-hub\": \"wss://a\", bulletin: \"https://a\" },\n target_b: { \"asset-hub\": \"wss://b\", bulletin: \"https://b\" },\n },\n dependencies: {\n target_a: { \"@org/foo\": \"1.0\" },\n target_b: { \"@org/foo\": \"2.0\" },\n },\n contracts: {\n target_a: {\n \"@org/foo\": {\n version: 1,\n address: \"0x1111111111111111111111111111111111111111\",\n abi: [],\n },\n },\n target_b: {\n \"@org/foo\": {\n version: 2,\n address: \"0x2222222222222222222222222222222222222222\",\n abi: [],\n },\n },\n },\n };\n\n const aManager = new ContractManager(multiTargetCdm, fakeInkSdk(), {\n targetHash: \"target_a\",\n });\n const bManager = new ContractManager(multiTargetCdm, fakeInkSdk(), {\n targetHash: \"target_b\",\n });\n\n expect(aManager.getAddress(\"@org/foo\")).toBe(\n \"0x1111111111111111111111111111111111111111\",\n );\n expect(bManager.getAddress(\"@org/foo\")).toBe(\n \"0x2222222222222222222222222222222222222222\",\n );\n });\n\n test(\"constructor throws when cdm.json has no targets\", () => {\n const emptyCdm: CdmJson = { targets: {}, dependencies: {} };\n expect(() => new ContractManager(emptyCdm, fakeInkSdk())).toThrow(/No targets found/);\n });\n });\n\n describe(\"ContractManager defaults\", () => {\n test(\"setDefaults updates origin / signer / signerManager mid-flight\", () => {\n const manager = new ContractManager(playgroundCdm, fakeInkSdk(), {\n defaultOrigin: \"5OldOrigin\" as HexString,\n });\n // This is a behavioral check via private-ish field — we don't\n // expose `defaults` directly, but `setDefaults` returning\n // without error is the contract.\n expect(() => manager.setDefaults({ origin: \"5NewOrigin\" as HexString })).not.toThrow();\n });\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parity/product-sdk-contracts",
|
|
3
3
|
"description": "Typed contract interactions on Polkadot Asset Hub",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@polkadot-api/sdk-ink": "^0.
|
|
26
|
+
"@polkadot-api/sdk-ink": "^0.7.0",
|
|
27
27
|
"@polkadot-labs/hdkd-helpers": "^0.0.27",
|
|
28
|
-
"polkadot-api": "^1.
|
|
29
|
-
"@parity/product-sdk-
|
|
30
|
-
"@parity/product-sdk-
|
|
31
|
-
"@parity/product-sdk-
|
|
32
|
-
"@parity/product-sdk-
|
|
28
|
+
"polkadot-api": "^2.1.2",
|
|
29
|
+
"@parity/product-sdk-keys": "0.2.0",
|
|
30
|
+
"@parity/product-sdk-logger": "0.1.1",
|
|
31
|
+
"@parity/product-sdk-tx": "0.2.0",
|
|
32
|
+
"@parity/product-sdk-signer": "0.2.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsup": "^8.4.0",
|