@parity/product-sdk-contracts 0.0.0-dev.312.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/dist/index.js ADDED
@@ -0,0 +1,630 @@
1
+ import { ok, err } from '@parity/result';
2
+ import { isValidH160, ss58ToH160, isValidSs58 } from '@parity/product-sdk-address';
3
+ import { createLogger } from '@parity/product-sdk-logger';
4
+ import { ensureAccountMapped, submitAndWatch } from '@parity/product-sdk-tx';
5
+ import { ss58Address } from '@polkadot-labs/hdkd-helpers';
6
+ import { encodeFunctionData, bytesToHex, decodeErrorResult, decodeFunctionResult } from 'viem';
7
+
8
+ // src/manager.ts
9
+ var ContractError = class extends Error {
10
+ isSdkError = true;
11
+ source = "contracts";
12
+ constructor(message, options) {
13
+ super(message, options);
14
+ this.name = "ContractError";
15
+ }
16
+ };
17
+ var ContractSignerMissingError = class extends ContractError {
18
+ constructor() {
19
+ super(
20
+ "No signer available. Pass { signer } in call options, set defaultSigner, or provide a signerManager."
21
+ );
22
+ this.name = "ContractSignerMissingError";
23
+ }
24
+ };
25
+ var ContractNotFoundError = class extends ContractError {
26
+ library;
27
+ constructor(library) {
28
+ super(`Contract "${library}" not found in cdm.json`);
29
+ this.name = "ContractNotFoundError";
30
+ this.library = library;
31
+ }
32
+ };
33
+ var ContractInvalidOriginError = class extends ContractError {
34
+ /** The rejected origin value. */
35
+ origin;
36
+ constructor(origin) {
37
+ const h160Hint = isValidH160(origin) ? " (looks like an H160 \u2014 convert it with h160ToSs58 from @parity/product-sdk-address first)" : "";
38
+ super(`Contract call origin must be an SS58 address, got "${origin}"${h160Hint}`);
39
+ this.name = "ContractInvalidOriginError";
40
+ this.origin = origin;
41
+ }
42
+ };
43
+ var ContractLiveAddressResolutionError = class extends ContractError {
44
+ library;
45
+ detail;
46
+ constructor(message, options) {
47
+ super(message, options?.cause !== void 0 ? { cause: options.cause } : void 0);
48
+ this.name = "ContractLiveAddressResolutionError";
49
+ this.library = options?.library;
50
+ this.detail = options?.detail;
51
+ }
52
+ };
53
+ var ContractDryRunFailedError = class extends ContractError {
54
+ methodName;
55
+ dispatchError;
56
+ constructor(methodName, dispatchError) {
57
+ super(
58
+ `Dry-run failed for "${methodName}": ${typeof dispatchError === "string" ? dispatchError : JSON.stringify(dispatchError)}. The transaction was not submitted.`
59
+ );
60
+ this.name = "ContractDryRunFailedError";
61
+ this.methodName = methodName;
62
+ this.dispatchError = dispatchError;
63
+ }
64
+ };
65
+ function stringifyArg(arg) {
66
+ if (typeof arg === "bigint") return arg.toString();
67
+ return JSON.stringify(arg, (_, v) => typeof v === "bigint" ? v.toString() : v);
68
+ }
69
+ var ContractRevertedError = class extends ContractError {
70
+ methodName;
71
+ data;
72
+ reason;
73
+ decoded;
74
+ constructor(methodName, data, info) {
75
+ const suffix = info?.reason ?? (info?.decoded ? `${info.decoded.errorName}(${(info.decoded.args ?? []).map(stringifyArg).join(", ")})` : data);
76
+ super(
77
+ `Contract reverted in "${methodName}": ${suffix}. The transaction was not submitted.`
78
+ );
79
+ this.name = "ContractRevertedError";
80
+ this.methodName = methodName;
81
+ this.data = data;
82
+ this.reason = info?.reason;
83
+ this.decoded = info?.decoded;
84
+ }
85
+ };
86
+ var log = createLogger("contracts");
87
+ function buildMethodArgMap(abi) {
88
+ const map = {};
89
+ for (const entry of abi) {
90
+ if (entry.type === "function" && entry.name) {
91
+ map[entry.name] = entry.inputs.map((p) => p.name);
92
+ }
93
+ }
94
+ return map;
95
+ }
96
+ function extractOverrides(argNames, args) {
97
+ if (args.length > argNames.length && args.length > 0) {
98
+ const last = args[args.length - 1];
99
+ if (last && typeof last === "object" && !Array.isArray(last)) {
100
+ return { positionalArgs: args.slice(0, -1), overrides: last };
101
+ }
102
+ }
103
+ return { positionalArgs: args };
104
+ }
105
+ var REVIVE_PALLET_ACCOUNT = new Uint8Array(32);
106
+ REVIVE_PALLET_ACCOUNT.set(new TextEncoder().encode("modlpy/reviv"));
107
+ var QUERY_FALLBACK_ORIGIN = ss58Address(REVIVE_PALLET_ACCOUNT);
108
+ function resolveOrigin(defaults, override, forQuery) {
109
+ if (override) return override;
110
+ const sourceAddr = defaults.signerManager?.getState().selectedAccount?.address;
111
+ if (sourceAddr) return sourceAddr;
112
+ if (defaults.origin) return defaults.origin;
113
+ if (forQuery) {
114
+ log.warn("No origin configured \u2014 using pallet-revive account fallback for query dry-run");
115
+ return QUERY_FALLBACK_ORIGIN;
116
+ }
117
+ return void 0;
118
+ }
119
+ function resolveSigner(defaults, override) {
120
+ return override ?? defaults.signerManager?.getSigner() ?? defaults.signer;
121
+ }
122
+ function validateOrigin(origin) {
123
+ return isValidSs58(origin) ? null : new ContractInvalidOriginError(origin);
124
+ }
125
+ function normalizeContractAddress(address) {
126
+ const hex = address.startsWith("0x") ? address.slice(2) : address;
127
+ if (hex.length !== 40) {
128
+ throw new Error(`Expected 20-byte H160 contract address, got ${hex.length / 2} bytes`);
129
+ }
130
+ return `0x${hex.toLowerCase()}`;
131
+ }
132
+ function hexToBytes(hex) {
133
+ const stripped = hex.slice(2);
134
+ const out = new Uint8Array(stripped.length / 2);
135
+ for (let i = 0; i < out.length; i++) {
136
+ out[i] = Number.parseInt(stripped.slice(i * 2, i * 2 + 2), 16);
137
+ }
138
+ return out;
139
+ }
140
+ var REVERT_FLAG = 1;
141
+ var PANIC_REASONS = {
142
+ "0x01": "assertion failed",
143
+ "0x11": "arithmetic overflow",
144
+ "0x12": "division by zero",
145
+ "0x21": "invalid enum value",
146
+ "0x22": "improperly encoded storage byte array",
147
+ "0x31": "pop on empty array",
148
+ "0x32": "array index out of bounds",
149
+ "0x41": "memory allocation overflow",
150
+ "0x51": "call to uninitialized internal function"
151
+ };
152
+ function decodeRevert(abi, data) {
153
+ const hex = bytesToHex(data);
154
+ const info = {
155
+ type: "ContractRevertedWithPayload",
156
+ data: hex
157
+ };
158
+ if (data.byteLength === 0) return info;
159
+ try {
160
+ const decoded = decodeErrorResult({
161
+ abi,
162
+ data: hex
163
+ });
164
+ info.decoded = {
165
+ errorName: decoded.errorName,
166
+ args: decoded.args
167
+ };
168
+ if (decoded.errorName === "Error" && typeof decoded.args?.[0] === "string") {
169
+ info.reason = decoded.args[0];
170
+ } else if (decoded.errorName === "Panic" && typeof decoded.args?.[0] === "bigint") {
171
+ const code = `0x${decoded.args[0].toString(16).padStart(2, "0")}`;
172
+ info.reason = PANIC_REASONS[code] ? `Panic: ${PANIC_REASONS[code]}` : `Panic(${code})`;
173
+ }
174
+ return info;
175
+ } catch {
176
+ try {
177
+ info.reason = new TextDecoder("utf-8", { fatal: true }).decode(data);
178
+ } catch {
179
+ }
180
+ return info;
181
+ }
182
+ }
183
+ function encodeCalldata(abi, methodName, args) {
184
+ return encodeFunctionData({
185
+ abi,
186
+ functionName: methodName,
187
+ args
188
+ });
189
+ }
190
+ function decodeReturn(abi, methodName, returnData) {
191
+ if (returnData.byteLength === 0) return void 0;
192
+ const decoded = decodeFunctionResult({
193
+ abi,
194
+ functionName: methodName,
195
+ data: bytesToHex(returnData)
196
+ });
197
+ const entry = abi.find((e) => e.type === "function" && e.name === methodName);
198
+ const outputs = entry?.outputs ?? [];
199
+ if (outputs.length <= 1 || !Array.isArray(decoded)) return decoded;
200
+ const obj = {};
201
+ for (let i = 0; i < outputs.length; i++) {
202
+ obj[outputs[i].name || `_${i}`] = decoded[i];
203
+ }
204
+ return obj;
205
+ }
206
+ async function buildReviveCall(runtime, dest, abi, methodName, positionalArgs, origin, overrides) {
207
+ const value = overrides?.value ?? 0n;
208
+ const calldata = hexToBytes(encodeCalldata(abi, methodName, positionalArgs));
209
+ let weightLimit = overrides?.gasLimit;
210
+ let storageDepositLimit = overrides?.storageDepositLimit;
211
+ if (weightLimit === void 0 || storageDepositLimit === void 0) {
212
+ const dryRun = await runtime.dryRunCall(
213
+ origin,
214
+ dest,
215
+ value,
216
+ void 0,
217
+ void 0,
218
+ calldata,
219
+ overrides?.at !== void 0 ? { at: overrides.at } : void 0
220
+ );
221
+ if (!dryRun.result.success) {
222
+ return err(new ContractDryRunFailedError(methodName, dryRun.result.value));
223
+ }
224
+ if ((dryRun.result.value.flags & REVERT_FLAG) !== 0) {
225
+ const { data, reason, decoded } = decodeRevert(abi, dryRun.result.value.data);
226
+ log.debug("Contract reverted", { methodName, reason, errorName: decoded?.errorName });
227
+ return err(new ContractRevertedError(methodName, data, { reason, decoded }));
228
+ }
229
+ weightLimit = weightLimit ?? dryRun.weight_required;
230
+ if (storageDepositLimit === void 0) {
231
+ storageDepositLimit = dryRun.storage_deposit.type === "Charge" ? dryRun.storage_deposit.value : 0n;
232
+ }
233
+ }
234
+ return ok(
235
+ runtime.api.tx.Revive.call({
236
+ dest,
237
+ value,
238
+ weight_limit: weightLimit,
239
+ storage_deposit_limit: storageDepositLimit,
240
+ data: calldata
241
+ })
242
+ );
243
+ }
244
+ function wrapContract(runtime, address, abi, defaults) {
245
+ const methodArgs = buildMethodArgMap(abi);
246
+ const dest = normalizeContractAddress(address);
247
+ return new Proxy({}, {
248
+ get(_, methodName) {
249
+ if (typeof methodName !== "string") return void 0;
250
+ const argNames = methodArgs[methodName];
251
+ if (!argNames) return void 0;
252
+ return {
253
+ query: async (...args) => {
254
+ const { positionalArgs, overrides } = extractOverrides(
255
+ argNames,
256
+ args
257
+ );
258
+ const origin = resolveOrigin(defaults, overrides?.origin, true);
259
+ const originError = validateOrigin(origin);
260
+ if (originError) throw originError;
261
+ const value = overrides?.value ?? 0n;
262
+ const calldata = hexToBytes(encodeCalldata(abi, methodName, positionalArgs));
263
+ const dryRun = await runtime.dryRunCall(
264
+ origin,
265
+ dest,
266
+ value,
267
+ void 0,
268
+ void 0,
269
+ calldata,
270
+ overrides?.at !== void 0 ? { at: overrides.at } : void 0
271
+ );
272
+ if (!dryRun.result.success) {
273
+ return {
274
+ success: false,
275
+ value: dryRun.result.value,
276
+ gasRequired: dryRun.weight_required
277
+ };
278
+ }
279
+ if ((dryRun.result.value.flags & REVERT_FLAG) !== 0) {
280
+ const info = decodeRevert(abi, dryRun.result.value.data);
281
+ log.debug("Contract reverted", {
282
+ methodName,
283
+ reason: info.reason,
284
+ errorName: info.decoded?.errorName
285
+ });
286
+ return {
287
+ success: false,
288
+ value: info,
289
+ gasRequired: dryRun.weight_required
290
+ };
291
+ }
292
+ const decoded = decodeReturn(abi, methodName, dryRun.result.value.data);
293
+ return {
294
+ success: true,
295
+ value: decoded,
296
+ gasRequired: dryRun.weight_required
297
+ };
298
+ },
299
+ tx: async (...args) => {
300
+ const { positionalArgs, overrides } = extractOverrides(
301
+ argNames,
302
+ args
303
+ );
304
+ const signer = resolveSigner(defaults, overrides?.signer);
305
+ if (!signer) {
306
+ return err(new ContractSignerMissingError());
307
+ }
308
+ const origin = resolveOrigin(defaults, overrides?.origin) ?? ss58Address(signer.publicKey);
309
+ const originError = validateOrigin(origin);
310
+ if (originError) return err(originError);
311
+ const built = await buildReviveCall(
312
+ runtime,
313
+ dest,
314
+ abi,
315
+ methodName,
316
+ positionalArgs,
317
+ origin,
318
+ overrides
319
+ );
320
+ if (!built.ok) return built;
321
+ return submitAndWatch(built.value, signer, {
322
+ waitFor: overrides?.waitFor,
323
+ timeoutMs: overrides?.timeoutMs,
324
+ mortalityPeriod: overrides?.mortalityPeriod,
325
+ onStatus: overrides?.onStatus
326
+ });
327
+ },
328
+ prepare: async (...args) => {
329
+ const { positionalArgs, overrides } = extractOverrides(
330
+ argNames,
331
+ args
332
+ );
333
+ const origin = resolveOrigin(defaults, overrides?.origin, true);
334
+ const originError = validateOrigin(origin);
335
+ if (originError) return err(originError);
336
+ return buildReviveCall(
337
+ runtime,
338
+ dest,
339
+ abi,
340
+ methodName,
341
+ positionalArgs,
342
+ origin,
343
+ overrides
344
+ );
345
+ }
346
+ };
347
+ }
348
+ });
349
+ }
350
+ function createContractRuntime(api, options) {
351
+ const defaultAt = options?.at ?? "best";
352
+ return {
353
+ api,
354
+ dryRunCall: (origin, dest, value, gas, deposit, data, callOpts) => api.apis.ReviveApi.call(origin, dest, value, gas, deposit, data, {
355
+ at: callOpts?.at ?? defaultAt
356
+ })
357
+ };
358
+ }
359
+ function createContractRuntimeFromClient(client, descriptor, options) {
360
+ const defaultAt = options?.at ?? "best";
361
+ const typed = client.getTypedApi(
362
+ descriptor
363
+ );
364
+ const unsafe = client.getUnsafeApi();
365
+ return {
366
+ api: typed,
367
+ dryRunCall: (origin, dest, value, gas, deposit, data, callOpts) => unsafe.apis.ReviveApi.call(origin, dest, value, gas, deposit, data, {
368
+ at: callOpts?.at ?? defaultAt
369
+ })
370
+ };
371
+ }
372
+ async function ensureContractAccountMapped(runtime, address, signer, options) {
373
+ const checker = {
374
+ addressIsMapped: async (addr) => {
375
+ const mapped = await isContractAccountMapped(runtime, addr);
376
+ if (!mapped.ok) throw mapped.error;
377
+ return mapped.value;
378
+ }
379
+ };
380
+ return ensureAccountMapped(address, signer, checker, runtime.api, options);
381
+ }
382
+ async function isContractAccountMapped(runtime, address) {
383
+ try {
384
+ const h160 = ss58ToH160(address);
385
+ const mapped = await runtime.api.query.Revive.OriginalAccount.getValue(h160) !== void 0;
386
+ return ok(mapped);
387
+ } catch (cause) {
388
+ return err(
389
+ new ContractError(`Failed to check pallet-revive mapping for ${address}`, { cause })
390
+ );
391
+ }
392
+ }
393
+
394
+ // src/manager.ts
395
+ var CDM_REGISTRY_ABI = [
396
+ {
397
+ type: "function",
398
+ name: "getAddress",
399
+ inputs: [{ name: "contract_name", type: "string" }],
400
+ outputs: [
401
+ {
402
+ name: "",
403
+ type: "tuple",
404
+ components: [
405
+ { name: "isSome", type: "bool" },
406
+ { name: "value", type: "address" }
407
+ ]
408
+ }
409
+ ],
410
+ stateMutability: "view"
411
+ },
412
+ {
413
+ type: "function",
414
+ name: "getAddressAtVersion",
415
+ inputs: [
416
+ { name: "contract_name", type: "string" },
417
+ { name: "version", type: "uint32" }
418
+ ],
419
+ outputs: [
420
+ {
421
+ name: "",
422
+ type: "tuple",
423
+ components: [
424
+ { name: "isSome", type: "bool" },
425
+ { name: "value", type: "address" }
426
+ ]
427
+ }
428
+ ],
429
+ stateMutability: "view"
430
+ }
431
+ ];
432
+ function cloneCdmJson(cdmJson) {
433
+ const cloneContractMap = (contracts) => Object.fromEntries(
434
+ Object.entries(contracts).map(([library, contract]) => [library, { ...contract }])
435
+ );
436
+ return {
437
+ ...cdmJson,
438
+ dependencies: { ...cdmJson.dependencies },
439
+ contracts: cdmJson.contracts ? cloneContractMap(cdmJson.contracts) : void 0
440
+ };
441
+ }
442
+ function resolveRegistryAddress(cdmJson, override) {
443
+ if (override) return override;
444
+ if (cdmJson.registry) return cdmJson.registry;
445
+ throw new ContractLiveAddressResolutionError(
446
+ "CDM registry address is required for live contract address resolution. Pass registryAddress or set cdm.json registry."
447
+ );
448
+ }
449
+ function patchContractAddress(cdmJson, library, address) {
450
+ const contract = cdmJson.contracts?.[library];
451
+ if (!contract) {
452
+ throw new ContractNotFoundError(library);
453
+ }
454
+ contract.address = address;
455
+ }
456
+ function resolveLiveVersionSpec(cdmJson, library, contract) {
457
+ const requested = cdmJson.dependencies[library];
458
+ if (typeof requested === "number" && Number.isInteger(requested) && requested >= 0) {
459
+ return requested;
460
+ }
461
+ if (typeof requested === "string") {
462
+ if (requested === "latest") return "latest";
463
+ const parsed = Number(requested);
464
+ if (Number.isInteger(parsed) && parsed >= 0) return parsed;
465
+ }
466
+ return contract.version;
467
+ }
468
+ async function queryLiveAddress(registry, library, version) {
469
+ const result = version === "latest" ? await registry.getAddress.query(library) : await registry.getAddressAtVersion.query(library, version);
470
+ if (!result.success) {
471
+ throw new ContractLiveAddressResolutionError(
472
+ version === "latest" ? `Failed to resolve live address for "${library}" from the CDM registry` : `Failed to resolve live address for "${library}" version ${version} from the CDM registry`,
473
+ { library, detail: result.value }
474
+ );
475
+ }
476
+ const value = result.value;
477
+ if (!value?.isSome) {
478
+ throw new ContractLiveAddressResolutionError(
479
+ version === "latest" ? `Contract "${library}" is not registered in the CDM registry` : `Contract "${library}" version ${version} is not registered in the CDM registry`,
480
+ { library, detail: result.value }
481
+ );
482
+ }
483
+ return value.value;
484
+ }
485
+ async function withLiveContractAddresses(cdmJson, runtime, options) {
486
+ try {
487
+ const contracts = cdmJson.contracts;
488
+ if (!contracts || Object.keys(contracts).length === 0) {
489
+ throw new ContractLiveAddressResolutionError(
490
+ "No installed contracts found in cdm.json for live address resolution."
491
+ );
492
+ }
493
+ const libraries = options?.libraries ?? Object.keys(contracts);
494
+ for (const library of libraries) {
495
+ if (!(library in contracts)) {
496
+ throw new ContractNotFoundError(library);
497
+ }
498
+ }
499
+ const registryAddress = resolveRegistryAddress(cdmJson, options?.registryAddress);
500
+ const registry = createContract(runtime, registryAddress, CDM_REGISTRY_ABI, {
501
+ defaultOrigin: options?.registryOrigin
502
+ });
503
+ const liveAddresses = await Promise.all(
504
+ libraries.map(async (library) => {
505
+ const version = resolveLiveVersionSpec(cdmJson, library, contracts[library]);
506
+ return [library, await queryLiveAddress(registry, library, version)];
507
+ })
508
+ );
509
+ const resolved = cloneCdmJson(cdmJson);
510
+ for (const [library, address] of liveAddresses) {
511
+ patchContractAddress(resolved, library, address);
512
+ }
513
+ return ok(resolved);
514
+ } catch (cause) {
515
+ if (cause instanceof ContractError) return err(cause);
516
+ const message = cause instanceof Error ? cause.message : String(cause);
517
+ return err(
518
+ new ContractLiveAddressResolutionError(
519
+ `Live contract address resolution failed: ${message}`,
520
+ { cause }
521
+ )
522
+ );
523
+ }
524
+ }
525
+ var ContractManager = class _ContractManager {
526
+ contracts;
527
+ runtime;
528
+ defaults;
529
+ constructor(cdmJson, runtime, options) {
530
+ this.runtime = runtime;
531
+ this.contracts = cdmJson.contracts;
532
+ this.defaults = {
533
+ signerManager: options?.signerManager,
534
+ origin: options?.defaultOrigin,
535
+ signer: options?.defaultSigner
536
+ };
537
+ }
538
+ /** Update the default origin, signer, or signerManager used by all contract handles. */
539
+ setDefaults(defaults) {
540
+ if (defaults.signerManager !== void 0)
541
+ this.defaults.signerManager = defaults.signerManager;
542
+ if (defaults.origin !== void 0) this.defaults.origin = defaults.origin;
543
+ if (defaults.signer !== void 0) this.defaults.signer = defaults.signer;
544
+ }
545
+ /**
546
+ * Create a `ContractManager` from a raw `PolkadotClient`.
547
+ *
548
+ * Convenience factory: builds a `ContractRuntime` internally from the
549
+ * client's typed API. Requires that the chain's typed API exposes the
550
+ * `Revive` pallet and `ReviveApi` runtime API (Asset Hub Paseo /
551
+ * Polkadot / Kusama).
552
+ *
553
+ * @param cdmJson - The CDM manifest.
554
+ * @param client - A `PolkadotClient` for the chain where contracts are deployed.
555
+ * @param descriptor - The chain descriptor used to derive the typed API.
556
+ * @param options - Optional configuration (signerManager, defaults).
557
+ */
558
+ static fromClient(cdmJson, client, descriptor, options) {
559
+ return new _ContractManager(
560
+ cdmJson,
561
+ createContractRuntimeFromClient(client, descriptor, options),
562
+ options
563
+ );
564
+ }
565
+ /**
566
+ * Create a manager after strictly resolving installed contract addresses
567
+ * from the live CDM registry. ABIs still come from the installed manifest.
568
+ */
569
+ static async fromLive(cdmJson, runtime, options) {
570
+ const resolved = await withLiveContractAddresses(cdmJson, runtime, {
571
+ ...options,
572
+ registryOrigin: options?.registryOrigin ?? options?.defaultOrigin
573
+ });
574
+ if (!resolved.ok) return resolved;
575
+ return ok(new _ContractManager(resolved.value, runtime, options));
576
+ }
577
+ /**
578
+ * Convenience factory for {@link fromLive} when the caller has a raw
579
+ * `PolkadotClient` and descriptor.
580
+ */
581
+ static async fromLiveClient(cdmJson, client, descriptor, options) {
582
+ const runtime = createContractRuntimeFromClient(client, descriptor, options);
583
+ return _ContractManager.fromLive(cdmJson, runtime, options);
584
+ }
585
+ getContractData(library) {
586
+ if (!this.contracts || !(library in this.contracts)) {
587
+ throw new ContractNotFoundError(library);
588
+ }
589
+ return this.contracts[library];
590
+ }
591
+ getContract(library) {
592
+ const data = this.getContractData(library);
593
+ return wrapContract(this.runtime, data.address, data.abi, this.defaults);
594
+ }
595
+ /** Get the on-chain address of an installed contract. */
596
+ getAddress(library) {
597
+ return this.getContractData(library).address;
598
+ }
599
+ /**
600
+ * Get the underlying {@link ContractRuntime} backing this manager.
601
+ *
602
+ * Useful when a consumer needs to call helpers that take a runtime
603
+ * directly — most commonly {@link ensureContractAccountMapped} at app
604
+ * boot. Avoids the alternative of building a second runtime against the
605
+ * same client and descriptor.
606
+ */
607
+ getRuntime() {
608
+ return this.runtime;
609
+ }
610
+ };
611
+ function createContract(runtime, address, abi, options) {
612
+ const defaults = {
613
+ signerManager: options?.signerManager,
614
+ origin: options?.defaultOrigin,
615
+ signer: options?.defaultSigner
616
+ };
617
+ return wrapContract(runtime, address, abi, defaults);
618
+ }
619
+ function createContractFromClient(client, descriptor, address, abi, options) {
620
+ return createContract(
621
+ createContractRuntimeFromClient(client, descriptor, options),
622
+ address,
623
+ abi,
624
+ options
625
+ );
626
+ }
627
+
628
+ export { ContractDryRunFailedError, ContractError, ContractInvalidOriginError, ContractLiveAddressResolutionError, ContractManager, ContractNotFoundError, ContractRevertedError, ContractSignerMissingError, QUERY_FALLBACK_ORIGIN, createContract, createContractFromClient, createContractRuntime, createContractRuntimeFromClient, ensureContractAccountMapped, isContractAccountMapped, withLiveContractAddresses };
629
+ //# sourceMappingURL=index.js.map
630
+ //# sourceMappingURL=index.js.map