@d9-network/ink 0.0.6 → 0.0.8

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.d.cts CHANGED
@@ -1131,6 +1131,19 @@ declare function buildAllEventDecoders(metadata: InkMetadata): Map<string, (data
1131
1131
  * @returns Event signature as Uint8Array (32 bytes)
1132
1132
  */
1133
1133
  declare function getEventSignature(eventLabel: string): Uint8Array;
1134
+ /**
1135
+ * Create ASCII-encoded event topic (D9 chain format)
1136
+ *
1137
+ * D9 chain uses a format where:
1138
+ * - First byte is 0x00 (null)
1139
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
1140
+ * - Total is exactly 32 bytes (truncated/padded as needed)
1141
+ *
1142
+ * @param contractName - Contract name (e.g., "MarketMaker", "Usdt")
1143
+ * @param eventLabel - Event label (e.g., "Transfer", "USDTToD9Conversion")
1144
+ * @returns 32-byte topic with null prefix and ASCII-encoded path
1145
+ */
1146
+ declare function createAsciiEventTopic(contractName: string, eventLabel: string): Uint8Array;
1134
1147
  //#endregion
1135
1148
  //#region src/events.d.ts
1136
1149
  /**
@@ -1162,6 +1175,18 @@ declare class ContractEventParser<S extends InkStorageDescriptor = InkStorageDes
1162
1175
  * ```
1163
1176
  */
1164
1177
  parseEvent(chainEvent: unknown): TypedContractEvent<E> | null;
1178
+ /**
1179
+ * Extract event label from ASCII-encoded topic (D9 chain format)
1180
+ *
1181
+ * D9 chain uses a format where:
1182
+ * - First byte is 0x00 (null)
1183
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
1184
+ * - Total is exactly 32 bytes (truncated/padded as needed)
1185
+ *
1186
+ * @param topic - The 32-byte topic from the event
1187
+ * @returns The extracted event label, or null if not in ASCII format
1188
+ */
1189
+ private extractEventLabelFromAsciiTopic;
1165
1190
  /**
1166
1191
  * Filter a batch of events and return type-safe results
1167
1192
  *
@@ -1206,10 +1231,6 @@ declare class ContractEventParser<S extends InkStorageDescriptor = InkStorageDes
1206
1231
  * Compare two Uint8Arrays for equality
1207
1232
  */
1208
1233
  private bytesEqual;
1209
- /**
1210
- * Build event signature map from metadata
1211
- */
1212
- private static buildEventSignatureMap;
1213
1234
  }
1214
1235
  /**
1215
1236
  * Type guard for narrowing event types
@@ -1428,5 +1449,111 @@ declare function isCallType<M$1 extends InkCallableDescriptor, L extends Extract
1428
1449
  */
1429
1450
  declare function createTypedRpc(client: PolkadotClient): TypedRpcRequest;
1430
1451
  //#endregion
