@parity/product-sdk-contracts 0.2.2 → 0.4.0
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 +63 -15
- package/dist/chunk-YZ3YBERU.js +53 -0
- package/dist/chunk-YZ3YBERU.js.map +1 -0
- package/dist/codegen.d.ts +62 -1
- package/dist/codegen.js +81 -1
- package/dist/codegen.js.map +1 -1
- package/dist/index.d.ts +230 -50
- package/dist/index.js +192 -79
- package/dist/index.js.map +1 -1
- package/dist/pvm.d.ts +52 -0
- package/dist/pvm.js +3 -0
- package/dist/pvm.js.map +1 -0
- package/dist/{codegen-BPDBGrJC.d.ts → types-DJDMz91q.d.ts} +21 -37
- package/package.json +10 -5
- package/dist/chunk-E7AP65D4.js +0 -73
- package/dist/chunk-E7AP65D4.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import { submitAndWatch } from '@parity/product-sdk-tx';
|
|
1
|
+
import { encodeFunctionData, decodeFunctionResult } from 'viem';
|
|
2
|
+
import { ensureAccountMapped, submitAndWatch } from '@parity/product-sdk-tx';
|
|
3
3
|
import { seedToAccount } from '@parity/product-sdk-keys';
|
|
4
4
|
import { createLogger } from '@parity/product-sdk-logger';
|
|
5
5
|
import { DEV_PHRASE, ss58Address } from '@polkadot-labs/hdkd-helpers';
|
|
6
|
+
import { ss58ToH160 } from '@parity/product-sdk-address';
|
|
7
|
+
|
|
8
|
+
// src/wrap.ts
|
|
6
9
|
|
|
7
10
|
// src/errors.ts
|
|
8
11
|
var ContractError = class extends Error {
|
|
@@ -29,6 +32,18 @@ var ContractNotFoundError = class extends ContractError {
|
|
|
29
32
|
this.targetHash = targetHash;
|
|
30
33
|
}
|
|
31
34
|
};
|
|
35
|
+
var ContractDryRunFailedError = class extends ContractError {
|
|
36
|
+
methodName;
|
|
37
|
+
dispatchError;
|
|
38
|
+
constructor(methodName, dispatchError) {
|
|
39
|
+
super(
|
|
40
|
+
`Dry-run failed for "${methodName}": ${typeof dispatchError === "string" ? dispatchError : JSON.stringify(dispatchError)}. The transaction was not submitted.`
|
|
41
|
+
);
|
|
42
|
+
this.name = "ContractDryRunFailedError";
|
|
43
|
+
this.methodName = methodName;
|
|
44
|
+
this.dispatchError = dispatchError;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
32
47
|
|
|
33
48
|
// src/wrap.ts
|
|
34
49
|
var log = createLogger("contracts");
|
|
@@ -41,13 +56,6 @@ function buildMethodArgMap(abi) {
|
|
|
41
56
|
}
|
|
42
57
|
return map;
|
|
43
58
|
}
|
|
44
|
-
function positionalToNamed(argNames, values) {
|
|
45
|
-
const data = {};
|
|
46
|
-
for (let i = 0; i < argNames.length; i++) {
|
|
47
|
-
data[argNames[i]] = values[i];
|
|
48
|
-
}
|
|
49
|
-
return data;
|
|
50
|
-
}
|
|
51
59
|
function extractOverrides(argNames, args) {
|
|
52
60
|
if (args.length > argNames.length && args.length > 0) {
|
|
53
61
|
const last = args[args.length - 1];
|
|
@@ -72,8 +80,81 @@ function resolveOrigin(defaults, override, forQuery) {
|
|
|
72
80
|
function resolveSigner(defaults, override) {
|
|
73
81
|
return override ?? defaults.signerManager?.getSigner() ?? defaults.signer;
|
|
74
82
|
}
|
|
75
|
-
function
|
|
83
|
+
function normalizeContractAddress(address) {
|
|
84
|
+
const hex = address.startsWith("0x") ? address.slice(2) : address;
|
|
85
|
+
if (hex.length !== 40) {
|
|
86
|
+
throw new Error(`Expected 20-byte H160 contract address, got ${hex.length / 2} bytes`);
|
|
87
|
+
}
|
|
88
|
+
return `0x${hex.toLowerCase()}`;
|
|
89
|
+
}
|
|
90
|
+
function hexToBytes(hex) {
|
|
91
|
+
const stripped = hex.slice(2);
|
|
92
|
+
const out = new Uint8Array(stripped.length / 2);
|
|
93
|
+
for (let i = 0; i < out.length; i++) {
|
|
94
|
+
out[i] = Number.parseInt(stripped.slice(i * 2, i * 2 + 2), 16);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
function encodeCalldata(abi, methodName, args) {
|
|
99
|
+
return encodeFunctionData({
|
|
100
|
+
abi,
|
|
101
|
+
functionName: methodName,
|
|
102
|
+
args
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function decodeReturn(abi, methodName, returnData) {
|
|
106
|
+
if (returnData.byteLength === 0) return void 0;
|
|
107
|
+
let hex = "0x";
|
|
108
|
+
for (let i = 0; i < returnData.byteLength; i++) {
|
|
109
|
+
hex += returnData[i].toString(16).padStart(2, "0");
|
|
110
|
+
}
|
|
111
|
+
const decoded = decodeFunctionResult({
|
|
112
|
+
abi,
|
|
113
|
+
functionName: methodName,
|
|
114
|
+
data: hex
|
|
115
|
+
});
|
|
116
|
+
const entry = abi.find((e) => e.type === "function" && e.name === methodName);
|
|
117
|
+
const outputs = entry?.outputs ?? [];
|
|
118
|
+
if (outputs.length <= 1 || !Array.isArray(decoded)) return decoded;
|
|
119
|
+
const obj = {};
|
|
120
|
+
for (let i = 0; i < outputs.length; i++) {
|
|
121
|
+
obj[outputs[i].name || `_${i}`] = decoded[i];
|
|
122
|
+
}
|
|
123
|
+
return obj;
|
|
124
|
+
}
|
|
125
|
+
async function buildReviveCall(runtime, dest, abi, methodName, positionalArgs, origin, overrides) {
|
|
126
|
+
const value = overrides?.value ?? 0n;
|
|
127
|
+
const calldata = hexToBytes(encodeCalldata(abi, methodName, positionalArgs));
|
|
128
|
+
let weightLimit = overrides?.gasLimit;
|
|
129
|
+
let storageDepositLimit = overrides?.storageDepositLimit;
|
|
130
|
+
if (weightLimit === void 0 || storageDepositLimit === void 0) {
|
|
131
|
+
const dryRun = await runtime.dryRunCall(
|
|
132
|
+
origin,
|
|
133
|
+
dest,
|
|
134
|
+
value,
|
|
135
|
+
void 0,
|
|
136
|
+
void 0,
|
|
137
|
+
calldata
|
|
138
|
+
);
|
|
139
|
+
if (!dryRun.result.success) {
|
|
140
|
+
throw new ContractDryRunFailedError(methodName, dryRun.result.value);
|
|
141
|
+
}
|
|
142
|
+
weightLimit = weightLimit ?? dryRun.weight_required;
|
|
143
|
+
if (storageDepositLimit === void 0) {
|
|
144
|
+
storageDepositLimit = dryRun.storage_deposit.type === "Charge" ? dryRun.storage_deposit.value : 0n;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return runtime.api.tx.Revive.call({
|
|
148
|
+
dest,
|
|
149
|
+
value,
|
|
150
|
+
weight_limit: weightLimit,
|
|
151
|
+
storage_deposit_limit: storageDepositLimit,
|
|
152
|
+
data: calldata
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function wrapContract(runtime, address, abi, defaults) {
|
|
76
156
|
const methodArgs = buildMethodArgMap(abi);
|
|
157
|
+
const dest = normalizeContractAddress(address);
|
|
77
158
|
return new Proxy({}, {
|
|
78
159
|
get(_, methodName) {
|
|
79
160
|
if (typeof methodName !== "string") return void 0;
|
|
@@ -85,17 +166,29 @@ function wrapContract(inkContract, abi, defaults) {
|
|
|
85
166
|
argNames,
|
|
86
167
|
args
|
|
87
168
|
);
|
|
88
|
-
const data = positionalToNamed(argNames, positionalArgs);
|
|
89
169
|
const origin = resolveOrigin(defaults, overrides?.origin, true);
|
|
90
|
-
const
|
|
170
|
+
const value = overrides?.value ?? 0n;
|
|
171
|
+
const calldata = hexToBytes(encodeCalldata(abi, methodName, positionalArgs));
|
|
172
|
+
const dryRun = await runtime.dryRunCall(
|
|
91
173
|
origin,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
174
|
+
dest,
|
|
175
|
+
value,
|
|
176
|
+
void 0,
|
|
177
|
+
void 0,
|
|
178
|
+
calldata
|
|
179
|
+
);
|
|
180
|
+
if (!dryRun.result.success) {
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
value: void 0,
|
|
184
|
+
gasRequired: dryRun.weight_required
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const decoded = decodeReturn(abi, methodName, dryRun.result.value.data);
|
|
95
188
|
return {
|
|
96
|
-
success:
|
|
97
|
-
value:
|
|
98
|
-
gasRequired:
|
|
189
|
+
success: true,
|
|
190
|
+
value: decoded,
|
|
191
|
+
gasRequired: dryRun.weight_required
|
|
99
192
|
};
|
|
100
193
|
},
|
|
101
194
|
tx: async (...args) => {
|
|
@@ -103,59 +196,82 @@ function wrapContract(inkContract, abi, defaults) {
|
|
|
103
196
|
argNames,
|
|
104
197
|
args
|
|
105
198
|
);
|
|
106
|
-
const data = positionalToNamed(argNames, positionalArgs);
|
|
107
199
|
const signer = resolveSigner(defaults, overrides?.signer);
|
|
108
200
|
if (!signer) {
|
|
109
201
|
throw new ContractSignerMissingError();
|
|
110
202
|
}
|
|
111
203
|
const origin = resolveOrigin(defaults, overrides?.origin) ?? ss58Address(signer.publicKey);
|
|
112
|
-
const
|
|
113
|
-
|
|
204
|
+
const tx = await buildReviveCall(
|
|
205
|
+
runtime,
|
|
206
|
+
dest,
|
|
207
|
+
abi,
|
|
208
|
+
methodName,
|
|
209
|
+
positionalArgs,
|
|
114
210
|
origin,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
storageDepositLimit: overrides.storageDepositLimit
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
return submitAndWatch(inkTx, signer, {
|
|
211
|
+
overrides
|
|
212
|
+
);
|
|
213
|
+
return submitAndWatch(tx, signer, {
|
|
122
214
|
waitFor: overrides?.waitFor,
|
|
123
215
|
timeoutMs: overrides?.timeoutMs,
|
|
124
216
|
mortalityPeriod: overrides?.mortalityPeriod,
|
|
125
217
|
onStatus: overrides?.onStatus
|
|
126
218
|
});
|
|
127
219
|
},
|
|
128
|
-
prepare: (...args) => {
|
|
220
|
+
prepare: async (...args) => {
|
|
129
221
|
const { positionalArgs, overrides } = extractOverrides(
|
|
130
222
|
argNames,
|
|
131
223
|
args
|
|
132
224
|
);
|
|
133
|
-
const data = positionalToNamed(argNames, positionalArgs);
|
|
134
225
|
const origin = resolveOrigin(defaults, overrides?.origin, true);
|
|
135
|
-
return
|
|
136
|
-
|
|
226
|
+
return buildReviveCall(
|
|
227
|
+
runtime,
|
|
228
|
+
dest,
|
|
229
|
+
abi,
|
|
230
|
+
methodName,
|
|
231
|
+
positionalArgs,
|
|
137
232
|
origin,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
...overrides?.storageDepositLimit !== void 0 && {
|
|
141
|
-
storageDepositLimit: overrides.storageDepositLimit
|
|
142
|
-
}
|
|
143
|
-
});
|
|
233
|
+
overrides
|
|
234
|
+
);
|
|
144
235
|
}
|
|
145
236
|
};
|
|
146
237
|
}
|
|
147
238
|
});
|
|
148
239
|
}
|
|
240
|
+
function createContractRuntime(api) {
|
|
241
|
+
return {
|
|
242
|
+
api,
|
|
243
|
+
dryRunCall: (origin, dest, value, gas, deposit, data) => api.apis.ReviveApi.call(origin, dest, value, gas, deposit, data)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function createContractRuntimeFromClient(client, descriptor) {
|
|
247
|
+
const typed = client.getTypedApi(
|
|
248
|
+
descriptor
|
|
249
|
+
);
|
|
250
|
+
const unsafe = client.getUnsafeApi();
|
|
251
|
+
return {
|
|
252
|
+
api: typed,
|
|
253
|
+
dryRunCall: (origin, dest, value, gas, deposit, data) => unsafe.apis.ReviveApi.call(origin, dest, value, gas, deposit, data)
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
async function ensureContractAccountMapped(runtime, address, signer, options) {
|
|
257
|
+
const checker = {
|
|
258
|
+
addressIsMapped: async (addr) => {
|
|
259
|
+
const h160 = ss58ToH160(addr);
|
|
260
|
+
return await runtime.api.query.Revive.OriginalAccount.getValue(h160) !== void 0;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
return ensureAccountMapped(address, signer, checker, runtime.api, options);
|
|
264
|
+
}
|
|
149
265
|
|
|
150
266
|
// src/manager.ts
|
|
151
267
|
var ContractManager = class _ContractManager {
|
|
152
268
|
cdmJson;
|
|
153
269
|
targetHash;
|
|
154
|
-
|
|
270
|
+
runtime;
|
|
155
271
|
defaults;
|
|
156
|
-
constructor(cdmJson,
|
|
272
|
+
constructor(cdmJson, runtime, options) {
|
|
157
273
|
this.cdmJson = cdmJson;
|
|
158
|
-
this.
|
|
274
|
+
this.runtime = runtime;
|
|
159
275
|
if (options?.targetHash) {
|
|
160
276
|
this.targetHash = options.targetHash;
|
|
161
277
|
} else {
|
|
@@ -177,38 +293,24 @@ var ContractManager = class _ContractManager {
|
|
|
177
293
|
if (defaults.signer !== void 0) this.defaults.signer = defaults.signer;
|
|
178
294
|
}
|
|
179
295
|
/**
|
|
180
|
-
* Create a ContractManager from a raw `PolkadotClient`.
|
|
296
|
+
* Create a `ContractManager` from a raw `PolkadotClient`.
|
|
181
297
|
*
|
|
182
|
-
* Convenience factory
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* For size-sensitive apps, prefer the constructor with a pre-created `InkSdk`
|
|
187
|
-
* to control exactly when `@polkadot-api/sdk-ink` is loaded.
|
|
298
|
+
* Convenience factory: builds a `ContractRuntime` internally from the
|
|
299
|
+
* client's typed API. Requires that the chain's typed API exposes the
|
|
300
|
+
* `Revive` pallet and `ReviveApi` runtime API (Asset Hub Paseo /
|
|
301
|
+
* Polkadot / Kusama).
|
|
188
302
|
*
|
|
189
303
|
* @param cdmJson - The CDM manifest.
|
|
190
|
-
* @param client - A `PolkadotClient` for the chain where contracts are deployed
|
|
304
|
+
* @param client - A `PolkadotClient` for the chain where contracts are deployed.
|
|
305
|
+
* @param descriptor - The chain descriptor used to derive the typed API.
|
|
191
306
|
* @param options - Optional configuration (signerManager, defaults).
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```ts
|
|
195
|
-
* import { createChainClient } from "@parity/product-sdk-chain-client";
|
|
196
|
-
* import { paseo_asset_hub } from "@parity/product-sdk-descriptors/paseo-asset-hub";
|
|
197
|
-
* import { ContractManager } from "@parity/product-sdk-contracts";
|
|
198
|
-
*
|
|
199
|
-
* const client = await createChainClient({
|
|
200
|
-
* chains: { assetHub: paseo_asset_hub },
|
|
201
|
-
* rpcs: { assetHub: ["wss://sys.ibp.network/asset-hub-paseo"] },
|
|
202
|
-
* });
|
|
203
|
-
* const manager = await ContractManager.fromClient(cdmJson, client.raw.assetHub, {
|
|
204
|
-
* signerManager,
|
|
205
|
-
* });
|
|
206
|
-
* ```
|
|
207
307
|
*/
|
|
208
|
-
static
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
308
|
+
static fromClient(cdmJson, client, descriptor, options) {
|
|
309
|
+
return new _ContractManager(
|
|
310
|
+
cdmJson,
|
|
311
|
+
createContractRuntimeFromClient(client, descriptor),
|
|
312
|
+
options
|
|
313
|
+
);
|
|
212
314
|
}
|
|
213
315
|
getContractData(library) {
|
|
214
316
|
const contractsForTarget = this.cdmJson.contracts?.[this.targetHash];
|
|
@@ -219,30 +321,41 @@ var ContractManager = class _ContractManager {
|
|
|
219
321
|
}
|
|
220
322
|
getContract(library) {
|
|
221
323
|
const data = this.getContractData(library);
|
|
222
|
-
|
|
223
|
-
const inkContract = this.inkSdk.getContract(descriptor, data.address);
|
|
224
|
-
return wrapContract(inkContract, data.abi, this.defaults);
|
|
324
|
+
return wrapContract(this.runtime, data.address, data.abi, this.defaults);
|
|
225
325
|
}
|
|
226
326
|
/** Get the on-chain address of an installed contract. */
|
|
227
327
|
getAddress(library) {
|
|
228
328
|
return this.getContractData(library).address;
|
|
229
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Get the underlying {@link ContractRuntime} backing this manager.
|
|
332
|
+
*
|
|
333
|
+
* Useful when a consumer needs to call helpers that take a runtime
|
|
334
|
+
* directly — most commonly {@link ensureContractAccountMapped} at app
|
|
335
|
+
* boot. Avoids the alternative of building a second runtime against the
|
|
336
|
+
* same client and descriptor.
|
|
337
|
+
*/
|
|
338
|
+
getRuntime() {
|
|
339
|
+
return this.runtime;
|
|
340
|
+
}
|
|
230
341
|
};
|
|
231
|
-
function createContract(
|
|
232
|
-
const inkContract = inkSdk.getContract({ abi }, address);
|
|
342
|
+
function createContract(runtime, address, abi, options) {
|
|
233
343
|
const defaults = {
|
|
234
344
|
signerManager: options?.signerManager,
|
|
235
345
|
origin: options?.defaultOrigin,
|
|
236
346
|
signer: options?.defaultSigner
|
|
237
347
|
};
|
|
238
|
-
return wrapContract(
|
|
348
|
+
return wrapContract(runtime, address, abi, defaults);
|
|
239
349
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
350
|
+
function createContractFromClient(client, descriptor, address, abi, options) {
|
|
351
|
+
return createContract(
|
|
352
|
+
createContractRuntimeFromClient(client, descriptor),
|
|
353
|
+
address,
|
|
354
|
+
abi,
|
|
355
|
+
options
|
|
356
|
+
);
|
|
244
357
|
}
|
|
245
358
|
|
|
246
|
-
export { ContractError, ContractManager, ContractNotFoundError, ContractSignerMissingError, createContract, createContractFromClient };
|
|
359
|
+
export { ContractDryRunFailedError, ContractError, ContractManager, ContractNotFoundError, ContractSignerMissingError, createContract, createContractFromClient, createContractRuntime, createContractRuntimeFromClient, ensureContractAccountMapped };
|
|
247
360
|
//# sourceMappingURL=index.js.map
|
|
248
361
|
//# sourceMappingURL=index.js.map
|