@d9-network/ink 0.0.3 → 0.0.4

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.cjs ADDED
@@ -0,0 +1,1274 @@
1
+ let polkadot_api = require("polkadot-api");
2
+ let polkadot_api_utils = require("polkadot-api/utils");
3
+ let _polkadot_api_ink_contracts = require("@polkadot-api/ink-contracts");
4
+ let _polkadot_labs_hdkd_helpers = require("@polkadot-labs/hdkd-helpers");
5
+ let _subsquid_scale_codec = require("@subsquid/scale-codec");
6
+ let _polkadot_api_substrate_bindings = require("@polkadot-api/substrate-bindings");
7
+ let _noble_hashes_blake2_js = require("@noble/hashes/blake2.js");
8
+ let rxjs = require("rxjs");
9
+
10
+ //#region src/encode.ts
11
+ /**
12
+ * Encode a contract call for ContractsApi_call state_call.
13
+ *
14
+ * The encoded format matches the ContractsApi::call runtime API:
15
+ * - origin: AccountId (32 bytes)
16
+ * - dest: AccountId (32 bytes)
17
+ * - value: Balance (u128)
18
+ * - gas_limit: Option<Weight> (1 byte for None)
19
+ * - storage_deposit_limit: Option<Balance> (1 byte for None)
20
+ * - input_data: Vec<u8> (compact length + bytes)
21
+ *
22
+ * @param origin - The origin account (as Uint8Array or hex string)
23
+ * @param dest - The contract address (as Uint8Array or hex string)
24
+ * @param input - The encoded call data (selector + arguments)
25
+ * @param value - Optional value to transfer (default: 0)
26
+ * @returns Hex-encoded bytes for state_call
27
+ */
28
+ function encodeContractCall(origin, dest, input, value = 0n) {
29
+ const sink = new _subsquid_scale_codec.HexSink();
30
+ const originBytes = typeof origin === "string" ? (0, polkadot_api_utils.fromHex)(origin) : origin;
31
+ const destBytes = typeof dest === "string" ? (0, polkadot_api_utils.fromHex)(dest) : dest;
32
+ const inputBytes = "asBytes" in input ? input.asBytes() : input;
33
+ sink.bytes(originBytes);
34
+ sink.bytes(destBytes);
35
+ sink.u128(value);
36
+ sink.u8(0);
37
+ sink.u8(0);
38
+ sink.compact(inputBytes.length);
39
+ sink.bytes(inputBytes);
40
+ return sink.toHex();
41
+ }
42
+ /**
43
+ * Encode a contract call using the same address for origin and dest.
44
+ * This is a simplified version for query operations where the origin
45
+ * doesn't matter much.
46
+ *
47
+ * @param address - The contract address
48
+ * @param input - The encoded call data
49
+ * @param value - Optional value to transfer
50
+ * @returns Hex-encoded bytes for state_call
51
+ */
52
+ function encodeCall(address, input, value = 0n) {
53
+ return encodeContractCall(address, address, input, value);
54
+ }
55
+ /**
56
+ * Encode a contract call with specific gas limit and storage deposit limit.
57
+ *
58
+ * @param origin - The origin account
59
+ * @param dest - The contract address
60
+ * @param input - The encoded call data
61
+ * @param options - Call options including value, gas limit, storage deposit limit
62
+ * @returns Hex-encoded bytes for state_call
63
+ */
64
+ function encodeContractCallWithLimits(origin, dest, input, options = {}) {
65
+ const sink = new _subsquid_scale_codec.HexSink();
66
+ const originBytes = typeof origin === "string" ? (0, polkadot_api_utils.fromHex)(origin) : origin;
67
+ const destBytes = typeof dest === "string" ? (0, polkadot_api_utils.fromHex)(dest) : dest;
68
+ const inputBytes = "asBytes" in input ? input.asBytes() : input;
69
+ sink.bytes(originBytes);
70
+ sink.bytes(destBytes);
71
+ sink.u128(options.value ?? 0n);
72
+ if (options.gasLimit) {
73
+ sink.u8(1);
74
+ sink.compact(options.gasLimit.refTime);
75
+ sink.compact(options.gasLimit.proofSize);
76
+ } else sink.u8(0);
77
+ if (options.storageDepositLimit !== void 0) {
78
+ sink.u8(1);
79
+ sink.u128(options.storageDepositLimit);
80
+ } else sink.u8(0);
81
+ sink.compact(inputBytes.length);
82
+ sink.bytes(inputBytes);
83
+ return sink.toHex();
84
+ }
85
+
86
+ //#endregion
87
+ //#region src/decode.ts
88
+ /**
89
+ * Decoding utilities for ContractsApi_call response
90
+ */
91
+ /**
92
+ * Decode the raw ContractsApi_call response.
93
+ *
94
+ * The response format is:
95
+ * - gasConsumed: Weight { ref_time: Compact<u64>, proof_size: Compact<u64> }
96
+ * - gasRequired: Weight
97
+ * - storageDeposit: StorageDeposit { variant: u8, amount: u128 }
98
+ * - debugMessage: String
99
+ * - result: Result<ExecReturnValue, DispatchError>
100
+ * - ExecReturnValue: { flags: u32, data: Vec<u8> }
101
+ *
102
+ * @param result - The raw response bytes from state_call ContractsApi_call
103
+ * @returns Decoded contract call result
104
+ */
105
+ function decodeContractCallResult(result) {
106
+ const src = new _subsquid_scale_codec.Src(result);
107
+ const gasConsumedRefTime = BigInt(src.compact());
108
+ const gasConsumedProofSize = BigInt(src.compact());
109
+ const gasRequiredRefTime = BigInt(src.compact());
110
+ const gasRequiredProofSize = BigInt(src.compact());
111
+ const storageDepositVariant = src.u8();
112
+ const storageDepositAmount = src.u128();
113
+ const debugMessage = src.str();
114
+ const success = src.u8() === 0;
115
+ const flags = src.u32();
116
+ const data = src.bytes(src.compactLength());
117
+ return {
118
+ gas: {
119
+ gasConsumed: {
120
+ refTime: gasConsumedRefTime,
121
+ proofSize: gasConsumedProofSize
122
+ },
123
+ gasRequired: {
124
+ refTime: gasRequiredRefTime,
125
+ proofSize: gasRequiredProofSize
126
+ }
127
+ },
128
+ storageDeposit: {
129
+ type: storageDepositVariant === 0 ? "Refund" : "Charge",
130
+ amount: storageDepositAmount
131
+ },
132
+ debugMessage,
133
+ success,
134
+ flags,
135
+ data
136
+ };
137
+ }
138
+ /**
139
+ * Legacy function - decode and return just the exec result data.
140
+ * @deprecated Use decodeContractCallResult for full information
141
+ */
142
+ function decodeResult(result) {
143
+ return decodeContractCallResult(result).data;
144
+ }
145
+ /**
146
+ * Unwrap the inner value from Result<T, LangError> by checking the variant byte.
147
+ *
148
+ * Ink contracts wrap their return values in Result<T, LangError>.
149
+ * This function handles the unwrapping and throws an error for LangError.
150
+ *
151
+ * @param data - The exec result bytes (Result<T, LangError> encoded)
152
+ * @returns The inner value bytes (T encoded)
153
+ * @throws Error if the result is Err variant (LangError)
154
+ */
155
+ function unwrapInkResult(data) {
156
+ if (data.length === 0) throw new Error("Empty result data");
157
+ const variant = data[0];
158
+ if (variant === 0) return data.slice(1);
159
+ else if (variant === 1) throw new Error("Contract call returned LangError");
160
+ else throw new Error(`Unknown result variant: ${variant}`);
161
+ }
162
+ /**
163
+ * Check if the result indicates a LangError
164
+ *
165
+ * @param data - The exec result bytes
166
+ * @returns True if it's a LangError (Err variant)
167
+ */
168
+ function isLangError(data) {
169
+ return data.length > 0 && data[0] === 1;
170
+ }
171
+ /**
172
+ * Decode ink contract message result using a custom SCALE codec.
173
+ * This bypasses polkadot-api's ink decoder which has issues with LangError type.
174
+ *
175
+ * @param data - The exec result bytes (Result<T, LangError> encoded)
176
+ * @param codec - The SCALE codec for the inner value type T
177
+ * @returns The decoded value
178
+ */
179
+ function decodeInkValue(data, codec) {
180
+ const innerData = unwrapInkResult(data);
181
+ return codec.dec(innerData);
182
+ }
183
+ /**
184
+ * Pre-defined codecs for common types
185
+ */
186
+ const InkCodecs = {
187
+ u128: _polkadot_api_substrate_bindings.u128,
188
+ balancePair: (0, _polkadot_api_substrate_bindings.Tuple)(_polkadot_api_substrate_bindings.u128, _polkadot_api_substrate_bindings.u128)
189
+ };
190
+
191
+ //#endregion
192
+ //#region src/codec-builder.ts
193
+ /**
194
+ * Auto-build SCALE decoders from ink metadata type definitions.
195
+ *
196
+ * This module provides a way to automatically construct decoders for ink contract
197
+ * message return types without manually specifying codecs for each message.
198
+ */
199
+ /**
200
+ * Build a SCALE codec from ink metadata type definition
201
+ */
202
+ function buildCodecFromType(typeId, types, cache) {
203
+ const cached = cache.get(typeId);
204
+ if (cached) return cached;
205
+ const typeEntry = types.find((t) => t.id === typeId);
206
+ if (!typeEntry) throw new Error(`Type ${typeId} not found in metadata`);
207
+ const def = typeEntry.type.def;
208
+ const path = typeEntry.type.path;
209
+ if (def.primitive) {
210
+ const codec = buildPrimitiveCodec(def.primitive);
211
+ cache.set(typeId, codec);
212
+ return codec;
213
+ }
214
+ if (path && path.length > 0) {
215
+ const specialCodec = buildSpecialTypeCodec(path, typeEntry, types, cache);
216
+ if (specialCodec) {
217
+ cache.set(typeId, specialCodec);
218
+ return specialCodec;
219
+ }
220
+ }
221
+ if (def.tuple) {
222
+ const codec = buildTupleCodec(def.tuple, types, cache);
223
+ cache.set(typeId, codec);
224
+ return codec;
225
+ }
226
+ if (def.sequence) {
227
+ const codec = (0, _polkadot_api_substrate_bindings.Vector)(buildCodecFromType(def.sequence.type, types, cache));
228
+ cache.set(typeId, codec);
229
+ return codec;
230
+ }
231
+ if (def.array) {
232
+ const innerCodec = buildCodecFromType(def.array.type, types, cache);
233
+ if (def.array.type === findPrimitiveTypeId(types, "u8")) {
234
+ const codec$1 = (0, _polkadot_api_substrate_bindings.Bytes)(def.array.len);
235
+ cache.set(typeId, codec$1);
236
+ return codec$1;
237
+ }
238
+ const codec = (0, _polkadot_api_substrate_bindings.Vector)(innerCodec, def.array.len);
239
+ cache.set(typeId, codec);
240
+ return codec;
241
+ }
242
+ if (def.composite) {
243
+ const codec = buildCompositeCodec(def.composite, types, cache);
244
+ cache.set(typeId, codec);
245
+ return codec;
246
+ }
247
+ if (def.variant) {
248
+ const codec = buildVariantCodec(def.variant, path, types, cache);
249
+ cache.set(typeId, codec);
250
+ return codec;
251
+ }
252
+ throw new Error(`Unknown type definition for type ${typeId}: ${JSON.stringify(def)}`);
253
+ }
254
+ /**
255
+ * Build codec for primitive types
256
+ */
257
+ function buildPrimitiveCodec(primitive) {
258
+ switch (primitive) {
259
+ case "u8": return _polkadot_api_substrate_bindings.u8;
260
+ case "u16": return _polkadot_api_substrate_bindings.u16;
261
+ case "u32": return _polkadot_api_substrate_bindings.u32;
262
+ case "u64": return _polkadot_api_substrate_bindings.u64;
263
+ case "u128": return _polkadot_api_substrate_bindings.u128;
264
+ case "i8": return _polkadot_api_substrate_bindings.i8;
265
+ case "i16": return _polkadot_api_substrate_bindings.i16;
266
+ case "i32": return _polkadot_api_substrate_bindings.i32;
267
+ case "i64": return _polkadot_api_substrate_bindings.i64;
268
+ case "i128": return _polkadot_api_substrate_bindings.i128;
269
+ case "bool": return _polkadot_api_substrate_bindings.bool;
270
+ case "str": return _polkadot_api_substrate_bindings.str;
271
+ default: throw new Error(`Unknown primitive type: ${primitive}`);
272
+ }
273
+ }
274
+ /**
275
+ * Build codec for special types based on path
276
+ */
277
+ function buildSpecialTypeCodec(path, typeEntry, types, cache) {
278
+ if (path.join("::").includes("AccountId")) return (0, _polkadot_api_substrate_bindings.AccountId)();
279
+ if (path[0] === "Option") {
280
+ const params = typeEntry.type.params;
281
+ if (params && params.length > 0 && params[0]?.type !== void 0) return (0, _polkadot_api_substrate_bindings.Option)(buildCodecFromType(params[0].type, types, cache));
282
+ }
283
+ if (path[0] === "Result") {
284
+ const params = typeEntry.type.params;
285
+ if (params && params.length >= 2) {
286
+ const okTypeId = params[0]?.type;
287
+ const errTypeId = params[1]?.type;
288
+ if (okTypeId !== void 0 && errTypeId !== void 0) return (0, _polkadot_api_substrate_bindings.Variant)({
289
+ Ok: buildCodecFromType(okTypeId, types, cache),
290
+ Err: buildCodecFromType(errTypeId, types, cache)
291
+ }, [0, 1]);
292
+ }
293
+ }
294
+ return null;
295
+ }
296
+ /**
297
+ * Build codec for tuple types
298
+ */
299
+ function buildTupleCodec(tupleTypes, types, cache) {
300
+ if (tupleTypes.length === 0) return _polkadot_api_substrate_bindings._void;
301
+ const innerCodecs = tupleTypes.map((t) => buildCodecFromType(t, types, cache));
302
+ switch (innerCodecs.length) {
303
+ case 1: return (0, _polkadot_api_substrate_bindings.Tuple)(innerCodecs[0]);
304
+ case 2: return (0, _polkadot_api_substrate_bindings.Tuple)(innerCodecs[0], innerCodecs[1]);
305
+ case 3: return (0, _polkadot_api_substrate_bindings.Tuple)(innerCodecs[0], innerCodecs[1], innerCodecs[2]);
306
+ case 4: return (0, _polkadot_api_substrate_bindings.Tuple)(innerCodecs[0], innerCodecs[1], innerCodecs[2], innerCodecs[3]);
307
+ default: return (0, _polkadot_api_substrate_bindings.Tuple)(...innerCodecs);
308
+ }
309
+ }
310
+ /**
311
+ * Build codec for composite (struct) types
312
+ */
313
+ function buildCompositeCodec(composite, types, cache) {
314
+ const fields = composite.fields;
315
+ if (fields.length === 1 && !fields[0]?.name) return buildCodecFromType(fields[0].type, types, cache);
316
+ const structDef = {};
317
+ for (const field of fields) {
318
+ const fieldName = field.name || `field${fields.indexOf(field)}`;
319
+ structDef[fieldName] = buildCodecFromType(field.type, types, cache);
320
+ }
321
+ return (0, _polkadot_api_substrate_bindings.Struct)(structDef);
322
+ }
323
+ /**
324
+ * Build codec for variant (enum) types
325
+ */
326
+ function buildVariantCodec(variant, path, types, cache) {
327
+ const variants = variant.variants;
328
+ const isLangError$1 = path?.includes("LangError");
329
+ const variantDef = {};
330
+ const indices = [];
331
+ if (isLangError$1 && !variants.some((v) => v.index === 0)) {
332
+ variantDef["_Placeholder"] = _polkadot_api_substrate_bindings._void;
333
+ indices.push(0);
334
+ }
335
+ for (const v of variants) {
336
+ let fieldCodec;
337
+ const fields = v.fields ?? [];
338
+ if (fields.length === 0) fieldCodec = _polkadot_api_substrate_bindings._void;
339
+ else if (fields.length === 1 && !fields[0]?.name) fieldCodec = buildCodecFromType(fields[0].type, types, cache);
340
+ else {
341
+ const structDef = {};
342
+ for (const field of fields) {
343
+ const fieldName = field.name || `field${fields.indexOf(field)}`;
344
+ structDef[fieldName] = buildCodecFromType(field.type, types, cache);
345
+ }
346
+ fieldCodec = (0, _polkadot_api_substrate_bindings.Struct)(structDef);
347
+ }
348
+ variantDef[v.name] = fieldCodec;
349
+ indices.push(v.index);
350
+ }
351
+ return (0, _polkadot_api_substrate_bindings.Variant)(variantDef, indices);
352
+ }
353
+ /**
354
+ * Find the type ID for a primitive type
355
+ */
356
+ function findPrimitiveTypeId(types, primitive) {
357
+ return types.find((t) => t.type.def.primitive === primitive)?.id ?? -1;
358
+ }
359
+ /**
360
+ * Extract the inner type from Result<T, LangError>
361
+ * Returns the type ID of T
362
+ */
363
+ function extractResultInnerType(typeEntry) {
364
+ const path = typeEntry.type.path;
365
+ if (!path || path[0] !== "Result") return null;
366
+ const params = typeEntry.type.params;
367
+ if (!params || params.length < 1) return null;
368
+ return params[0]?.type ?? null;
369
+ }
370
+ /**
371
+ * Build a decoder for a message's return type from ink metadata.
372
+ * This handles the Result<T, LangError> wrapper and returns a decoder for T.
373
+ *
374
+ * @param metadata - The ink contract metadata
375
+ * @param messageLabel - The message label (e.g., "PSP22::balance_of")
376
+ * @returns A decoder function that decodes the inner value bytes
377
+ */
378
+ function buildMessageDecoder(metadata, messageLabel) {
379
+ const types = metadata.types;
380
+ const message = metadata.spec.messages.find((m) => m.label === messageLabel);
381
+ if (!message) throw new Error(`Message "${messageLabel}" not found in metadata`);
382
+ const returnTypeId = message.returnType.type;
383
+ const returnTypeEntry = types.find((t) => t.id === returnTypeId);
384
+ if (!returnTypeEntry) throw new Error(`Return type ${returnTypeId} not found for message "${messageLabel}"`);
385
+ const cache = /* @__PURE__ */ new Map();
386
+ const innerTypeId = extractResultInnerType(returnTypeEntry);
387
+ if (innerTypeId !== null) {
388
+ const innerCodec = buildCodecFromType(innerTypeId, types, cache);
389
+ return (data) => innerCodec.dec(data);
390
+ }
391
+ const codec = buildCodecFromType(returnTypeId, types, cache);
392
+ return (data) => codec.dec(data);
393
+ }
394
+ /**
395
+ * Build decoders for all messages in the metadata.
396
+ * Returns a Map of message label -> decoder function.
397
+ */
398
+ function buildAllMessageDecoders(metadata) {
399
+ const decoders = /* @__PURE__ */ new Map();
400
+ for (const message of metadata.spec.messages) try {
401
+ const decoder = buildMessageDecoder(metadata, message.label);
402
+ decoders.set(message.label, decoder);
403
+ } catch (error) {
404
+ console.warn(`Failed to build decoder for message "${message.label}":`, error);
405
+ }
406
+ return decoders;
407
+ }
408
+ /**
409
+ * Create a codec registry compatible with ResponseDecoder type
410
+ */
411
+ function createCodecRegistry(metadata) {
412
+ const decoders = buildAllMessageDecoders(metadata);
413
+ const registry = /* @__PURE__ */ new Map();
414
+ for (const [label, decoder] of decoders) registry.set(label, { dec: decoder });
415
+ return registry;
416
+ }
417
+ /**
418
+ * Build a SCALE decoder for a contract event from ink metadata
419
+ *
420
+ * @param metadata - The ink contract metadata
421
+ * @param eventLabel - The event label (e.g., "Transfer", "Approval")
422
+ * @returns A decoder function that decodes the event data bytes
423
+ */
424
+ function buildEventDecoder(metadata, eventLabel) {
425
+ const types = metadata.types;
426
+ const event = metadata.spec.events.find((e) => e.label === eventLabel);
427
+ if (!event) throw new Error(`Event "${eventLabel}" not found in metadata`);
428
+ const cache = /* @__PURE__ */ new Map();
429
+ const structDef = {};
430
+ for (const arg of event.args) {
431
+ const fieldName = arg.label;
432
+ structDef[fieldName] = buildCodecFromType(arg.type.type, types, cache);
433
+ }
434
+ if (event.args.length === 0) return () => void 0;
435
+ if (event.args.length === 1) {
436
+ const argCodec = structDef[event.args[0].label];
437
+ return (data) => argCodec.dec(data);
438
+ }
439
+ const codec = (0, _polkadot_api_substrate_bindings.Struct)(structDef);
440
+ return (data) => codec.dec(data);
441
+ }
442
+ /**
443
+ * Build decoders for all events in the metadata
444
+ *
445
+ * @param metadata - The ink contract metadata
446
+ * @returns Map of event label -> decoder function
447
+ */
448
+ function buildAllEventDecoders(metadata) {
449
+ const decoders = /* @__PURE__ */ new Map();
450
+ const events = metadata.spec.events;
451
+ for (const event of events) try {
452
+ const decoder = buildEventDecoder(metadata, event.label);
453
+ decoders.set(event.label, decoder);
454
+ } catch (error) {
455
+ console.warn(`Failed to build decoder for event "${event.label}":`, error);
456
+ }
457
+ return decoders;
458
+ }
459
+ /**
460
+ * Get event signature (topic[0]) for filtering
461
+ * Events in ink! use blake2_256 hash of event label as topic[0]
462
+ *
463
+ * @param eventLabel - The event label (e.g., "Transfer")
464
+ * @returns Event signature as Uint8Array (32 bytes)
465
+ */
466
+ function getEventSignature(eventLabel) {
467
+ return (0, _noble_hashes_blake2_js.blake2b)(new TextEncoder().encode(eventLabel), { dkLen: 32 });
468
+ }
469
+
470
+ //#endregion
471
+ //#region src/events.ts
472
+ /**
473
+ * Event parser for a specific contract
474
+ */
475
+ var ContractEventParser = class {
476
+ eventDecoders;
477
+ eventSignatures;
478
+ contractAddressBytes;
479
+ contractAddress;
480
+ metadata;
481
+ constructor(metadata, contractAddress) {
482
+ this.metadata = metadata;
483
+ this.contractAddress = contractAddress;
484
+ this.eventDecoders = buildAllEventDecoders(metadata);
485
+ this.contractAddressBytes = (0, _polkadot_labs_hdkd_helpers.ss58Decode)(contractAddress)[0];
486
+ this.eventSignatures = /* @__PURE__ */ new Map();
487
+ const events = metadata.spec.events;
488
+ for (const event of events) {
489
+ const sig = getEventSignature(event.label);
490
+ this.eventSignatures.set(event.label, sig);
491
+ }
492
+ }
493
+ /**
494
+ * Parse a raw chain event into a contract event (if it matches)
495
+ * Returns null if the event is not from this contract or cannot be parsed
496
+ */
497
+ parseEvent(chainEvent) {
498
+ const extracted = this.extractContractEmittedEvent(chainEvent);
499
+ if (!extracted) return null;
500
+ const { contract, data, topics, blockNumber, blockHash, eventIndex } = extracted;
501
+ if (!this.bytesEqual(contract, this.contractAddressBytes)) return null;
502
+ if (topics.length === 0) return null;
503
+ const signature = topics[0];
504
+ let eventLabel = null;
505
+ for (const [label, sig] of this.eventSignatures) if (this.bytesEqual(signature, sig)) {
506
+ eventLabel = label;
507
+ break;
508
+ }
509
+ if (!eventLabel) {
510
+ console.warn("Unknown event signature:", signature);
511
+ return null;
512
+ }
513
+ const decoder = this.eventDecoders.get(eventLabel);
514
+ if (!decoder) {
515
+ console.warn(`No decoder for event ${eventLabel}`);
516
+ return null;
517
+ }
518
+ try {
519
+ const decodedData = decoder(data);
520
+ return {
521
+ label: eventLabel,
522
+ data: decodedData,
523
+ raw: {
524
+ blockNumber,
525
+ blockHash,
526
+ eventIndex,
527
+ contractAddress: this.getContractAddress(),
528
+ data,
529
+ topics
530
+ }
531
+ };
532
+ } catch (error) {
533
+ console.warn(`Failed to decode event ${eventLabel}:`, error);
534
+ return null;
535
+ }
536
+ }
537
+ /**
538
+ * Filter a batch of events
539
+ */
540
+ filterEvents(chainEvents, options) {
541
+ const results = [];
542
+ for (const chainEvent of chainEvents) {
543
+ const parsed = this.parseEvent(chainEvent);
544
+ if (!parsed) continue;
545
+ if (options?.eventLabels && !options.eventLabels.includes(parsed.label)) continue;
546
+ if (options?.fromBlock && parsed.raw.blockNumber < options.fromBlock) continue;
547
+ if (options?.toBlock && parsed.raw.blockNumber > options.toBlock) continue;
548
+ results.push(parsed);
549
+ }
550
+ return results;
551
+ }
552
+ /**
553
+ * Get the contract address as SS58 string
554
+ */
555
+ getContractAddress() {
556
+ return this.contractAddress;
557
+ }
558
+ /**
559
+ * Extract ContractEmitted event from chain event structure
560
+ * Based on polkadot-api event format
561
+ */
562
+ extractContractEmittedEvent(chainEvent) {
563
+ if (!chainEvent || typeof chainEvent !== "object") return null;
564
+ const record = chainEvent;
565
+ const event = record.event;
566
+ if (!event || typeof event !== "object") return null;
567
+ if (event.type !== "Contracts") return null;
568
+ const eventValue = event.value;
569
+ if (!eventValue || typeof eventValue !== "object") return null;
570
+ if (eventValue.type !== "ContractEmitted") return null;
571
+ const contractEmittedData = eventValue.value;
572
+ if (!contractEmittedData || typeof contractEmittedData !== "object") return null;
573
+ const contract = contractEmittedData.contract;
574
+ const data = contractEmittedData.data;
575
+ if (!(contract instanceof Uint8Array) || !(data instanceof Uint8Array)) return null;
576
+ const topics = [];
577
+ if (record.topics && Array.isArray(record.topics)) {
578
+ for (const topic of record.topics) if (topic instanceof Uint8Array) topics.push(topic);
579
+ }
580
+ return {
581
+ contract,
582
+ data,
583
+ topics,
584
+ blockNumber: typeof record.blockNumber === "number" ? record.blockNumber : 0,
585
+ blockHash: typeof record.blockHash === "string" ? record.blockHash : "",
586
+ eventIndex: typeof record.eventIndex === "number" ? record.eventIndex : 0
587
+ };
588
+ }
589
+ /**
590
+ * Compare two Uint8Arrays for equality
591
+ */
592
+ bytesEqual(a, b) {
593
+ if (a.length !== b.length) return false;
594
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
595
+ return true;
596
+ }
597
+ /**
598
+ * Build event signature map from metadata
599
+ */
600
+ static buildEventSignatureMap(metadata) {
601
+ const signatures = /* @__PURE__ */ new Map();
602
+ const events = metadata.spec.events;
603
+ for (const event of events) {
604
+ const sig = getEventSignature(event.label);
605
+ signatures.set(event.label, sig);
606
+ }
607
+ return signatures;
608
+ }
609
+ };
610
+
611
+ //#endregion
612
+ //#region src/subscriptions.ts
613
+ /**
614
+ * Event subscriptions using RxJS
615
+ */
616
+ /**
617
+ * Create an observable stream of contract events
618
+ *
619
+ * @param client - Polkadot API client
620
+ * @param metadata - Contract metadata
621
+ * @param options - Subscription options
622
+ * @returns Observable stream of decoded contract events
623
+ */
624
+ function createContractEventStream(client, metadata, options) {
625
+ const parser = new ContractEventParser(metadata, options.contractAddress);
626
+ return client.finalizedBlock$.pipe((0, rxjs.mergeMap)(async (block) => {
627
+ try {
628
+ return {
629
+ block,
630
+ events: await options.getEvents(block.hash)
631
+ };
632
+ } catch (error) {
633
+ console.error("Error fetching events at block", block.number, ":", error instanceof Error ? error.message : String(error));
634
+ return {
635
+ block,
636
+ events: []
637
+ };
638
+ }
639
+ }), (0, rxjs.map)(({ block, events }) => {
640
+ return events.map((event, index) => {
641
+ const eventWithMeta = {
642
+ ...event,
643
+ blockNumber: block.number,
644
+ blockHash: block.hash,
645
+ eventIndex: index
646
+ };
647
+ return parser.parseEvent(eventWithMeta);
648
+ }).filter((e) => e !== null);
649
+ }), (0, rxjs.mergeMap)((events) => (0, rxjs.from)(events)), (0, rxjs.filter)((event) => {
650
+ if (!options.eventLabels) return true;
651
+ return options.eventLabels.includes(event.label);
652
+ }), (0, rxjs.catchError)((error) => {
653
+ console.error("Error in contract event stream:", error);
654
+ return (0, rxjs.of)();
655
+ }), (0, rxjs.share)());
656
+ }
657
+ /**
658
+ * Convenience helper to create a Transfer event stream for PSP22 tokens
659
+ *
660
+ * @param client - Polkadot API client
661
+ * @param metadata - PSP22 contract metadata
662
+ * @param contractAddress - PSP22 contract address
663
+ * @param getEvents - Function to fetch System.Events at a block hash
664
+ * @param watchAddress - Optional address to filter transfers (only events involving this address)
665
+ * @returns Observable stream of Transfer events
666
+ */
667
+ function createPSP22TransferStream(client, metadata, contractAddress, getEvents, watchAddress) {
668
+ return createContractEventStream(client, metadata, {
669
+ contractAddress,
670
+ eventLabels: ["Transfer"],
671
+ getEvents
672
+ }).pipe((0, rxjs.filter)((event) => {
673
+ if (!watchAddress) return true;
674
+ const data = event.data;
675
+ return data.from === watchAddress || data.to === watchAddress;
676
+ }));
677
+ }
678
+ /**
679
+ * Create a native token (D9) transfer event stream
680
+ *
681
+ * This monitors System.Transfer events instead of contract events
682
+ *
683
+ * @param client - Polkadot API client
684
+ * @param getEvents - Function to fetch System.Events at a block hash
685
+ * @param watchAddress - Address to monitor for transfers
686
+ * @returns Observable stream of native transfer events
687
+ */
688
+ function createNativeTransferStream(client, getEvents, watchAddress) {
689
+ return client.finalizedBlock$.pipe((0, rxjs.mergeMap)(async (block) => {
690
+ try {
691
+ return {
692
+ block,
693
+ events: await getEvents(block.hash)
694
+ };
695
+ } catch (error) {
696
+ console.error("Error fetching events for native transfers:", error instanceof Error ? error.message : String(error));
697
+ return {
698
+ block,
699
+ events: []
700
+ };
701
+ }
702
+ }), (0, rxjs.map)(({ block, events }) => {
703
+ return events.map((record) => {
704
+ if (record.event?.type !== "Balances") return null;
705
+ if (record.event?.value?.type !== "Transfer") return null;
706
+ const { from: from$1, to, amount } = record.event.value.value;
707
+ if (from$1 !== watchAddress && to !== watchAddress) return null;
708
+ return {
709
+ from: from$1,
710
+ to,
711
+ amount,
712
+ blockNumber: block.number,
713
+ blockHash: block.hash
714
+ };
715
+ }).filter((t) => t !== null);
716
+ }), (0, rxjs.mergeMap)((transfers) => (0, rxjs.from)(transfers)), (0, rxjs.catchError)((error) => {
717
+ console.error("Error in native transfer stream:", error);
718
+ return (0, rxjs.of)();
719
+ }), (0, rxjs.share)());
720
+ }
721
+
722
+ //#endregion
723
+ //#region src/errors.ts
724
+ /**
725
+ * Base error class for all contract-related errors
726
+ */
727
+ var ContractError = class ContractError extends Error {
728
+ timestamp;
729
+ cause;
730
+ constructor(message, type, label, details, cause) {
731
+ super(message, { cause });
732
+ this.type = type;
733
+ this.label = label;
734
+ this.details = details;
735
+ this.name = "ContractError";
736
+ this.timestamp = /* @__PURE__ */ new Date();
737
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ContractError);
738
+ }
739
+ /**
740
+ * Create a formatted error message for logging
741
+ */
742
+ toLogString() {
743
+ const parts = [
744
+ `[${this.type}]`,
745
+ this.label ? `${this.label}:` : "",
746
+ this.message
747
+ ].filter(Boolean);
748
+ if (this.details) parts.push(`Details: ${JSON.stringify(this.details)}`);
749
+ return parts.join(" ");
750
+ }
751
+ /**
752
+ * Convert to a plain object for serialization
753
+ */
754
+ toJSON() {
755
+ return {
756
+ name: this.name,
757
+ type: this.type,
758
+ message: this.message,
759
+ label: this.label,
760
+ details: this.details,
761
+ timestamp: this.timestamp.toISOString(),
762
+ stack: this.stack
763
+ };
764
+ }
765
+ };
766
+ /**
767
+ * Error thrown when contract metadata is missing or invalid
768
+ */
769
+ var MetadataError = class extends ContractError {
770
+ constructor(message, details) {
771
+ super(message, "METADATA_ERROR", void 0, details);
772
+ this.name = "MetadataError";
773
+ }
774
+ };
775
+ /**
776
+ * Error thrown when encoding call data fails
777
+ */
778
+ var EncodeError = class extends ContractError {
779
+ constructor(label, message, details) {
780
+ super(message, "ENCODE_ERROR", label, details);
781
+ this.name = "EncodeError";
782
+ }
783
+ };
784
+ /**
785
+ * Error thrown when decoding response fails
786
+ */
787
+ var DecodeError = class extends ContractError {
788
+ constructor(label, message, details) {
789
+ super(message, "DECODE_ERROR", label, details);
790
+ this.name = "DecodeError";
791
+ }
792
+ };
793
+ /**
794
+ * Error thrown for network/RPC errors
795
+ */
796
+ var NetworkError = class extends ContractError {
797
+ constructor(message, cause, details) {
798
+ super(message, "NETWORK_ERROR", void 0, details, cause);
799
+ this.name = "NetworkError";
800
+ }
801
+ };
802
+ /**
803
+ * Error thrown when contract returns an error result
804
+ */
805
+ var ContractExecutionError = class extends ContractError {
806
+ constructor(label, errorValue) {
807
+ super(`Contract execution failed: ${JSON.stringify(errorValue)}`, "CONTRACT_ERROR", label, errorValue);
808
+ this.errorValue = errorValue;
809
+ this.name = "ContractExecutionError";
810
+ }
811
+ };
812
+ /**
813
+ * Error thrown for Ink LangError
814
+ */
815
+ var LangError = class extends ContractError {
816
+ constructor(label, variant) {
817
+ const variantName = variant === 1 ? "CouldNotReadInput" : `Unknown(${variant})`;
818
+ super(`Ink LangError: ${variantName}`, "LANG_ERROR", label, {
819
+ variant,
820
+ variantName
821
+ });
822
+ this.variant = variant;
823
+ this.name = "LangError";
824
+ }
825
+ };
826
+ /**
827
+ * Error thrown when request times out
828
+ */
829
+ var TimeoutError = class extends ContractError {
830
+ constructor(label, timeoutMs) {
831
+ super(`Request timed out after ${timeoutMs}ms`, "TIMEOUT_ERROR", label, { timeoutMs });
832
+ this.timeoutMs = timeoutMs;
833
+ this.name = "TimeoutError";
834
+ }
835
+ };
836
+ /**
837
+ * Error thrown when request is aborted
838
+ */
839
+ var AbortedError = class extends ContractError {
840
+ constructor(label, reason) {
841
+ super(reason || "Request was aborted", "ABORTED", label, { reason });
842
+ this.name = "AbortedError";
843
+ }
844
+ };
845
+ /**
846
+ * Error thrown for signer-related issues
847
+ */
848
+ var SignerError = class extends ContractError {
849
+ constructor(message, details) {
850
+ super(message, "SIGNER_ERROR", void 0, details);
851
+ this.name = "SignerError";
852
+ }
853
+ };
854
+ /**
855
+ * Error thrown when transaction submission fails
856
+ */
857
+ var TransactionError = class extends ContractError {
858
+ constructor(label, message, txHash, details) {
859
+ super(message, "TX_ERROR", label, {
860
+ ...details,
861
+ txHash
862
+ });
863
+ this.txHash = txHash;
864
+ this.name = "TransactionError";
865
+ }
866
+ };
867
+ /**
868
+ * Type guard to check if an error is a ContractError
869
+ */
870
+ function isContractError(error) {
871
+ return error instanceof ContractError;
872
+ }
873
+ /**
874
+ * Type guard to check for specific error types
875
+ */
876
+ function isErrorType(error, type) {
877
+ return isContractError(error) && error.type === type;
878
+ }
879
+
880
+ //#endregion
881
+ //#region src/contract.ts
882
+ /**
883
+ * Patch LangError type in ink metadata to fix the missing index 0 variant issue.
884
+ * Uses structuredClone for efficient deep cloning.
885
+ */
886
+ function patchLangErrorInMetadata(metadata) {
887
+ const patched = structuredClone(metadata);
888
+ for (const typeEntry of patched.types) {
889
+ const path = typeEntry.type?.path;
890
+ const def = typeEntry.type?.def;
891
+ if (path && Array.isArray(path) && path.includes("LangError") && def?.variant) {
892
+ const variants = def.variant.variants;
893
+ if (Array.isArray(variants)) {
894
+ if (!variants.some((v) => v.index === 0)) variants.unshift({
895
+ index: 0,
896
+ name: "_Placeholder",
897
+ fields: [],
898
+ docs: []
899
+ });
900
+ }
901
+ }
902
+ }
903
+ return patched;
904
+ }
905
+ /**
906
+ * Convert SS58 address to bytes
907
+ */
908
+ function ss58ToBytes(address) {
909
+ const [publicKey] = (0, _polkadot_labs_hdkd_helpers.ss58Decode)(address);
910
+ return publicKey;
911
+ }
912
+ /**
913
+ * Create a promise that rejects after a timeout
914
+ */
915
+ function createTimeout(ms, label) {
916
+ let timeoutId;
917
+ return {
918
+ promise: new Promise((_, reject) => {
919
+ timeoutId = setTimeout(() => {
920
+ reject(new TimeoutError(label, ms));
921
+ }, ms);
922
+ }),
923
+ clear: () => clearTimeout(timeoutId)
924
+ };
925
+ }
926
+ /**
927
+ * Check if AbortSignal is aborted and throw if so
928
+ */
929
+ function checkAborted(signal, label) {
930
+ if (signal?.aborted) throw new AbortedError(label, signal.reason);
931
+ }
932
+ /**
933
+ * Create a D9 Ink Contract instance
934
+ */
935
+ function createD9InkContract(descriptor, address, options) {
936
+ const { client, typedApi, defaultQueryOptions = {}, defaultSendOptions = {} } = options;
937
+ if (!descriptor.metadata) throw new MetadataError("Contract descriptor must include metadata");
938
+ const patchedMetadata = patchLangErrorInMetadata(descriptor.metadata);
939
+ const builder = (0, _polkadot_api_ink_contracts.getInkDynamicBuilder)((0, _polkadot_api_ink_contracts.getInkLookup)(patchedMetadata));
940
+ let codecRegistry;
941
+ try {
942
+ codecRegistry = createCodecRegistry(patchedMetadata);
943
+ } catch (error) {
944
+ console.warn("Failed to auto-generate codecs from metadata:", error);
945
+ codecRegistry = /* @__PURE__ */ new Map();
946
+ }
947
+ const addressBytes = ss58ToBytes(address);
948
+ const messageCodecCache = /* @__PURE__ */ new Map();
949
+ function getMessageCodec(label) {
950
+ const cached = messageCodecCache.get(label);
951
+ if (cached) return cached;
952
+ const codec = builder.buildMessage(label);
953
+ messageCodecCache.set(label, codec);
954
+ return codec;
955
+ }
956
+ /**
957
+ * Get the decoder for a message
958
+ */
959
+ function getDecoder(label) {
960
+ return codecRegistry.get(label) ?? null;
961
+ }
962
+ /**
963
+ * Execute a query (dry-run)
964
+ */
965
+ async function executeQuery(method, queryOptions) {
966
+ const { origin, args, value = 0n, signal, timeout, at } = {
967
+ ...defaultQueryOptions,
968
+ ...queryOptions
969
+ };
970
+ try {
971
+ checkAborted(signal, method);
972
+ const originBytes = ss58ToBytes(origin);
973
+ const codec = getMessageCodec(method);
974
+ const message = encodeContractCall(originBytes, addressBytes, codec.call.enc(args ?? {}), value);
975
+ const blockHash = at ?? (await client.getFinalizedBlock()).hash;
976
+ checkAborted(signal, method);
977
+ const executeCall = async () => {
978
+ return (0, polkadot_api_utils.fromHex)(await client._request("state_call", [
979
+ "ContractsApi_call",
980
+ message,
981
+ blockHash
982
+ ]));
983
+ };
984
+ let rawResponse;
985
+ if (timeout) {
986
+ const { promise: timeoutPromise, clear } = createTimeout(timeout, method);
987
+ try {
988
+ rawResponse = await Promise.race([executeCall(), timeoutPromise]);
989
+ } finally {
990
+ clear();
991
+ }
992
+ } else rawResponse = await executeCall();
993
+ checkAborted(signal, method);
994
+ const callResult = decodeContractCallResult(rawResponse);
995
+ if (!callResult.success) return {
996
+ success: false,
997
+ error: new ContractError(`Contract execution failed: ${callResult.debugMessage}`, "CONTRACT_ERROR", method)
998
+ };
999
+ if (isLangError(callResult.data)) return {
1000
+ success: false,
1001
+ error: new LangError(method, callResult.data[1] ?? 1)
1002
+ };
1003
+ const innerData = unwrapInkResult(callResult.data);
1004
+ let decodedResponse;
1005
+ const decoder = getDecoder(method);
1006
+ if (decoder) try {
1007
+ decodedResponse = decoder.dec(innerData);
1008
+ } catch (decodeError) {
1009
+ console.warn("D9InkContract: Failed to decode response:", decodeError);
1010
+ const fullResult = new Uint8Array(1 + innerData.length);
1011
+ fullResult[0] = 0;
1012
+ fullResult.set(innerData, 1);
1013
+ try {
1014
+ const papiResult = codec.value.dec(fullResult);
1015
+ if (papiResult !== null && typeof papiResult === "object" && "success" in papiResult && "value" in papiResult) if (papiResult.success) decodedResponse = papiResult.value;
1016
+ else return {
1017
+ success: false,
1018
+ error: new DecodeError(method, `Contract returned error: ${JSON.stringify(papiResult.value)}`, papiResult.value)
1019
+ };
1020
+ else decodedResponse = papiResult;
1021
+ } catch (error) {
1022
+ return {
1023
+ success: false,
1024
+ error: new DecodeError(method, `Failed to decode response: ${error instanceof Error ? error.message : String(error)}`, { error })
1025
+ };
1026
+ }
1027
+ }
1028
+ else {
1029
+ const fullResult = new Uint8Array(1 + innerData.length);
1030
+ fullResult[0] = 0;
1031
+ fullResult.set(innerData, 1);
1032
+ const papiResult = codec.value.dec(fullResult);
1033
+ if (papiResult !== null && typeof papiResult === "object" && "success" in papiResult && "value" in papiResult) if (papiResult.success) decodedResponse = papiResult.value;
1034
+ else return {
1035
+ success: false,
1036
+ error: new DecodeError(method, `Contract returned error: ${JSON.stringify(papiResult.value)}`, papiResult.value)
1037
+ };
1038
+ else decodedResponse = papiResult;
1039
+ }
1040
+ return {
1041
+ success: true,
1042
+ value: decodedResponse,
1043
+ events: [],
1044
+ gasConsumed: callResult.gas.gasConsumed,
1045
+ gasRequired: callResult.gas.gasRequired,
1046
+ storageDeposit: callResult.storageDeposit.amount,
1047
+ send: () => createSendableTransaction(method, {
1048
+ origin,
1049
+ args,
1050
+ value,
1051
+ gasLimit: callResult.gas.gasRequired
1052
+ })
1053
+ };
1054
+ } catch (error) {
1055
+ if (error instanceof ContractError) return {
1056
+ success: false,
1057
+ error
1058
+ };
1059
+ return {
1060
+ success: false,
1061
+ error: new ContractError(error instanceof Error ? error.message : String(error), "NETWORK_ERROR", method)
1062
+ };
1063
+ }
1064
+ }
1065
+ /**
1066
+ * Create a sendable transaction
1067
+ */
1068
+ function createSendableTransaction(method, sendOptions) {
1069
+ const { origin, args, value = 0n, gasLimit, storageDepositLimit } = {
1070
+ ...defaultSendOptions,
1071
+ ...sendOptions
1072
+ };
1073
+ const originBytes = ss58ToBytes(origin);
1074
+ const callData = getMessageCodec(method).call.enc(args ?? {});
1075
+ return {
1076
+ getEncodedData: () => callData,
1077
+ async signAndSubmit(signer) {
1078
+ if (!typedApi) throw new TransactionError(method, "typedApi is required for transaction submission. Pass typedApi in SDK options.");
1079
+ try {
1080
+ let gas = gasLimit;
1081
+ if (!gas) {
1082
+ const message = encodeContractCall(originBytes, addressBytes, callData, value);
1083
+ const blockHash = (await client.getFinalizedBlock()).hash;
1084
+ gas = decodeContractCallResult((0, polkadot_api_utils.fromHex)(await client._request("state_call", [
1085
+ "ContractsApi_call",
1086
+ message,
1087
+ blockHash
1088
+ ]))).gas.gasRequired;
1089
+ }
1090
+ const txResult = await typedApi.tx.Contracts.call({
1091
+ dest: {
1092
+ type: "Id",
1093
+ value: address
1094
+ },
1095
+ value,
1096
+ gas_limit: {
1097
+ ref_time: gas.refTime,
1098
+ proof_size: gas.proofSize
1099
+ },
1100
+ storage_deposit_limit: storageDepositLimit,
1101
+ data: polkadot_api.Binary.fromBytes(callData)
1102
+ }).signAndSubmit(signer, { at: "finalized" });
1103
+ return {
1104
+ ok: true,
1105
+ txHash: txResult.txHash,
1106
+ block: txResult.block,
1107
+ events: txResult.events ?? []
1108
+ };
1109
+ } catch (error) {
1110
+ return {
1111
+ ok: false,
1112
+ txHash: "",
1113
+ block: {
1114
+ hash: "",
1115
+ number: 0
1116
+ },
1117
+ events: [],
1118
+ dispatchError: error
1119
+ };
1120
+ }
1121
+ }
1122
+ };
1123
+ }
1124
+ /**
1125
+ * Create send method that returns a sendable transaction
1126
+ */
1127
+ function send(method, sendOptions) {
1128
+ return createSendableTransaction(method, sendOptions);
1129
+ }
1130
+ /**
1131
+ * Create storage query interface
1132
+ */
1133
+ function getStorage() {
1134
+ return {
1135
+ async getRoot() {
1136
+ console.warn("D9InkContract: getRoot not implemented");
1137
+ return {
1138
+ success: false,
1139
+ value: new ContractError("Storage queries not yet implemented", "METADATA_ERROR")
1140
+ };
1141
+ },
1142
+ async getNested(path, ..._keys) {
1143
+ console.warn("D9InkContract: getNested not implemented");
1144
+ return {
1145
+ success: false,
1146
+ value: new ContractError(`Storage query for "${path}" not yet implemented`, "METADATA_ERROR")
1147
+ };
1148
+ }
1149
+ };
1150
+ }
1151
+ /**
1152
+ * Filter events for this contract
1153
+ */
1154
+ function filterEvents(events) {
1155
+ return new ContractEventParser(patchedMetadata, address).filterEvents(events);
1156
+ }
1157
+ /**
1158
+ * Subscribe to contract events as an RxJS Observable
1159
+ *
1160
+ * @param options - Subscription options (contractAddress is automatically set)
1161
+ * @param options.getEvents - Function to fetch System.Events at a block hash
1162
+ * @param options.eventLabels - Optional filter for specific event names
1163
+ * @param options.fromBlock - Optional starting block number
1164
+ */
1165
+ function subscribeToEvents(options$1) {
1166
+ return createContractEventStream(client, patchedMetadata, {
1167
+ ...options$1,
1168
+ contractAddress: address
1169
+ });
1170
+ }
1171
+ return {
1172
+ address,
1173
+ metadata: patchedMetadata,
1174
+ query: executeQuery,
1175
+ send,
1176
+ getStorage,
1177
+ filterEvents,
1178
+ subscribeToEvents
1179
+ };
1180
+ }
1181
+
1182
+ //#endregion
1183
+ //#region src/sdk.ts
1184
+ /**
1185
+ * Create a D9 Ink SDK instance.
1186
+ *
1187
+ * This SDK provides a similar API to the official @polkadot-api/sdk-ink,
1188
+ * but uses state_call + ContractsApi_call instead of ReviveApi.
1189
+ *
1190
+ * @example
1191
+ * ```ts
1192
+ * import { createD9InkSdk } from "@d9-network/ink";
1193
+ * import { contracts } from "@polkadot-api/descriptors";
1194
+ *
1195
+ * const sdk = createD9InkSdk(client);
1196
+ * const usdtContract = sdk.getContract(
1197
+ * contracts.d9_usdt,
1198
+ * "uLj9DRUujbpCyK7USZY5ebGbxdtKoWvdRvGyyUsoLWDsNng"
1199
+ * );
1200
+ *
1201
+ * // Query balance
1202
+ * const result = await usdtContract.query("PSP22::balance_of", {
1203
+ * origin: aliceAddress,
1204
+ * args: { owner: aliceAddress }
1205
+ * });
1206
+ *
1207
+ * if (result.success) {
1208
+ * console.log("Balance:", result.value.response);
1209
+ *
1210
+ * // Send transaction from the query result
1211
+ * const txResult = await result.value.send().signAndSubmit(aliceSigner);
1212
+ * }
1213
+ *
1214
+ * // Or send directly
1215
+ * const txResult = await usdtContract
1216
+ * .send("PSP22::transfer", {
1217
+ * origin: aliceAddress,
1218
+ * args: { to: bobAddress, value: 1000n, data: [] }
1219
+ * })
1220
+ * .signAndSubmit(aliceSigner);
1221
+ * ```
1222
+ *
1223
+ * @param client - The PolkadotClient instance
1224
+ * @param options - Optional SDK configuration
1225
+ * @returns D9 Ink SDK instance
1226
+ */
1227
+ function createD9InkSdk(client, options = {}) {
1228
+ const { typedApi, defaultQueryOptions, defaultSendOptions } = options;
1229
+ return { getContract(descriptor, address) {
1230
+ return createD9InkContract(descriptor, address, {
1231
+ client,
1232
+ typedApi,
1233
+ defaultQueryOptions,
1234
+ defaultSendOptions
1235
+ });
1236
+ } };
1237
+ }
1238
+
1239
+ //#endregion
1240
+ exports.AbortedError = AbortedError;
1241
+ exports.ContractError = ContractError;
1242
+ exports.ContractEventParser = ContractEventParser;
1243
+ exports.ContractExecutionError = ContractExecutionError;
1244
+ exports.DecodeError = DecodeError;
1245
+ exports.EncodeError = EncodeError;
1246
+ exports.InkCodecs = InkCodecs;
1247
+ exports.LangError = LangError;
1248
+ exports.MetadataError = MetadataError;
1249
+ exports.NetworkError = NetworkError;
1250
+ exports.SignerError = SignerError;
1251
+ exports.TimeoutError = TimeoutError;
1252
+ exports.TransactionError = TransactionError;
1253
+ exports.buildAllEventDecoders = buildAllEventDecoders;
1254
+ exports.buildAllMessageDecoders = buildAllMessageDecoders;
1255
+ exports.buildEventDecoder = buildEventDecoder;
1256
+ exports.buildMessageDecoder = buildMessageDecoder;
1257
+ exports.createCodecRegistry = createCodecRegistry;
1258
+ exports.createContractEventStream = createContractEventStream;
1259
+ exports.createD9InkContract = createD9InkContract;
1260
+ exports.createD9InkSdk = createD9InkSdk;
1261
+ exports.createNativeTransferStream = createNativeTransferStream;
1262
+ exports.createPSP22TransferStream = createPSP22TransferStream;
1263
+ exports.decodeContractCallResult = decodeContractCallResult;
1264
+ exports.decodeInkValue = decodeInkValue;
1265
+ exports.decodeResult = decodeResult;
1266
+ exports.encodeCall = encodeCall;
1267
+ exports.encodeContractCall = encodeContractCall;
1268
+ exports.encodeContractCallWithLimits = encodeContractCallWithLimits;
1269
+ exports.getEventSignature = getEventSignature;
1270
+ exports.isContractError = isContractError;
1271
+ exports.isErrorType = isErrorType;
1272
+ exports.isLangError = isLangError;
1273
+ exports.unwrapInkResult = unwrapInkResult;
1274
+ //# sourceMappingURL=index.cjs.map