1431
- export { AbortedError, type BlockHeader, type CallFilterOptions, ContractCallParser, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractMessageBuilder, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, type D9InkSdkWithRpc, DecodeError, type DecodedContractEvent, EncodeError, type EventFilterOptions, type EventSubscriptionOptions, type ExtractEnumDef, type ExtractEventLabels, type ExtractMessageLabels, type GasInfo, type InferEvents, type InferMessages, InkCodecs, type KnownRpcMethod, LangError, type MessageAttributes, type MessageInfo, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractCall, type RawContractEvent, type ResponseDecoder, type RpcParams, type RpcReturn, type RuntimeVersion, type SendOptions, type SendableTransaction, SignerError, type StorageChangeSet, type StorageDepositInfo, type SubstrateRpcMethods, type SystemHealth, TimeoutError, TransactionError, type TxResult, type TypedCallFilterOptions, type TypedContractCall, type TypedContractEvent, type TypedEventFilterOptions, type TypedMessage, type TypedRpcRequest, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1452
+ //#region src/utils/fees.d.ts
1453
+ /**
1454
+ * Gas weight representation
1455
+ */
1456
+ interface GasWeight {
1457
+ refTime: bigint;
1458
+ proofSize: bigint;
1459
+ }
1460
+ /**
1461
+ * Estimated transaction cost breakdown
1462
+ */
1463
+ interface EstimatedCost {
1464
+ /** Cost from gas consumption */
1465
+ gasCost: bigint;
1466
+ /** Storage deposit (may be refunded) */
1467
+ storageDeposit: bigint;
1468
+ /** Total estimated cost (gas + storage) */
1469
+ total: bigint;
1470
+ }
1471
+ /**
1472
+ * Formatted gas information for display
1473
+ */
1474
+ interface FormattedGasInfo {
1475
+ /** Human-readable ref_time */
1476
+ refTime: string;
1477
+ /** Human-readable proof_size */
1478
+ proofSize: string;
1479
+ }
1480
+ /**
1481
+ * Estimate the transaction cost from gas info and storage deposit
1482
+ *
1483
+ * Note: This is an approximation. Actual fees depend on chain configuration
1484
+ * and may vary slightly.
1485
+ *
1486
+ * @param gasInfo - Gas information from contract query
1487
+ * @param storageDeposit - Storage deposit amount (positive for charge, negative for refund)
1488
+ * @returns Estimated cost breakdown
1489
+ *
1490
+ * @example
1491
+ * ```typescript
1492
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1493
+ * if (result.success) {
1494
+ * const cost = estimateTransactionCost(
1495
+ * { gasConsumed: result.gasConsumed, gasRequired: result.gasRequired },
1496
+ * result.storageDeposit
1497
+ * );
1498
+ * console.log(`Estimated cost: ${formatBalance(cost.total, { decimals: 12 })} D9`);
1499
+ * }
1500
+ * ```
1501
+ */
1502
+ declare function estimateTransactionCost(gasInfo: GasInfo, storageDeposit: bigint): EstimatedCost;
1503
+ /**
1504
+ * Format gas information for human-readable display
1505
+ *
1506
+ * @param gasInfo - Gas information from contract query
1507
+ * @returns Formatted strings for ref_time and proof_size
1508
+ *
1509
+ * @example
1510
+ * ```typescript
1511
+ * const formatted = formatGasInfo(result.gasRequired);
1512
+ * console.log(`Gas: refTime=${formatted.refTime}, proofSize=${formatted.proofSize}`);
1513
+ * ```
1514
+ */
1515
+ declare function formatGasInfo(gasInfo: GasInfo["gasRequired"]): FormattedGasInfo;
1516
+ /**
1517
+ * Apply a safety margin to gas limits
1518
+ *
1519
+ * It's recommended to add a small margin to gas estimates to account for
1520
+ * slight variations in execution. 10% (multiplier = 1.1) is a common choice.
1521
+ *
1522
+ * @param gas - The gas weight to adjust
1523
+ * @param multiplier - The multiplier to apply (default: 1.1 for 10% margin)
1524
+ * @returns Adjusted gas weight with margin applied
1525
+ *
1526
+ * @example
1527
+ * ```typescript
1528
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1529
+ * if (result.success) {
1530
+ * // Add 10% safety margin
1531
+ * const safeGas = applyGasMargin(result.gasRequired, 1.1);
1532
+ * await contract.send("PSP22::transfer", {
1533
+ * origin,
1534
+ * args,
1535
+ * gasLimit: safeGas,
1536
+ * });
1537
+ * }
1538
+ * ```
1539
+ */
1540
+ declare function applyGasMargin(gas: GasWeight, multiplier?: number): GasWeight;
1541
+ /**
1542
+ * Compare two gas weights
1543
+ *
1544
+ * @param a - First gas weight
1545
+ * @param b - Second gas weight
1546
+ * @returns -1 if a < b, 0 if equal, 1 if a > b (compares refTime first, then proofSize)
1547
+ */
1548
+ declare function compareGasWeight(a: GasWeight, b: GasWeight): -1 | 0 | 1;
1549
+ /**
1550
+ * Check if gas weight exceeds a limit
1551
+ *
1552
+ * @param gas - The gas to check
1553
+ * @param limit - The limit to compare against
1554
+ * @returns True if gas exceeds the limit in either dimension
1555
+ */
1556
+ declare function gasExceedsLimit(gas: GasWeight, limit: GasWeight): boolean;
1557
+ //#endregion
1558
+ export { AbortedError, type BlockHeader, type CallFilterOptions, ContractCallParser, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractMessageBuilder, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, type D9InkSdkWithRpc, DecodeError, type DecodedContractEvent, EncodeError, EstimatedCost, type EventFilterOptions, type EventSubscriptionOptions, type ExtractEnumDef, type ExtractEventLabels, type ExtractMessageLabels, FormattedGasInfo, type GasInfo, GasWeight, type InferEvents, type InferMessages, InkCodecs, type KnownRpcMethod, LangError, type MessageAttributes, type MessageInfo, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractCall, type RawContractEvent, type ResponseDecoder, type RpcParams, type RpcReturn, type RuntimeVersion, type SendOptions, type SendableTransaction, SignerError, type StorageChangeSet, type StorageDepositInfo, type SubstrateRpcMethods, type SystemHealth, TimeoutError, TransactionError, type TxResult, type TypedCallFilterOptions, type TypedContractCall, type TypedContractEvent, type TypedEventFilterOptions, type TypedMessage, type TypedRpcRequest, applyGasMargin, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, compareGasWeight, createAsciiEventTopic, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, estimateTransactionCost, formatGasInfo, gasExceedsLimit, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1432
1559
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.mts CHANGED
@@ -1131,6 +1131,19 @@ declare function buildAllEventDecoders(metadata: InkMetadata): Map<string, (data
1131
1131
  * @returns Event signature as Uint8Array (32 bytes)
1132
1132
  */
1133
1133
  declare function getEventSignature(eventLabel: string): Uint8Array;
1134
+ /**
1135
+ * Create ASCII-encoded event topic (D9 chain format)
1136
+ *
1137
+ * D9 chain uses a format where:
1138
+ * - First byte is 0x00 (null)
1139
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
1140
+ * - Total is exactly 32 bytes (truncated/padded as needed)
1141
+ *
1142
+ * @param contractName - Contract name (e.g., "MarketMaker", "Usdt")
1143
+ * @param eventLabel - Event label (e.g., "Transfer", "USDTToD9Conversion")
1144
+ * @returns 32-byte topic with null prefix and ASCII-encoded path
1145
+ */
1146
+ declare function createAsciiEventTopic(contractName: string, eventLabel: string): Uint8Array;
1134
1147
  //#endregion
1135
1148
  //#region src/events.d.ts
1136
1149
  /**
@@ -1162,6 +1175,18 @@ declare class ContractEventParser<S extends InkStorageDescriptor = InkStorageDes
1162
1175
  * ```
1163
1176
  */
1164
1177
  parseEvent(chainEvent: unknown): TypedContractEvent<E> | null;
1178
+ /**
1179
+ * Extract event label from ASCII-encoded topic (D9 chain format)
1180
+ *
1181
+ * D9 chain uses a format where:
1182
+ * - First byte is 0x00 (null)
1183
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
1184
+ * - Total is exactly 32 bytes (truncated/padded as needed)
1185
+ *
1186
+ * @param topic - The 32-byte topic from the event
1187
+ * @returns The extracted event label, or null if not in ASCII format
1188
+ */
1189
+ private extractEventLabelFromAsciiTopic;
1165
1190
  /**
1166
1191
  * Filter a batch of events and return type-safe results
1167
1192
  *
@@ -1206,10 +1231,6 @@ declare class ContractEventParser<S extends InkStorageDescriptor = InkStorageDes
1206
1231
  * Compare two Uint8Arrays for equality
1207
1232
  */
1208
1233
  private bytesEqual;
1209
- /**
1210
- * Build event signature map from metadata
1211
- */
1212
- private static buildEventSignatureMap;
1213
1234
  }
1214
1235
  /**
1215
1236
  * Type guard for narrowing event types
@@ -1428,5 +1449,111 @@ declare function isCallType<M$1 extends InkCallableDescriptor, L extends Extract
1428
1449
  */
1429
1450
  declare function createTypedRpc(client: PolkadotClient): TypedRpcRequest;
1430
1451
  //#endregion
1431
- export { AbortedError, type BlockHeader, type CallFilterOptions, ContractCallParser, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractMessageBuilder, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, type D9InkSdkWithRpc, DecodeError, type DecodedContractEvent, EncodeError, type EventFilterOptions, type EventSubscriptionOptions, type ExtractEnumDef, type ExtractEventLabels, type ExtractMessageLabels, type GasInfo, type InferEvents, type InferMessages, InkCodecs, type KnownRpcMethod, LangError, type MessageAttributes, type MessageInfo, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractCall, type RawContractEvent, type ResponseDecoder, type RpcParams, type RpcReturn, type RuntimeVersion, type SendOptions, type SendableTransaction, SignerError, type StorageChangeSet, type StorageDepositInfo, type SubstrateRpcMethods, type SystemHealth, TimeoutError, TransactionError, type TxResult, type TypedCallFilterOptions, type TypedContractCall, type TypedContractEvent, type TypedEventFilterOptions, type TypedMessage, type TypedRpcRequest, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1452
+ //#region src/utils/fees.d.ts
1453
+ /**
1454
+ * Gas weight representation
1455
+ */
1456
+ interface GasWeight {
1457
+ refTime: bigint;
1458
+ proofSize: bigint;
1459
+ }
1460
+ /**
1461
+ * Estimated transaction cost breakdown
1462
+ */
1463
+ interface EstimatedCost {
1464
+ /** Cost from gas consumption */
1465
+ gasCost: bigint;
1466
+ /** Storage deposit (may be refunded) */
1467
+ storageDeposit: bigint;
1468
+ /** Total estimated cost (gas + storage) */
1469
+ total: bigint;
1470
+ }
1471
+ /**
1472
+ * Formatted gas information for display
1473
+ */
1474
+ interface FormattedGasInfo {
1475
+ /** Human-readable ref_time */
1476
+ refTime: string;
1477
+ /** Human-readable proof_size */
1478
+ proofSize: string;
1479
+ }
1480
+ /**
1481
+ * Estimate the transaction cost from gas info and storage deposit
1482
+ *
1483
+ * Note: This is an approximation. Actual fees depend on chain configuration
1484
+ * and may vary slightly.
1485
+ *
1486
+ * @param gasInfo - Gas information from contract query
1487
+ * @param storageDeposit - Storage deposit amount (positive for charge, negative for refund)
1488
+ * @returns Estimated cost breakdown
1489
+ *
1490
+ * @example
1491
+ * ```typescript
1492
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1493
+ * if (result.success) {
1494
+ * const cost = estimateTransactionCost(
1495
+ * { gasConsumed: result.gasConsumed, gasRequired: result.gasRequired },
1496
+ * result.storageDeposit
1497
+ * );
1498
+ * console.log(`Estimated cost: ${formatBalance(cost.total, { decimals: 12 })} D9`);
1499
+ * }
1500
+ * ```
1501
+ */
1502
+ declare function estimateTransactionCost(gasInfo: GasInfo, storageDeposit: bigint): EstimatedCost;
1503
+ /**
1504
+ * Format gas information for human-readable display
1505
+ *
1506
+ * @param gasInfo - Gas information from contract query
1507
+ * @returns Formatted strings for ref_time and proof_size
1508
+ *
1509
+ * @example
1510
+ * ```typescript
1511
+ * const formatted = formatGasInfo(result.gasRequired);
1512
+ * console.log(`Gas: refTime=${formatted.refTime}, proofSize=${formatted.proofSize}`);
1513
+ * ```
1514
+ */
1515
+ declare function formatGasInfo(gasInfo: GasInfo["gasRequired"]): FormattedGasInfo;
1516
+ /**
1517
+ * Apply a safety margin to gas limits
1518
+ *
1519
+ * It's recommended to add a small margin to gas estimates to account for
1520
+ * slight variations in execution. 10% (multiplier = 1.1) is a common choice.
1521
+ *
1522
+ * @param gas - The gas weight to adjust
1523
+ * @param multiplier - The multiplier to apply (default: 1.1 for 10% margin)
1524
+ * @returns Adjusted gas weight with margin applied
1525
+ *
1526
+ * @example
1527
+ * ```typescript
1528
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1529
+ * if (result.success) {
1530
+ * // Add 10% safety margin
1531
+ * const safeGas = applyGasMargin(result.gasRequired, 1.1);
1532
+ * await contract.send("PSP22::transfer", {
1533
+ * origin,
1534
+ * args,
1535
+ * gasLimit: safeGas,
1536
+ * });
1537
+ * }
1538
+ * ```
1539
+ */
1540
+ declare function applyGasMargin(gas: GasWeight, multiplier?: number): GasWeight;
1541
+ /**
1542
+ * Compare two gas weights
1543
+ *
1544
+ * @param a - First gas weight
1545
+ * @param b - Second gas weight
1546
+ * @returns -1 if a < b, 0 if equal, 1 if a > b (compares refTime first, then proofSize)
1547
+ */
1548
+ declare function compareGasWeight(a: GasWeight, b: GasWeight): -1 | 0 | 1;
1549
+ /**
1550
+ * Check if gas weight exceeds a limit
1551
+ *
1552
+ * @param gas - The gas to check
1553
+ * @param limit - The limit to compare against
1554
+ * @returns True if gas exceeds the limit in either dimension
1555
+ */
1556
+ declare function gasExceedsLimit(gas: GasWeight, limit: GasWeight): boolean;
1557
+ //#endregion
1558
+ export { AbortedError, type BlockHeader, type CallFilterOptions, ContractCallParser, type ContractCallResult, ContractError, type ContractErrorType, ContractEventParser, ContractExecutionError, type ContractMessageBuilder, type ContractStorage, type CreateContractOptions, type CreateD9InkSdkOptions, type D9InkContract, type D9InkContractFromDescriptor, type D9InkSdk, type D9InkSdkOptions, type D9InkSdkWithRpc, DecodeError, type DecodedContractEvent, EncodeError, EstimatedCost, type EventFilterOptions, type EventSubscriptionOptions, type ExtractEnumDef, type ExtractEventLabels, type ExtractMessageLabels, FormattedGasInfo, type GasInfo, GasWeight, type InferEvents, type InferMessages, InkCodecs, type KnownRpcMethod, LangError, type MessageAttributes, type MessageInfo, MetadataError, NetworkError, type QueryOptions, type QueryResult, type QuerySuccessValue, type RawContractCall, type RawContractEvent, type ResponseDecoder, type RpcParams, type RpcReturn, type RuntimeVersion, type SendOptions, type SendableTransaction, SignerError, type StorageChangeSet, type StorageDepositInfo, type SubstrateRpcMethods, type SystemHealth, TimeoutError, TransactionError, type TxResult, type TypedCallFilterOptions, type TypedContractCall, type TypedContractEvent, type TypedEventFilterOptions, type TypedMessage, type TypedRpcRequest, applyGasMargin, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, compareGasWeight, createAsciiEventTopic, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, estimateTransactionCost, formatGasInfo, gasExceedsLimit, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1432
1559
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -466,6 +466,27 @@ function buildAllEventDecoders(metadata) {
466
466
  function getEventSignature(eventLabel) {
467
467
  return blake2b(new TextEncoder().encode(eventLabel), { dkLen: 32 });
468
468
  }
469
+ /**
470
+ * Create ASCII-encoded event topic (D9 chain format)
471
+ *
472
+ * D9 chain uses a format where:
473
+ * - First byte is 0x00 (null)
474
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
475
+ * - Total is exactly 32 bytes (truncated/padded as needed)
476
+ *
477
+ * @param contractName - Contract name (e.g., "MarketMaker", "Usdt")
478
+ * @param eventLabel - Event label (e.g., "Transfer", "USDTToD9Conversion")
479
+ * @returns 32-byte topic with null prefix and ASCII-encoded path
480
+ */
481
+ function createAsciiEventTopic(contractName, eventLabel) {
482
+ const topic = new Uint8Array(32);
483
+ topic[0] = 0;
484
+ const encoder = new TextEncoder();
485
+ const fullPath = `${contractName}::${eventLabel}`;
486
+ const encoded = encoder.encode(fullPath);
487
+ topic.set(encoded.slice(0, 31), 1);
488
+ return topic;
489
+ }
469
490
 
470
491
  //#endregion
471
492
  //#region src/events.ts
@@ -517,9 +538,13 @@ var ContractEventParser = class {
517
538
  if (topics.length === 0) return null;
518
539
  const signature = topics[0];
519
540
  let eventLabel = null;
520
- for (const [label, sig] of this.eventSignatures) if (this.bytesEqual(signature, sig)) {
521
- eventLabel = label;
522
- break;
541
+ eventLabel = this.extractEventLabelFromAsciiTopic(signature);
542
+ if (eventLabel && !this.eventDecoders.has(eventLabel)) eventLabel = null;
543
+ if (!eventLabel) {
544
+ for (const [label, sig] of this.eventSignatures) if (this.bytesEqual(signature, sig)) {
545
+ eventLabel = label;
546
+ break;
547
+ }
523
548
  }
524
549
  if (!eventLabel) {
525
550
  console.warn("Unknown event signature:", signature);
@@ -531,7 +556,7 @@ var ContractEventParser = class {
531
556
  return null;
532
557
  }
533
558
  try {
534
- const decodedData = decoder(data);
559
+ const decodedData = decoder(data.slice(1));
535
560
  return {
536
561
  type: eventLabel,
537
562
  value: decodedData,
@@ -550,6 +575,25 @@ var ContractEventParser = class {
550
575
  }
551
576
  }
552
577
  /**
578
+ * Extract event label from ASCII-encoded topic (D9 chain format)
579
+ *
580
+ * D9 chain uses a format where:
581
+ * - First byte is 0x00 (null)
582
+ * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`
583
+ * - Total is exactly 32 bytes (truncated/padded as needed)
584
+ *
585
+ * @param topic - The 32-byte topic from the event
586
+ * @returns The extracted event label, or null if not in ASCII format
587
+ */
588
+ extractEventLabelFromAsciiTopic(topic) {
589
+ if (topic.length !== 32) return null;
590
+ if (topic[0] !== 0) return null;
591
+ const ascii = new TextDecoder().decode(topic.slice(1)).replace(/\0+$/, "");
592
+ const colonIndex = ascii.lastIndexOf("::");
593
+ if (colonIndex !== -1) return ascii.slice(colonIndex + 2);
594
+ return ascii || null;
595
+ }
596
+ /**
553
597
  * Filter a batch of events and return type-safe results
554
598
  *
555
599
  * @param chainEvents - Array of chain events to filter
@@ -647,18 +691,6 @@ var ContractEventParser = class {
647
691
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
648
692
  return true;
649
693
  }
650
- /**
651
- * Build event signature map from metadata
652
- */
653
- static buildEventSignatureMap(metadata) {
654
- const signatures = /* @__PURE__ */ new Map();
655
- const events = metadata.spec.events;
656
- for (const event of events) {
657
- const sig = getEventSignature(event.label);
658
- signatures.set(event.label, sig);
659
- }
660
- return signatures;
661
- }
662
694
  };
663
695
  /**
664
696
  * Type guard for narrowing event types
@@ -1811,5 +1843,126 @@ function isCallType(call, label) {
1811
1843
  }
1812
1844
 
1813
1845
  //#endregion
1814
- export { AbortedError, ContractCallParser, ContractError, ContractEventParser, ContractExecutionError, DecodeError, EncodeError, InkCodecs, LangError, MetadataError, NetworkError, SignerError, TimeoutError, TransactionError, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1846
+ //#region src/utils/fees.ts
1847
+ const WEIGHT_REF_TIME_PER_SECOND = 1000000000000n;
1848
+ const WEIGHT_FEE_COEFFICIENT = 1n;
1849
+ /**
1850
+ * Estimate the transaction cost from gas info and storage deposit
1851
+ *
1852
+ * Note: This is an approximation. Actual fees depend on chain configuration
1853
+ * and may vary slightly.
1854
+ *
1855
+ * @param gasInfo - Gas information from contract query
1856
+ * @param storageDeposit - Storage deposit amount (positive for charge, negative for refund)
1857
+ * @returns Estimated cost breakdown
1858
+ *
1859
+ * @example
1860
+ * ```typescript
1861
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1862
+ * if (result.success) {
1863
+ * const cost = estimateTransactionCost(
1864
+ * { gasConsumed: result.gasConsumed, gasRequired: result.gasRequired },
1865
+ * result.storageDeposit
1866
+ * );
1867
+ * console.log(`Estimated cost: ${formatBalance(cost.total, { decimals: 12 })} D9`);
1868
+ * }
1869
+ * ```
1870
+ */
1871
+ function estimateTransactionCost(gasInfo, storageDeposit) {
1872
+ const { gasRequired } = gasInfo;
1873
+ const gasCost = gasRequired.refTime * WEIGHT_FEE_COEFFICIENT / WEIGHT_REF_TIME_PER_SECOND + gasRequired.proofSize;
1874
+ const effectiveStorageDeposit = storageDeposit > 0n ? storageDeposit : 0n;
1875
+ return {
1876
+ gasCost,
1877
+ storageDeposit: effectiveStorageDeposit,
1878
+ total: gasCost + effectiveStorageDeposit
1879
+ };
1880
+ }
1881
+ /**
1882
+ * Format gas information for human-readable display
1883
+ *
1884
+ * @param gasInfo - Gas information from contract query
1885
+ * @returns Formatted strings for ref_time and proof_size
1886
+ *
1887
+ * @example
1888
+ * ```typescript
1889
+ * const formatted = formatGasInfo(result.gasRequired);
1890
+ * console.log(`Gas: refTime=${formatted.refTime}, proofSize=${formatted.proofSize}`);
1891
+ * ```
1892
+ */
1893
+ function formatGasInfo(gasInfo) {
1894
+ return {
1895
+ refTime: formatWeight(gasInfo.refTime),
1896
+ proofSize: formatWeight(gasInfo.proofSize)
1897
+ };
1898
+ }
1899
+ /**
1900
+ * Format a single weight value with appropriate units
1901
+ */
1902
+ function formatWeight(weight) {
1903
+ if (weight >= 1000000000000n) return `${(Number(weight) / 0xe8d4a51000).toFixed(2)}T`;
1904
+ if (weight >= 1000000000n) return `${(Number(weight) / 1e9).toFixed(2)}G`;
1905
+ if (weight >= 1000000n) return `${(Number(weight) / 1e6).toFixed(2)}M`;
1906
+ if (weight >= 1000n) return `${(Number(weight) / 1e3).toFixed(2)}K`;
1907
+ return weight.toString();
1908
+ }
1909
+ /**
1910
+ * Apply a safety margin to gas limits
1911
+ *
1912
+ * It's recommended to add a small margin to gas estimates to account for
1913
+ * slight variations in execution. 10% (multiplier = 1.1) is a common choice.
1914
+ *
1915
+ * @param gas - The gas weight to adjust
1916
+ * @param multiplier - The multiplier to apply (default: 1.1 for 10% margin)
1917
+ * @returns Adjusted gas weight with margin applied
1918
+ *
1919
+ * @example
1920
+ * ```typescript
1921
+ * const result = await contract.query("PSP22::transfer", { origin, args });
1922
+ * if (result.success) {
1923
+ * // Add 10% safety margin
1924
+ * const safeGas = applyGasMargin(result.gasRequired, 1.1);
1925
+ * await contract.send("PSP22::transfer", {
1926
+ * origin,
1927
+ * args,
1928
+ * gasLimit: safeGas,
1929
+ * });
1930
+ * }
1931
+ * ```
1932
+ */
1933
+ function applyGasMargin(gas, multiplier = 1.1) {
1934
+ if (multiplier <= 0) throw new Error("Multiplier must be positive");
1935
+ const basisPoints = BigInt(Math.round(multiplier * 1e4));
1936
+ return {
1937
+ refTime: gas.refTime * basisPoints / 10000n,
1938
+ proofSize: gas.proofSize * basisPoints / 10000n
1939
+ };
1940
+ }
1941
+ /**
1942
+ * Compare two gas weights
1943
+ *
1944
+ * @param a - First gas weight
1945
+ * @param b - Second gas weight
1946
+ * @returns -1 if a < b, 0 if equal, 1 if a > b (compares refTime first, then proofSize)
1947
+ */
1948
+ function compareGasWeight(a, b) {
1949
+ if (a.refTime < b.refTime) return -1;
1950
+ if (a.refTime > b.refTime) return 1;
1951
+ if (a.proofSize < b.proofSize) return -1;
1952
+ if (a.proofSize > b.proofSize) return 1;
1953
+ return 0;
1954
+ }
1955
+ /**
1956
+ * Check if gas weight exceeds a limit
1957
+ *
1958
+ * @param gas - The gas to check
1959
+ * @param limit - The limit to compare against
1960
+ * @returns True if gas exceeds the limit in either dimension
1961
+ */
1962
+ function gasExceedsLimit(gas, limit) {
1963
+ return gas.refTime > limit.refTime || gas.proofSize > limit.proofSize;
1964
+ }
1965
+
1966
+ //#endregion
1967
+ export { AbortedError, ContractCallParser, ContractError, ContractEventParser, ContractExecutionError, DecodeError, EncodeError, InkCodecs, LangError, MetadataError, NetworkError, SignerError, TimeoutError, TransactionError, applyGasMargin, buildAllEventDecoders, buildAllMessageDecoders, buildEventDecoder, buildMessageDecoder, compareGasWeight, createAsciiEventTopic, createCodecRegistry, createContractEventStream, createD9InkContract, createD9InkSdk, createMessageBuilder, createNativeTransferStream, createPSP22TransferStream, createTypedRpc, decodeContractCallResult, decodeInkValue, decodeResult, encodeCall, encodeContractCall, encodeContractCallWithLimits, estimateTransactionCost, formatGasInfo, gasExceedsLimit, getEventSignature, isCallType, isContractError, isErrorType, isEventType, isLangError, unwrapInkResult };
1815
1968
  //# sourceMappingURL=index.mjs.map