@d9-network/ink 0.0.7 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["HexSink","Src","u128","buildPrimitiveCodec","buildSpecialTypeCodec","buildTupleCodec","findPrimitiveTypeId","codec","buildCompositeCodec","buildVariantCodec","u8","u16","u32","u64","u128","i8","i16","i32","i64","i128","bool","str","_void","structDef: Record<string, AnyCodec>","isLangError","variantDef: Record<string, any>","indices: number[]","fieldCodec: AnyCodec","cache: CodecCache","eventLabel: string | null","results: TypedContractEvent<E>[]","contract: Uint8Array","data: Uint8Array","topics: Uint8Array[]","error: unknown","from","Binary","type: ContractErrorType","label?: string","details?: unknown","errorValue: unknown","variant: number","timeoutMs: number","txHash?: string","timeoutId: ReturnType<typeof setTimeout>","codecRegistry: Map<string, ResponseDecoder>","message","rawResponse: Uint8Array","decodedResponse: M[K][\"response\"]","Binary","options","codec","u8","u16","u32","u64","u128","i8","i16","i32","i64","i128","bool","str","_void","structDef: Record<string, AnyCodec>","isLangError","variantDef: Record<string, any>","indices: number[]","fieldCodec: AnyCodec","cache: CodecCache","raw: RawContractCall","results: TypedContractCall<M>[]"],"sources":["../src/encode.ts","../src/decode.ts","../src/codec-builder.ts","../src/events.ts","../src/subscriptions.ts","../src/message-builder.ts","../src/errors.ts","../src/contract.ts","../src/rpc.ts","../src/sdk.ts","../src/codec-builder-internal.ts","../src/calls.ts","../src/utils/fees.ts"],"sourcesContent":["/**\n * Encoding utilities for ContractsApi_call state_call\n */\n\nimport type { Bytes } from \"@subsquid/scale-codec\";\nimport { HexSink } from \"@subsquid/scale-codec\";\nimport type { Binary } from \"polkadot-api\";\nimport { fromHex } from \"polkadot-api/utils\";\n\n/**\n * Encode a contract call for ContractsApi_call state_call.\n *\n * The encoded format matches the ContractsApi::call runtime API:\n * - origin: AccountId (32 bytes)\n * - dest: AccountId (32 bytes)\n * - value: Balance (u128)\n * - gas_limit: Option<Weight> (1 byte for None)\n * - storage_deposit_limit: Option<Balance> (1 byte for None)\n * - input_data: Vec<u8> (compact length + bytes)\n *\n * @param origin - The origin account (as Uint8Array or hex string)\n * @param dest - The contract address (as Uint8Array or hex string)\n * @param input - The encoded call data (selector + arguments)\n * @param value - Optional value to transfer (default: 0)\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeContractCall(\n origin: Uint8Array | string,\n dest: Uint8Array | string,\n input: Binary | Uint8Array,\n value: bigint = 0n,\n): Bytes {\n const sink = new HexSink();\n\n const originBytes = typeof origin === \"string\" ? fromHex(origin) : origin;\n const destBytes = typeof dest === \"string\" ? fromHex(dest) : dest;\n const inputBytes = \"asBytes\" in input ? input.asBytes() : input;\n\n // origin: AccountId\n sink.bytes(originBytes);\n // dest: AccountId\n sink.bytes(destBytes);\n // value: Balance (u128)\n sink.u128(value);\n // gas_limit: Option<Weight> - None\n sink.u8(0);\n // storage_deposit_limit: Option<Balance> - None\n sink.u8(0);\n // input_data: Vec<u8>\n sink.compact(inputBytes.length);\n sink.bytes(inputBytes);\n\n return sink.toHex();\n}\n\n/**\n * Encode a contract call using the same address for origin and dest.\n * This is a simplified version for query operations where the origin\n * doesn't matter much.\n *\n * @param address - The contract address\n * @param input - The encoded call data\n * @param value - Optional value to transfer\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeCall(\n address: Uint8Array | string,\n input: Binary | Uint8Array,\n value: bigint = 0n,\n): Bytes {\n return encodeContractCall(address, address, input, value);\n}\n\n/**\n * Encode a contract call with specific gas limit and storage deposit limit.\n *\n * @param origin - The origin account\n * @param dest - The contract address\n * @param input - The encoded call data\n * @param options - Call options including value, gas limit, storage deposit limit\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeContractCallWithLimits(\n origin: Uint8Array | string,\n dest: Uint8Array | string,\n input: Binary | Uint8Array,\n options: {\n value?: bigint;\n gasLimit?: { refTime: bigint; proofSize: bigint };\n storageDepositLimit?: bigint;\n } = {},\n): Bytes {\n const sink = new HexSink();\n\n const originBytes = typeof origin === \"string\" ? fromHex(origin) : origin;\n const destBytes = typeof dest === \"string\" ? fromHex(dest) : dest;\n const inputBytes = \"asBytes\" in input ? input.asBytes() : input;\n\n // origin: AccountId\n sink.bytes(originBytes);\n // dest: AccountId\n sink.bytes(destBytes);\n // value: Balance (u128)\n sink.u128(options.value ?? 0n);\n\n // gas_limit: Option<Weight>\n if (options.gasLimit) {\n sink.u8(1); // Some\n sink.compact(options.gasLimit.refTime);\n sink.compact(options.gasLimit.proofSize);\n } else {\n sink.u8(0); // None\n }\n\n // storage_deposit_limit: Option<Balance>\n if (options.storageDepositLimit !== undefined) {\n sink.u8(1); // Some\n sink.u128(options.storageDepositLimit);\n } else {\n sink.u8(0); // None\n }\n\n // input_data: Vec<u8>\n sink.compact(inputBytes.length);\n sink.bytes(inputBytes);\n\n return sink.toHex();\n}\n","/**\n * Decoding utilities for ContractsApi_call response\n */\n\nimport { Src } from \"@subsquid/scale-codec\";\nimport { type Codec, u128, Tuple } from \"@polkadot-api/substrate-bindings\";\n\n/**\n * Gas information from contract execution\n */\nexport interface GasInfo {\n /** Gas consumed during execution */\n gasConsumed: { refTime: bigint; proofSize: bigint };\n /** Gas required for execution */\n gasRequired: { refTime: bigint; proofSize: bigint };\n}\n\n/**\n * Storage deposit information\n */\nexport interface StorageDepositInfo {\n /** Storage deposit type: 0 = Refund, 1 = Charge */\n type: \"Refund\" | \"Charge\";\n /** Amount of storage deposit */\n amount: bigint;\n}\n\n/**\n * Full decoded result from ContractsApi_call\n */\nexport interface ContractCallResult {\n /** Gas information */\n gas: GasInfo;\n /** Storage deposit information */\n storageDeposit: StorageDepositInfo;\n /** Debug message (if any) */\n debugMessage: string;\n /** Whether the execution was successful */\n success: boolean;\n /** Execution flags */\n flags: number;\n /** The raw execution result bytes (still wrapped in Result<T, LangError>) */\n data: Uint8Array;\n}\n\n/**\n * Decode the raw ContractsApi_call response.\n *\n * The response format is:\n * - gasConsumed: Weight { ref_time: Compact<u64>, proof_size: Compact<u64> }\n * - gasRequired: Weight\n * - storageDeposit: StorageDeposit { variant: u8, amount: u128 }\n * - debugMessage: String\n * - result: Result<ExecReturnValue, DispatchError>\n * - ExecReturnValue: { flags: u32, data: Vec<u8> }\n *\n * @param result - The raw response bytes from state_call ContractsApi_call\n * @returns Decoded contract call result\n */\nexport function decodeContractCallResult(result: Uint8Array): ContractCallResult {\n const src = new Src(result);\n\n // gasConsumed: Weight\n const gasConsumedRefTime = BigInt(src.compact());\n const gasConsumedProofSize = BigInt(src.compact());\n\n // gasRequired: Weight\n const gasRequiredRefTime = BigInt(src.compact());\n const gasRequiredProofSize = BigInt(src.compact());\n\n // storageDeposit: StorageDeposit\n const storageDepositVariant = src.u8();\n const storageDepositAmount = src.u128();\n\n // debugMessage: String\n const debugMessage = src.str();\n\n // result: Result<ExecReturnValue, DispatchError>\n const resultVariant = src.u8(); // 0 = Ok, 1 = Err\n const success = resultVariant === 0;\n\n // ExecReturnValue: { flags: u32, data: Vec<u8> }\n const flags = src.u32();\n const data = src.bytes(src.compactLength());\n\n return {\n gas: {\n gasConsumed: {\n refTime: gasConsumedRefTime,\n proofSize: gasConsumedProofSize,\n },\n gasRequired: {\n refTime: gasRequiredRefTime,\n proofSize: gasRequiredProofSize,\n },\n },\n storageDeposit: {\n type: storageDepositVariant === 0 ? \"Refund\" : \"Charge\",\n amount: storageDepositAmount,\n },\n debugMessage,\n success,\n flags,\n data,\n };\n}\n\n/**\n * Legacy function - decode and return just the exec result data.\n * @deprecated Use decodeContractCallResult for full information\n */\nexport function decodeResult(result: Uint8Array): Uint8Array {\n const decoded = decodeContractCallResult(result);\n return decoded.data;\n}\n\n/**\n * Unwrap the inner value from Result<T, LangError> by checking the variant byte.\n *\n * Ink contracts wrap their return values in Result<T, LangError>.\n * This function handles the unwrapping and throws an error for LangError.\n *\n * @param data - The exec result bytes (Result<T, LangError> encoded)\n * @returns The inner value bytes (T encoded)\n * @throws Error if the result is Err variant (LangError)\n */\nexport function unwrapInkResult(data: Uint8Array): Uint8Array {\n if (data.length === 0) {\n throw new Error(\"Empty result data\");\n }\n\n const variant = data[0];\n\n if (variant === 0) {\n // Ok variant - return the inner data (skip the variant byte)\n return data.slice(1);\n } else if (variant === 1) {\n // Err variant - LangError\n throw new Error(\"Contract call returned LangError\");\n } else {\n throw new Error(`Unknown result variant: ${variant}`);\n }\n}\n\n/**\n * Check if the result indicates a LangError\n *\n * @param data - The exec result bytes\n * @returns True if it's a LangError (Err variant)\n */\nexport function isLangError(data: Uint8Array): boolean {\n return data.length > 0 && data[0] === 1;\n}\n\n/**\n * Decode ink contract message result using a custom SCALE codec.\n * This bypasses polkadot-api's ink decoder which has issues with LangError type.\n *\n * @param data - The exec result bytes (Result<T, LangError> encoded)\n * @param codec - The SCALE codec for the inner value type T\n * @returns The decoded value\n */\nexport function decodeInkValue<T>(data: Uint8Array, codec: Codec<T>): T {\n const innerData = unwrapInkResult(data);\n return codec.dec(innerData);\n}\n\n/**\n * Pre-defined codecs for common types\n */\nexport const InkCodecs = {\n /** u128 codec for Balance type */\n u128,\n /** Tuple of two u128 values, commonly used for (Balance, Balance) */\n balancePair: Tuple(u128, u128),\n};\n","/**\n * Auto-build SCALE decoders from ink metadata type definitions.\n *\n * This module provides a way to automatically construct decoders for ink contract\n * message return types without manually specifying codecs for each message.\n */\n\nimport {\n u8,\n u16,\n u32,\n u64,\n u128,\n i8,\n i16,\n i32,\n i64,\n i128,\n bool,\n str,\n Bytes,\n Vector,\n Tuple,\n Struct,\n Variant,\n _void,\n Option,\n AccountId,\n type Codec,\n} from \"@polkadot-api/substrate-bindings\";\nimport type { InkMetadata } from \"@polkadot-api/ink-contracts\";\nimport { blake2b } from \"@noble/hashes/blake2.js\";\n\n// Use 'any' for dynamic codec building to avoid TypeScript strict type issues\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\n\n/**\n * Type definition from ink metadata\n */\ninterface TypeDef {\n primitive?: string;\n composite?: {\n fields: Array<{\n name?: string;\n type: number;\n typeName?: string;\n }>;\n };\n variant?: {\n variants: Array<{\n name: string;\n index: number;\n fields: Array<{\n name?: string;\n type: number;\n typeName?: string;\n }>;\n }>;\n };\n sequence?: {\n type: number;\n };\n array?: {\n len: number;\n type: number;\n };\n tuple?: number[];\n}\n\ninterface TypeEntry {\n id: number;\n type: {\n def: TypeDef;\n path?: string[];\n params?: Array<{\n name: string;\n type?: number;\n }>;\n };\n}\n\n/**\n * Cache for built codecs to avoid rebuilding the same type\n */\ntype CodecCache = Map<number, AnyCodec>;\n\n/**\n * Build a SCALE codec from ink metadata type definition\n */\nfunction buildCodecFromType(\n typeId: number,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n // Check cache first\n const cached = cache.get(typeId);\n if (cached) {\n return cached;\n }\n\n const typeEntry = types.find((t) => t.id === typeId);\n if (!typeEntry) {\n throw new Error(`Type ${typeId} not found in metadata`);\n }\n\n const def = typeEntry.type.def;\n const path = typeEntry.type.path;\n\n // Handle primitive types\n if (def.primitive) {\n const codec = buildPrimitiveCodec(def.primitive);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle special path types (AccountId, Hash, etc.)\n if (path && path.length > 0) {\n const specialCodec = buildSpecialTypeCodec(path, typeEntry, types, cache);\n if (specialCodec) {\n cache.set(typeId, specialCodec);\n return specialCodec;\n }\n }\n\n // Handle tuple\n if (def.tuple) {\n const codec = buildTupleCodec(def.tuple, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle sequence (Vec<T>)\n if (def.sequence) {\n const innerCodec = buildCodecFromType(def.sequence.type, types, cache);\n const codec = Vector(innerCodec);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle array [T; N]\n if (def.array) {\n const innerCodec = buildCodecFromType(def.array.type, types, cache);\n // For fixed-size byte arrays, use Bytes\n if (def.array.type === findPrimitiveTypeId(types, \"u8\")) {\n const codec = Bytes(def.array.len);\n cache.set(typeId, codec);\n return codec;\n }\n // For other arrays, use Vector with fixed length validation\n const codec = Vector(innerCodec, def.array.len);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle composite (struct)\n if (def.composite) {\n const codec = buildCompositeCodec(def.composite, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle variant (enum)\n if (def.variant) {\n const codec = buildVariantCodec(def.variant, path, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n throw new Error(\n `Unknown type definition for type ${typeId}: ${JSON.stringify(def)}`,\n );\n}\n\n/**\n * Build codec for primitive types\n */\nfunction buildPrimitiveCodec(primitive: string): AnyCodec {\n switch (primitive) {\n case \"u8\":\n return u8;\n case \"u16\":\n return u16;\n case \"u32\":\n return u32;\n case \"u64\":\n return u64;\n case \"u128\":\n return u128;\n case \"i8\":\n return i8;\n case \"i16\":\n return i16;\n case \"i32\":\n return i32;\n case \"i64\":\n return i64;\n case \"i128\":\n return i128;\n case \"bool\":\n return bool;\n case \"str\":\n return str;\n default:\n throw new Error(`Unknown primitive type: ${primitive}`);\n }\n}\n\n/**\n * Build codec for special types based on path\n */\nfunction buildSpecialTypeCodec(\n path: string[],\n typeEntry: TypeEntry,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec | null {\n const fullPath = path.join(\"::\");\n\n // AccountId type\n if (fullPath.includes(\"AccountId\")) {\n return AccountId();\n }\n\n // Option type\n if (path[0] === \"Option\") {\n const params = typeEntry.type.params;\n if (params && params.length > 0 && params[0]?.type !== undefined) {\n const innerCodec = buildCodecFromType(params[0].type, types, cache);\n return Option(innerCodec);\n }\n }\n\n // Result type - we need special handling\n if (path[0] === \"Result\") {\n const params = typeEntry.type.params;\n if (params && params.length >= 2) {\n const okTypeId = params[0]?.type;\n const errTypeId = params[1]?.type;\n if (okTypeId !== undefined && errTypeId !== undefined) {\n const okCodec = buildCodecFromType(okTypeId, types, cache);\n const errCodec = buildCodecFromType(errTypeId, types, cache);\n // Build a proper Result variant\n return Variant(\n {\n Ok: okCodec,\n Err: errCodec,\n },\n [0, 1],\n );\n }\n }\n }\n\n return null;\n}\n\n/**\n * Build codec for tuple types\n */\nfunction buildTupleCodec(\n tupleTypes: number[],\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n if (tupleTypes.length === 0) {\n return _void;\n }\n\n const innerCodecs = tupleTypes.map((t) => buildCodecFromType(t, types, cache));\n\n // Handle different tuple sizes\n switch (innerCodecs.length) {\n case 1:\n return Tuple(innerCodecs[0]!);\n case 2:\n return Tuple(innerCodecs[0]!, innerCodecs[1]!);\n case 3:\n return Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!);\n case 4:\n return Tuple(\n innerCodecs[0]!,\n innerCodecs[1]!,\n innerCodecs[2]!,\n innerCodecs[3]!,\n );\n default:\n // For larger tuples, use dynamic tuple (cast to any)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (Tuple as any)(...innerCodecs);\n }\n}\n\n/**\n * Build codec for composite (struct) types\n */\nfunction buildCompositeCodec(\n composite: NonNullable<TypeDef[\"composite\"]>,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n const fields = composite.fields;\n\n // Single unnamed field - unwrap it\n if (fields.length === 1 && !fields[0]?.name) {\n return buildCodecFromType(fields[0]!.type, types, cache);\n }\n\n // Multiple fields - build a struct\n const structDef: Record<string, AnyCodec> = {};\n for (const field of fields) {\n const fieldName = field.name || `field${fields.indexOf(field)}`;\n structDef[fieldName] = buildCodecFromType(field.type, types, cache);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Struct(structDef as any);\n}\n\n/**\n * Build codec for variant (enum) types\n */\nfunction buildVariantCodec(\n variant: NonNullable<TypeDef[\"variant\"]>,\n path: string[] | undefined,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n const variants = variant.variants;\n\n // Check if this is a LangError type (ink specific)\n const isLangError = path?.includes(\"LangError\");\n\n // Build variant definition\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const variantDef: Record<string, any> = {};\n const indices: number[] = [];\n\n // For LangError, add a placeholder for index 0 if missing\n if (isLangError && !variants.some((v) => v.index === 0)) {\n variantDef[\"_Placeholder\"] = _void;\n indices.push(0);\n }\n\n for (const v of variants) {\n let fieldCodec: AnyCodec;\n\n // Handle variants with no fields or undefined fields\n const fields = v.fields ?? [];\n\n if (fields.length === 0) {\n fieldCodec = _void;\n } else if (fields.length === 1 && !fields[0]?.name) {\n // Single unnamed field\n fieldCodec = buildCodecFromType(fields[0]!.type, types, cache);\n } else {\n // Multiple or named fields - build struct\n const structDef: Record<string, AnyCodec> = {};\n for (const field of fields) {\n const fieldName = field.name || `field${fields.indexOf(field)}`;\n structDef[fieldName] = buildCodecFromType(field.type, types, cache);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fieldCodec = Struct(structDef as any);\n }\n\n variantDef[v.name] = fieldCodec;\n indices.push(v.index);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Variant(variantDef as any, indices as any);\n}\n\n/**\n * Find the type ID for a primitive type\n */\nfunction findPrimitiveTypeId(types: TypeEntry[], primitive: string): number {\n const entry = types.find((t) => t.type.def.primitive === primitive);\n return entry?.id ?? -1;\n}\n\n/**\n * Extract the inner type from Result<T, LangError>\n * Returns the type ID of T\n */\nfunction extractResultInnerType(typeEntry: TypeEntry): number | null {\n const path = typeEntry.type.path;\n if (!path || path[0] !== \"Result\") {\n return null;\n }\n\n const params = typeEntry.type.params;\n if (!params || params.length < 1) {\n return null;\n }\n\n return params[0]?.type ?? null;\n}\n\n/**\n * Build a decoder for a message's return type from ink metadata.\n * This handles the Result<T, LangError> wrapper and returns a decoder for T.\n *\n * @param metadata - The ink contract metadata\n * @param messageLabel - The message label (e.g., \"PSP22::balance_of\")\n * @returns A decoder function that decodes the inner value bytes\n */\nexport function buildMessageDecoder(\n metadata: InkMetadata,\n messageLabel: string,\n): (data: Uint8Array) => unknown {\n const types = metadata.types as TypeEntry[];\n const message = metadata.spec.messages.find((m) => m.label === messageLabel);\n\n if (!message) {\n throw new Error(`Message \"${messageLabel}\" not found in metadata`);\n }\n\n const returnTypeId = message.returnType.type;\n const returnTypeEntry = types.find((t) => t.id === returnTypeId);\n\n if (!returnTypeEntry) {\n throw new Error(\n `Return type ${returnTypeId} not found for message \"${messageLabel}\"`,\n );\n }\n\n const cache: CodecCache = new Map();\n\n // Check if it's a Result type and extract inner type\n const innerTypeId = extractResultInnerType(returnTypeEntry);\n\n if (innerTypeId !== null) {\n // Build decoder for the inner type (T in Result<T, LangError>)\n const innerCodec = buildCodecFromType(innerTypeId, types, cache);\n return (data: Uint8Array) => innerCodec.dec(data);\n }\n\n // Not a Result type, build decoder for the full return type\n const codec = buildCodecFromType(returnTypeId, types, cache);\n return (data: Uint8Array) => codec.dec(data);\n}\n\n/**\n * Build decoders for all messages in the metadata.\n * Returns a Map of message label -> decoder function.\n */\nexport function buildAllMessageDecoders(\n metadata: InkMetadata,\n): Map<string, (data: Uint8Array) => unknown> {\n const decoders = new Map<string, (data: Uint8Array) => unknown>();\n\n for (const message of metadata.spec.messages as Array<{ label: string }>) {\n try {\n const decoder = buildMessageDecoder(metadata, message.label);\n decoders.set(message.label, decoder);\n } catch (error) {\n console.warn(\n `Failed to build decoder for message \"${message.label}\":`,\n error,\n );\n }\n }\n\n return decoders;\n}\n\n/**\n * Create a codec registry compatible with ResponseDecoder type\n */\nexport function createCodecRegistry(\n metadata: InkMetadata,\n): Map<string, { dec: (data: Uint8Array) => unknown }> {\n const decoders = buildAllMessageDecoders(metadata);\n const registry = new Map<string, { dec: (data: Uint8Array) => unknown }>();\n\n for (const [label, decoder] of decoders) {\n registry.set(label, { dec: decoder });\n }\n\n return registry;\n}\n\n/**\n * Build a SCALE decoder for a contract event from ink metadata\n *\n * @param metadata - The ink contract metadata\n * @param eventLabel - The event label (e.g., \"Transfer\", \"Approval\")\n * @returns A decoder function that decodes the event data bytes\n */\nexport function buildEventDecoder(\n metadata: InkMetadata,\n eventLabel: string,\n): (data: Uint8Array) => unknown {\n const types = metadata.types as TypeEntry[];\n const events = metadata.spec.events as Array<{\n label: string;\n args: Array<{\n label: string;\n type: { type: number };\n }>;\n }>;\n\n const event = events.find((e) => e.label === eventLabel);\n\n if (!event) {\n throw new Error(`Event \"${eventLabel}\" not found in metadata`);\n }\n\n const cache: CodecCache = new Map();\n\n // Build struct codec from event args\n const structDef: Record<string, AnyCodec> = {};\n\n for (const arg of event.args) {\n const fieldName = arg.label;\n const fieldCodec = buildCodecFromType(arg.type.type, types, cache);\n structDef[fieldName] = fieldCodec;\n }\n\n // If event has no args, return void decoder\n if (event.args.length === 0) {\n return () => undefined;\n }\n\n // If event has single unnamed arg, unwrap it\n if (event.args.length === 1) {\n const argCodec = structDef[event.args[0]!.label];\n return (data: Uint8Array) => argCodec!.dec(data);\n }\n\n // Multiple args - return struct\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const codec = Struct(structDef as any);\n return (data: Uint8Array) => codec.dec(data);\n}\n\n/**\n * Build decoders for all events in the metadata\n *\n * @param metadata - The ink contract metadata\n * @returns Map of event label -> decoder function\n */\nexport function buildAllEventDecoders(\n metadata: InkMetadata,\n): Map<string, (data: Uint8Array) => unknown> {\n const decoders = new Map<string, (data: Uint8Array) => unknown>();\n\n const events = metadata.spec.events as Array<{ label: string }>;\n\n for (const event of events) {\n try {\n const decoder = buildEventDecoder(metadata, event.label);\n decoders.set(event.label, decoder);\n } catch (error) {\n console.warn(`Failed to build decoder for event \"${event.label}\":`, error);\n }\n }\n\n return decoders;\n}\n\n/**\n * Get event signature (topic[0]) for filtering\n * Events in ink! use blake2_256 hash of event label as topic[0]\n *\n * @param eventLabel - The event label (e.g., \"Transfer\")\n * @returns Event signature as Uint8Array (32 bytes)\n */\nexport function getEventSignature(eventLabel: string): Uint8Array {\n return blake2b(new TextEncoder().encode(eventLabel), { dkLen: 32 });\n}\n\n/**\n * Create ASCII-encoded event topic (D9 chain format)\n *\n * D9 chain uses a format where:\n * - First byte is 0x00 (null)\n * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`\n * - Total is exactly 32 bytes (truncated/padded as needed)\n *\n * @param contractName - Contract name (e.g., \"MarketMaker\", \"Usdt\")\n * @param eventLabel - Event label (e.g., \"Transfer\", \"USDTToD9Conversion\")\n * @returns 32-byte topic with null prefix and ASCII-encoded path\n */\nexport function createAsciiEventTopic(\n contractName: string,\n eventLabel: string,\n): Uint8Array {\n const topic = new Uint8Array(32);\n topic[0] = 0; // Null prefix\n const encoder = new TextEncoder();\n const fullPath = `${contractName}::${eventLabel}`;\n const encoded = encoder.encode(fullPath);\n // Copy up to 31 bytes (leaving room for null prefix)\n topic.set(encoded.slice(0, 31), 1);\n return topic;\n}\n","/**\n * Event parsing and filtering for ink! contracts\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n\tEvent as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport type { Enum, SS58String } from \"polkadot-api\";\nimport { ss58Decode } from \"@polkadot-labs/hdkd-helpers\";\nimport {\n\tbuildAllEventDecoders,\n\tbuildEventDecoder,\n\tgetEventSignature,\n} from \"./codec-builder\";\nimport type {\n\tTypedContractEvent,\n\tEventFilterOptions,\n\tRawContractEvent,\n\tExtractEnumDef,\n\tExtractEventLabels,\n} from \"./event-types\";\n\n/**\n * Type-safe event parser for a specific contract\n *\n * @typeParam S - The storage descriptor type\n * @typeParam M - The messages descriptor type\n * @typeParam C - The constructors descriptor type\n * @typeParam E - The event type representing all possible events for this contract\n */\nexport class ContractEventParser<\n\tS extends InkStorageDescriptor = InkStorageDescriptor,\n\tM extends InkCallableDescriptor = InkCallableDescriptor,\n\tC extends InkCallableDescriptor = InkCallableDescriptor,\n\tE extends InkEvent = InkEvent,\n> {\n\tprivate eventDecoders: Map<string, (data: Uint8Array) => unknown>;\n\tprivate eventSignatures: Map<string, Uint8Array>;\n\tprivate contractAddressBytes: Uint8Array;\n\tprivate contractAddress: SS58String;\n\tprivate metadata: InkMetadata;\n\n\tconstructor(\n\t\tdescriptor: InkDescriptors<S, M, C, E>,\n\t\tcontractAddress: SS58String,\n\t) {\n\t\tif (!descriptor.metadata) {\n\t\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t\t}\n\t\tthis.metadata = descriptor.metadata;\n\t\tthis.contractAddress = contractAddress;\n\t\tthis.eventDecoders = buildAllEventDecoders(this.metadata);\n\t\tthis.contractAddressBytes = ss58Decode(contractAddress)[0];\n\n\t\t// Build signature map for topic filtering\n\t\tthis.eventSignatures = new Map();\n\t\tconst events = this.metadata.spec.events as Array<{ label: string }>;\n\n\t\tfor (const event of events) {\n\t\t\tconst sig = getEventSignature(event.label);\n\t\t\tthis.eventSignatures.set(event.label, sig);\n\t\t}\n\t}\n\n\t/**\n\t * Parse a raw chain event into a type-safe contract event (if it matches)\n\t * Returns null if the event is not from this contract or cannot be parsed\n\t *\n\t * @example\n\t * ```ts\n\t * const event = parser.parseEvent(chainEvent);\n\t * if (event?.type === \"Transfer\") {\n\t * // event.value is now typed as { from: SS58String; to: SS58String; value: bigint }\n\t * console.log(event.value.from);\n\t * }\n\t * ```\n\t */\n\tparseEvent(chainEvent: unknown): TypedContractEvent<E> | null {\n\t\t// Extract Contracts.ContractEmitted event from chain event\n\t\tconst extracted = this.extractContractEmittedEvent(chainEvent);\n\t\tif (!extracted) return null;\n\n\t\tconst { contract, data, topics, blockNumber, blockHash, eventIndex } =\n\t\t\textracted;\n\n\t\t// Filter by contract address\n\t\tif (!this.bytesEqual(contract, this.contractAddressBytes)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode event based on topic[0] signature\n\t\tif (topics.length === 0) return null;\n\n\t\tconst signature = topics[0];\n\t\tlet eventLabel: string | null = null;\n\n\t\t// Method 1: Try ASCII extraction (D9 chain format)\n\t\t// D9 chain uses format: \\0ContractName::EventLabel (32 bytes, null-prefixed)\n\t\teventLabel = this.extractEventLabelFromAsciiTopic(signature!);\n\n\t\t// Verify the extracted label has a decoder\n\t\tif (eventLabel && !this.eventDecoders.has(eventLabel)) {\n\t\t\teventLabel = null;\n\t\t}\n\n\t\t// Method 2: Fall back to blake2 signature matching (standard ink! format)\n\t\tif (!eventLabel) {\n\t\t\tfor (const [label, sig] of this.eventSignatures) {\n\t\t\t\tif (this.bytesEqual(signature!, sig)) {\n\t\t\t\t\teventLabel = label;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!eventLabel) {\n\t\t\tconsole.warn(\"Unknown event signature:\", signature);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst decoder = this.eventDecoders.get(eventLabel);\n\t\tif (!decoder) {\n\t\t\tconsole.warn(`No decoder for event ${eventLabel}`);\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tconst decodedData = decoder(data);\n\t\t\treturn {\n\t\t\t\ttype: eventLabel,\n\t\t\t\tvalue: decodedData,\n\t\t\t\traw: {\n\t\t\t\t\tblockNumber,\n\t\t\t\t\tblockHash,\n\t\t\t\t\teventIndex,\n\t\t\t\t\tcontractAddress: this.getContractAddress(),\n\t\t\t\t\tdata,\n\t\t\t\t\ttopics,\n\t\t\t\t},\n\t\t\t} as TypedContractEvent<E>;\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to decode event ${eventLabel}:`, error);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Extract event label from ASCII-encoded topic (D9 chain format)\n\t *\n\t * D9 chain uses a format where:\n\t * - First byte is 0x00 (null)\n\t * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`\n\t * - Total is exactly 32 bytes (truncated/padded as needed)\n\t *\n\t * @param topic - The 32-byte topic from the event\n\t * @returns The extracted event label, or null if not in ASCII format\n\t */\n\tprivate extractEventLabelFromAsciiTopic(topic: Uint8Array): string | null {\n\t\tif (topic.length !== 32) return null;\n\n\t\t// D9 format: first byte is null (0x00)\n\t\tif (topic[0] !== 0) return null;\n\n\t\t// Decode ASCII (skip null prefix, trim trailing nulls)\n\t\tconst ascii = new TextDecoder()\n\t\t\t.decode(topic.slice(1))\n\t\t\t.replace(/\\0+$/, \"\");\n\n\t\t// Extract label after \"::\"\n\t\tconst colonIndex = ascii.lastIndexOf(\"::\");\n\t\tif (colonIndex !== -1) {\n\t\t\treturn ascii.slice(colonIndex + 2);\n\t\t}\n\n\t\t// No \"::\" found, use entire string as label\n\t\treturn ascii || null;\n\t}\n\n\t/**\n\t * Filter a batch of events and return type-safe results\n\t *\n\t * @param chainEvents - Array of chain events to filter\n\t * @param options - Optional filter criteria\n\t * @returns Array of type-safe contract events\n\t */\n\tfilterEvents(\n\t\tchainEvents: unknown[],\n\t\toptions?: EventFilterOptions,\n\t): TypedContractEvent<E>[] {\n\t\tconst results: TypedContractEvent<E>[] = [];\n\n\t\tfor (const chainEvent of chainEvents) {\n\t\t\tconst parsed = this.parseEvent(chainEvent);\n\t\t\tif (!parsed) continue;\n\n\t\t\t// Apply label filter\n\t\t\tif (options?.eventLabels && !options.eventLabels.includes(parsed.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Apply block range filter\n\t\t\tif (options?.fromBlock && parsed.raw.blockNumber < options.fromBlock) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (options?.toBlock && parsed.raw.blockNumber > options.toBlock) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresults.push(parsed);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Filter events by specific type with proper type narrowing\n\t *\n\t * This method provides better type safety than filterEvents with eventLabels\n\t * because TypeScript can narrow the return type to only the specified event type.\n\t *\n\t * @param chainEvents - Array of chain events to filter\n\t * @param label - The event label to filter by\n\t * @returns Array of events narrowed to the specific type\n\t *\n\t * @example\n\t * ```ts\n\t * const transfers = parser.filterByType(events, \"Transfer\");\n\t *\n\t * for (const t of transfers) {\n\t * // t.value is fully typed as Transfer event data\n\t * console.log(t.value.from, \"->\", t.value.to, \":\", t.value.value);\n\t * }\n\t * ```\n\t */\n\tfilterByType<L extends string>(\n\t\tchainEvents: unknown[],\n\t\tlabel: L,\n\t): Array<TypedContractEvent<E> & { type: L }> {\n\t\treturn this.filterEvents(chainEvents).filter(\n\t\t\t(e): e is TypedContractEvent<E> & { type: L } =>\n\t\t\t\t(e.type as string) === label,\n\t\t);\n\t}\n\n\t/**\n\t * Get the contract address as SS58 string\n\t */\n\tprivate getContractAddress(): SS58String {\n\t\treturn this.contractAddress;\n\t}\n\n\t/**\n\t * Extract ContractEmitted event from chain event structure\n\t * Based on polkadot-api event format\n\t */\n\tprivate extractContractEmittedEvent(chainEvent: unknown): {\n\t\tcontract: Uint8Array;\n\t\tdata: Uint8Array;\n\t\ttopics: Uint8Array[];\n\t\tblockNumber: number;\n\t\tblockHash: string;\n\t\teventIndex: number;\n\t} | null {\n\t\t// Type guard and extract event structure\n\t\tif (!chainEvent || typeof chainEvent !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst record = chainEvent as any;\n\n\t\t// Extract event data\n\t\tconst event = record.event;\n\t\tif (!event || typeof event !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Check if this is a Contracts pallet event\n\t\tif (event.type !== \"Contracts\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Check if this is a ContractEmitted event\n\t\tconst eventValue = event.value;\n\t\tif (!eventValue || typeof eventValue !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (eventValue.type !== \"ContractEmitted\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract contract address and data\n\t\tconst contractEmittedData = eventValue.value;\n\t\tif (!contractEmittedData || typeof contractEmittedData !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst contractRaw = contractEmittedData.contract;\n\t\tconst dataRaw = contractEmittedData.data;\n\n\t\t// Handle contract address: can be SS58 string or Uint8Array\n\t\tlet contract: Uint8Array;\n\t\tif (contractRaw instanceof Uint8Array) {\n\t\t\tcontract = contractRaw;\n\t\t} else if (typeof contractRaw === \"string\") {\n\t\t\t// SS58 string format\n\t\t\tcontract = ss58Decode(contractRaw)[0];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle data: can be Binary object (with asBytes()) or Uint8Array\n\t\tlet data: Uint8Array;\n\t\tif (dataRaw instanceof Uint8Array) {\n\t\t\tdata = dataRaw;\n\t\t} else if (\n\t\t\tdataRaw &&\n\t\t\ttypeof dataRaw === \"object\" &&\n\t\t\t\"asBytes\" in dataRaw &&\n\t\t\ttypeof dataRaw.asBytes === \"function\"\n\t\t) {\n\t\t\t// Binary object format\n\t\t\tdata = dataRaw.asBytes();\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract topics from the event record\n\t\t// Topics are typically stored in the event record, not in the event value\n\t\tconst topics: Uint8Array[] = [];\n\n\t\t// Polkadot-API typically stores topics at the record level\n\t\t// Topics can be Uint8Array or Binary objects (with asBytes())\n\t\tif (record.topics && Array.isArray(record.topics)) {\n\t\t\tfor (const topic of record.topics) {\n\t\t\t\tif (topic instanceof Uint8Array) {\n\t\t\t\t\ttopics.push(topic);\n\t\t\t\t} else if (\n\t\t\t\t\ttopic &&\n\t\t\t\t\ttypeof topic === \"object\" &&\n\t\t\t\t\t\"asBytes\" in topic &&\n\t\t\t\t\ttypeof topic.asBytes === \"function\"\n\t\t\t\t) {\n\t\t\t\t\t// Binary object format\n\t\t\t\t\ttopics.push(topic.asBytes());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extract block metadata\n\t\tconst blockNumber =\n\t\t\ttypeof record.blockNumber === \"number\" ? record.blockNumber : 0;\n\t\tconst blockHash =\n\t\t\ttypeof record.blockHash === \"string\" ? record.blockHash : \"\";\n\t\tconst eventIndex =\n\t\t\ttypeof record.eventIndex === \"number\" ? record.eventIndex : 0;\n\n\t\treturn {\n\t\t\tcontract,\n\t\t\tdata,\n\t\t\ttopics,\n\t\t\tblockNumber,\n\t\t\tblockHash,\n\t\t\teventIndex,\n\t\t};\n\t}\n\n\t/**\n\t * Compare two Uint8Arrays for equality\n\t */\n\tprivate bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n\t\tif (a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tif (a[i] !== b[i]) return false;\n\t\t}\n\t\treturn true;\n\t}\n}\n\n/**\n * Type guard for narrowing event types\n *\n * Use this function when you have a `TypedContractEvent` and need to\n * narrow it to a specific event type. This is useful when the type\n * information is lost (e.g., after serialization or in generic functions).\n *\n * @typeParam E - The Enum type representing all possible events\n * @typeParam L - The specific event label to check\n * @param event - The event to check\n * @param label - The event label to match\n * @returns True if the event type matches the label\n *\n * @example\n * ```ts\n * const event = parser.parseEvent(chainEvent);\n *\n * if (event && isEventType(event, \"Transfer\")) {\n * // TypeScript knows event.value is Transfer event data\n * console.log(event.value.from);\n * console.log(event.value.to);\n * console.log(event.value.value);\n * }\n * ```\n */\nexport function isEventType<\n\tE extends InkEvent,\n\tL extends ExtractEventLabels<E>,\n>(\n\tevent: TypedContractEvent<E>,\n\tlabel: L,\n): event is Extract<TypedContractEvent<E>, { type: L }> {\n\treturn event.type === label;\n}\n","/**\n * Event subscriptions using RxJS\n */\nimport { Observable, filter, map, mergeMap, share, from, of, catchError } from \"rxjs\";\nimport type { PolkadotClient, SS58String } from \"polkadot-api\";\nimport type {\n InkMetadata,\n InkDescriptors,\n InkStorageDescriptor,\n InkCallableDescriptor,\n Event as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport { ContractEventParser } from \"./events\";\nimport type { TypedContractEvent, EventSubscriptionOptions } from \"./event-types\";\n\n/**\n * Block info type for type safety\n */\ninterface BlockInfo {\n number: number;\n hash: string;\n}\n\n/**\n * Create an observable stream of contract events\n *\n * @param client - Polkadot API client\n * @param descriptor - Contract descriptor\n * @param options - Subscription options\n * @returns Observable stream of type-safe contract events\n */\nexport function createContractEventStream<\n S extends InkStorageDescriptor = InkStorageDescriptor,\n M extends InkCallableDescriptor = InkCallableDescriptor,\n C extends InkCallableDescriptor = InkCallableDescriptor,\n E extends InkEvent = InkEvent,\n>(\n client: PolkadotClient,\n descriptor: InkDescriptors<S, M, C, E>,\n options: EventSubscriptionOptions,\n): Observable<TypedContractEvent<E>> {\n const parser = new ContractEventParser<S, M, C, E>(descriptor, options.contractAddress);\n\n // Subscribe to finalized blocks\n return client.finalizedBlock$.pipe(\n // For each finalized block, fetch its events\n mergeMap(async (block: BlockInfo) => {\n try {\n // Fetch System.Events at this block using the provided callback\n const events = await options.getEvents(block.hash);\n return { block, events };\n } catch (error: unknown) {\n console.error(\n \"Error fetching events at block\",\n block.number,\n \":\",\n error instanceof Error ? error.message : String(error),\n );\n // Return empty events on error to keep stream alive\n return { block, events: [] as unknown[] };\n }\n }),\n\n // Parse and filter events for this contract\n map(({ block, events }) => {\n const parsedEvents = events\n .map((event, index) => {\n // Attach block metadata to each event before parsing\n const eventWithMeta = {\n ...(event as object),\n blockNumber: block.number,\n blockHash: block.hash,\n eventIndex: index,\n };\n return parser.parseEvent(eventWithMeta);\n })\n .filter((e): e is TypedContractEvent<E> => e !== null);\n\n return parsedEvents;\n }),\n\n // Flatten array of events to individual emissions\n mergeMap((events) => from(events)),\n\n // Filter by event labels if specified\n filter((event) => {\n if (!options.eventLabels) return true;\n return options.eventLabels.includes(event.type);\n }),\n\n // Handle errors gracefully\n catchError((error: unknown) => {\n console.error(\"Error in contract event stream:\", error);\n return of(); // Return empty observable on error\n }),\n\n // Share subscription among multiple subscribers\n share(),\n );\n}\n\n/**\n * PSP22 Transfer event type\n */\nexport interface PSP22TransferEvent {\n type: \"Transfer\";\n value: {\n from?: SS58String | null;\n to?: SS58String | null;\n value: bigint;\n };\n raw: {\n blockNumber: number;\n blockHash: string;\n eventIndex: number;\n contractAddress: SS58String;\n data: Uint8Array;\n topics: Uint8Array[];\n };\n}\n\n/**\n * Convenience helper to create a Transfer event stream for PSP22 tokens\n *\n * @param client - Polkadot API client\n * @param descriptor - PSP22 contract descriptor\n * @param contractAddress - PSP22 contract address\n * @param getEvents - Function to fetch System.Events at a block hash\n * @param watchAddress - Optional address to filter transfers (only events involving this address)\n * @returns Observable stream of Transfer events\n */\nexport function createPSP22TransferStream<\n S extends InkStorageDescriptor = InkStorageDescriptor,\n M extends InkCallableDescriptor = InkCallableDescriptor,\n C extends InkCallableDescriptor = InkCallableDescriptor,\n E extends InkEvent = InkEvent,\n>(\n client: PolkadotClient,\n descriptor: InkDescriptors<S, M, C, E>,\n contractAddress: SS58String,\n getEvents: (blockHash: string) => Promise<unknown[]>,\n watchAddress?: SS58String,\n): Observable<PSP22TransferEvent> {\n return createContractEventStream<S, M, C, E>(client, descriptor, {\n contractAddress,\n eventLabels: [\"Transfer\"],\n getEvents,\n }).pipe(\n filter((event) => {\n if (!watchAddress) return true;\n\n // Filter transfers where from=watchAddress or to=watchAddress\n const value = event.value as {\n from?: SS58String | null;\n to?: SS58String | null;\n value: bigint;\n };\n\n return value.from === watchAddress || value.to === watchAddress;\n }),\n ) as Observable<PSP22TransferEvent>;\n}\n\n/**\n * Create a native token (D9) transfer event stream\n *\n * This monitors System.Transfer events instead of contract events\n *\n * @param client - Polkadot API client\n * @param getEvents - Function to fetch System.Events at a block hash\n * @param watchAddress - Address to monitor for transfers\n * @returns Observable stream of native transfer events\n */\nexport function createNativeTransferStream(\n client: PolkadotClient,\n getEvents: (blockHash: string) => Promise<unknown[]>,\n watchAddress: SS58String,\n): Observable<{\n from: SS58String;\n to: SS58String;\n amount: bigint;\n blockNumber: number;\n blockHash: string;\n}> {\n return client.finalizedBlock$.pipe(\n // For each block, query system events\n mergeMap(async (block: any) => {\n try {\n const events = await getEvents(block.hash);\n return { block, events };\n } catch (error: unknown) {\n console.error(\n \"Error fetching events for native transfers:\",\n error instanceof Error ? error.message : String(error),\n );\n return { block, events: [] };\n }\n }),\n\n // Filter for Balances.Transfer events\n map(({ block, events }) => {\n const transfers = events\n .map((record: any) => {\n // Check if this is a Balances.Transfer event\n if (record.event?.type !== \"Balances\") return null;\n if (record.event?.value?.type !== \"Transfer\") return null;\n\n const { from, to, amount } = record.event.value.value;\n\n // Filter by watchAddress\n if (from !== watchAddress && to !== watchAddress) return null;\n\n return {\n from: from as SS58String,\n to: to as SS58String,\n amount: amount as bigint,\n blockNumber: block.number,\n blockHash: block.hash,\n };\n })\n .filter((t: any): t is NonNullable<typeof t> => t !== null);\n\n return transfers;\n }),\n\n // Flatten array to individual emissions\n mergeMap((transfers: any[]) => from(transfers)),\n\n // Handle errors\n catchError((error: unknown) => {\n console.error(\"Error in native transfer stream:\", error);\n return of();\n }),\n\n // Share subscription\n share(),\n );\n}\n","/**\n * Type-safe message builder for ink! contracts\n *\n * Provides a polkadot-api compatible API for encoding and decoding\n * contract messages with full TypeScript type inference.\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n} from \"@polkadot-api/ink-contracts\";\nimport { getInkLookup, getInkDynamicBuilder } from \"@polkadot-api/ink-contracts\";\nimport type { Enum } from \"polkadot-api\";\nimport { Binary } from \"polkadot-api\";\nimport type { ExtractMessageLabels } from \"./call-types\";\n\n/**\n * Message attributes from metadata\n */\nexport interface MessageAttributes {\n\t/** Whether the message mutates state */\n\tmutates: boolean;\n\t/** Whether the message is payable */\n\tpayable: boolean;\n\t/** Whether this is the default message */\n\tdefault: boolean;\n}\n\n/**\n * Type-safe message interface with encode/decode methods\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam L - The specific message label\n */\nexport interface TypedMessage<\n\tM extends InkCallableDescriptor,\n\tL extends keyof M & string,\n> {\n\t/**\n\t * Encode message arguments to Binary\n\t *\n\t * @param args - The message arguments (fully typed)\n\t * @returns Encoded call data as Binary\n\t *\n\t * @example\n\t * ```ts\n\t * const transfer = builder.message(\"PSP22::transfer\");\n\t * const encoded = transfer.encode({\n\t * to: recipientAddress,\n\t * value: 1000n,\n\t * data: new Uint8Array(),\n\t * });\n\t * ```\n\t */\n\tencode: {} extends M[L][\"message\"]\n\t\t? (args?: M[L][\"message\"]) => Binary\n\t\t: (args: M[L][\"message\"]) => Binary;\n\n\t/**\n\t * Decode response to typed value\n\t *\n\t * @param response - The response data\n\t * @returns Decoded response value\n\t */\n\tdecode: (response: Binary | Uint8Array) => M[L][\"response\"];\n\n\t/** Message attributes (mutates, payable, default) */\n\tattributes: MessageAttributes;\n\n\t/** 4-byte selector */\n\tselector: Uint8Array;\n\n\t/** Message label */\n\tlabel: L;\n}\n\n/**\n * Contract message builder interface\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n */\nexport interface ContractMessageBuilder<M extends InkCallableDescriptor> {\n\t/**\n\t * Get a type-safe message interface for a specific message\n\t *\n\t * @param label - The message label (e.g., \"PSP22::transfer\")\n\t * @returns Typed message interface with encode/decode methods\n\t *\n\t * @example\n\t * ```ts\n\t * const transfer = builder.message(\"PSP22::transfer\");\n\t * const encoded = transfer.encode({ to, value, data });\n\t * const decoded = transfer.decode(response);\n\t * ```\n\t */\n\tmessage<L extends ExtractMessageLabels<M>>(label: L): TypedMessage<M, L>;\n\n\t/**\n\t * Get all available message labels\n\t *\n\t * @returns Array of message labels\n\t */\n\tgetMessageLabels(): Array<ExtractMessageLabels<M>>;\n}\n\n/**\n * Internal message metadata from ink! spec\n */\ninterface MessageMetadata {\n\tlabel: string;\n\tselector: string;\n\tmutates: boolean;\n\tpayable: boolean;\n\tdefault: boolean;\n\targs: Array<{ label: string; type: { type: number } }>;\n\treturnType: { type: number };\n}\n\n/**\n * Create a type-safe message builder from a contract descriptor\n *\n * @typeParam S - Storage descriptor type\n * @typeParam M - Messages descriptor type\n * @typeParam C - Constructors descriptor type\n * @typeParam E - Events Enum type\n * @param descriptor - The ink! contract descriptor containing metadata\n * @returns A ContractMessageBuilder instance\n *\n * @example\n * ```ts\n * import { createMessageBuilder } from '@d9-network/ink';\n * import { contracts } from '@polkadot-api/descriptors';\n *\n * const builder = createMessageBuilder(contracts.usdt);\n *\n * // Get a typed message interface\n * const transfer = builder.message(\"PSP22::transfer\");\n *\n * // Encode with full type checking on args\n * const encoded = transfer.encode({\n * to: recipientAddress, // Must be SS58String\n * value: 1000000n, // Must be bigint\n * data: new Uint8Array(), // Must be Uint8Array\n * });\n *\n * // Decode response with full type inference\n * const response = transfer.decode(resultBytes);\n * ```\n */\nexport function createMessageBuilder<\n\tS extends InkStorageDescriptor,\n\tM extends InkCallableDescriptor,\n\tC extends InkCallableDescriptor,\n\tE extends Enum<any>,\n>(descriptor: InkDescriptors<S, M, C, E>): ContractMessageBuilder<M> {\n\tif (!descriptor.metadata) {\n\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t}\n\n\tconst metadata = descriptor.metadata;\n\tconst lookup = getInkLookup(metadata);\n\tconst builder = getInkDynamicBuilder(lookup);\n\n\t// Cache for built message codecs\n\ttype MessageCodec = ReturnType<typeof builder.buildMessage>;\n\tconst codecCache = new Map<string, MessageCodec>();\n\n\t// Parse message metadata\n\tconst messagesMetadata = new Map<string, MessageMetadata>();\n\tfor (const msg of metadata.spec.messages as MessageMetadata[]) {\n\t\tmessagesMetadata.set(msg.label, msg);\n\t}\n\n\tfunction getMessageCodec(label: string): MessageCodec {\n\t\tconst cached = codecCache.get(label);\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\t\tconst codec = builder.buildMessage(label);\n\t\tcodecCache.set(label, codec);\n\t\treturn codec;\n\t}\n\n\tfunction parseSelector(selectorHex: string): Uint8Array {\n\t\tconst hex = selectorHex.startsWith(\"0x\")\n\t\t\t? selectorHex.slice(2)\n\t\t\t: selectorHex;\n\t\treturn new Uint8Array(\n\t\t\thex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n\t\t);\n\t}\n\n\tfunction message<L extends ExtractMessageLabels<M>>(\n\t\tlabel: L,\n\t): TypedMessage<M, L> {\n\t\tconst msgMeta = messagesMetadata.get(label);\n\t\tif (!msgMeta) {\n\t\t\tthrow new Error(`Message \"${label}\" not found in metadata`);\n\t\t}\n\n\t\tconst codec = getMessageCodec(label);\n\t\tconst selector = parseSelector(msgMeta.selector);\n\n\t\tconst encode = (args?: M[L][\"message\"]): Binary => {\n\t\t\tconst encoded = codec.call.enc(\n\t\t\t\t(args ?? {}) as Parameters<typeof codec.call.enc>[0],\n\t\t\t);\n\t\t\treturn Binary.fromBytes(encoded);\n\t\t};\n\n\t\tconst decode = (response: Binary | Uint8Array): M[L][\"response\"] => {\n\t\t\tconst bytes =\n\t\t\t\tresponse instanceof Uint8Array ? response : response.asBytes();\n\t\t\treturn codec.value.dec(bytes) as M[L][\"response\"];\n\t\t};\n\n\t\treturn {\n\t\t\tencode: encode as TypedMessage<M, L>[\"encode\"],\n\t\t\tdecode,\n\t\t\tattributes: {\n\t\t\t\tmutates: msgMeta.mutates,\n\t\t\t\tpayable: msgMeta.payable,\n\t\t\t\tdefault: msgMeta.default,\n\t\t\t},\n\t\t\tselector,\n\t\t\tlabel,\n\t\t};\n\t}\n\n\tfunction getMessageLabels(): Array<ExtractMessageLabels<M>> {\n\t\treturn Array.from(messagesMetadata.keys()) as Array<ExtractMessageLabels<M>>;\n\t}\n\n\treturn {\n\t\tmessage,\n\t\tgetMessageLabels,\n\t};\n}\n","/**\n * Structured error types for contract operations.\n * Provides detailed error information for debugging and handling.\n */\n\n/**\n * Error types for contract operations\n */\nexport type ContractErrorType =\n | \"METADATA_ERROR\" // Missing or invalid contract metadata\n | \"ENCODE_ERROR\" // Failed to encode call data\n | \"DECODE_ERROR\" // Failed to decode response\n | \"NETWORK_ERROR\" // Network or RPC error\n | \"CONTRACT_ERROR\" // Contract returned an error\n | \"LANG_ERROR\" // Ink LangError (CouldNotReadInput, etc.)\n | \"TIMEOUT_ERROR\" // Request timeout\n | \"ABORTED\" // Request was aborted\n | \"SIGNER_ERROR\" // Signer related error\n | \"TX_ERROR\"; // Transaction submission error\n\n/**\n * Base error class for all contract-related errors\n */\nexport class ContractError extends Error {\n public readonly timestamp: Date;\n\n public override readonly cause?: Error;\n\n constructor(\n message: string,\n public readonly type: ContractErrorType,\n public readonly label?: string,\n public readonly details?: unknown,\n cause?: Error,\n ) {\n super(message, { cause });\n this.name = \"ContractError\";\n this.timestamp = new Date();\n\n // Maintains proper stack trace for where error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ContractError);\n }\n }\n\n /**\n * Create a formatted error message for logging\n */\n toLogString(): string {\n const parts = [\n `[${this.type}]`,\n this.label ? `${this.label}:` : \"\",\n this.message,\n ].filter(Boolean);\n\n if (this.details) {\n parts.push(`Details: ${JSON.stringify(this.details)}`);\n }\n\n return parts.join(\" \");\n }\n\n /**\n * Convert to a plain object for serialization\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n type: this.type,\n message: this.message,\n label: this.label,\n details: this.details,\n timestamp: this.timestamp.toISOString(),\n stack: this.stack,\n };\n }\n}\n\n/**\n * Error thrown when contract metadata is missing or invalid\n */\nexport class MetadataError extends ContractError {\n constructor(message: string, details?: unknown) {\n super(message, \"METADATA_ERROR\", undefined, details);\n this.name = \"MetadataError\";\n }\n}\n\n/**\n * Error thrown when encoding call data fails\n */\nexport class EncodeError extends ContractError {\n constructor(label: string, message: string, details?: unknown) {\n super(message, \"ENCODE_ERROR\", label, details);\n this.name = \"EncodeError\";\n }\n}\n\n/**\n * Error thrown when decoding response fails\n */\nexport class DecodeError extends ContractError {\n constructor(label: string, message: string, details?: unknown) {\n super(message, \"DECODE_ERROR\", label, details);\n this.name = \"DecodeError\";\n }\n}\n\n/**\n * Error thrown for network/RPC errors\n */\nexport class NetworkError extends ContractError {\n constructor(message: string, cause?: Error, details?: unknown) {\n super(message, \"NETWORK_ERROR\", undefined, details, cause);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Error thrown when contract returns an error result\n */\nexport class ContractExecutionError extends ContractError {\n constructor(\n label: string,\n public readonly errorValue: unknown,\n ) {\n super(\n `Contract execution failed: ${JSON.stringify(errorValue)}`,\n \"CONTRACT_ERROR\",\n label,\n errorValue,\n );\n this.name = \"ContractExecutionError\";\n }\n}\n\n/**\n * Error thrown for Ink LangError\n */\nexport class LangError extends ContractError {\n constructor(\n label: string,\n public readonly variant: number,\n ) {\n const variantName =\n variant === 1 ? \"CouldNotReadInput\" : `Unknown(${variant})`;\n super(`Ink LangError: ${variantName}`, \"LANG_ERROR\", label, {\n variant,\n variantName,\n });\n this.name = \"LangError\";\n }\n}\n\n/**\n * Error thrown when request times out\n */\nexport class TimeoutError extends ContractError {\n constructor(\n label: string,\n public readonly timeoutMs: number,\n ) {\n super(`Request timed out after ${timeoutMs}ms`, \"TIMEOUT_ERROR\", label, {\n timeoutMs,\n });\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Error thrown when request is aborted\n */\nexport class AbortedError extends ContractError {\n constructor(label: string, reason?: string) {\n super(reason || \"Request was aborted\", \"ABORTED\", label, { reason });\n this.name = \"AbortedError\";\n }\n}\n\n/**\n * Error thrown for signer-related issues\n */\nexport class SignerError extends ContractError {\n constructor(message: string, details?: unknown) {\n super(message, \"SIGNER_ERROR\", undefined, details);\n this.name = \"SignerError\";\n }\n}\n\n/**\n * Error thrown when transaction submission fails\n */\nexport class TransactionError extends ContractError {\n constructor(\n label: string,\n message: string,\n public readonly txHash?: string,\n details?: unknown,\n ) {\n super(message, \"TX_ERROR\", label, { ...(details as object), txHash });\n this.name = \"TransactionError\";\n }\n}\n\n/**\n * Type guard to check if an error is a ContractError\n */\nexport function isContractError(error: unknown): error is ContractError {\n return error instanceof ContractError;\n}\n\n/**\n * Type guard to check for specific error types\n */\nexport function isErrorType<T extends ContractErrorType>(\n error: unknown,\n type: T,\n): error is ContractError & { type: T } {\n return isContractError(error) && error.type === type;\n}\n","/**\n * D9 Ink Contract implementation\n *\n * Provides a type-safe interface for interacting with ink! smart contracts\n * using state_call + ContractsApi_call instead of ReviveApi.\n */\n\nimport type { PolkadotSigner, SS58String } from \"polkadot-api\";\nimport { Binary } from \"polkadot-api\";\nimport { fromHex } from \"polkadot-api/utils\";\nimport {\n getInkLookup,\n getInkDynamicBuilder,\n type InkDescriptors,\n type InkCallableDescriptor,\n type InkStorageDescriptor,\n type InkMetadata,\n type Event as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport { ss58Decode } from \"@polkadot-labs/hdkd-helpers\";\n\nimport type {\n D9InkContract,\n QueryOptions,\n QueryResult,\n SendOptions,\n SendableTransaction,\n TxResult,\n ContractStorage,\n CreateContractOptions,\n ResponseDecoder,\n} from \"./types\";\nimport { encodeContractCall } from \"./encode\";\nimport {\n decodeContractCallResult,\n unwrapInkResult,\n isLangError,\n} from \"./decode\";\nimport { createCodecRegistry } from \"./codec-builder\";\nimport { ContractEventParser } from \"./events\";\nimport { createContractEventStream } from \"./subscriptions\";\nimport type {\n TypedContractEvent,\n EventSubscriptionOptions,\n} from \"./event-types\";\nimport type { ExtractMessageLabels } from \"./call-types\";\nimport { createMessageBuilder, type TypedMessage } from \"./message-builder\";\nimport {\n ContractError,\n MetadataError,\n DecodeError,\n LangError,\n TimeoutError,\n AbortedError,\n TransactionError,\n} from \"./errors\";\n\n/**\n * Patch LangError type in ink metadata to fix the missing index 0 variant issue.\n * Uses structuredClone for efficient deep cloning.\n */\nfunction patchLangErrorInMetadata(metadata: InkMetadata): InkMetadata {\n const patched = structuredClone(metadata);\n\n for (const typeEntry of patched.types) {\n const path = typeEntry.type?.path;\n const def = typeEntry.type?.def as {\n variant?: {\n variants: Array<{\n index: number;\n name: string;\n fields: unknown[];\n docs: string[];\n }>;\n };\n };\n if (\n path &&\n Array.isArray(path) &&\n path.includes(\"LangError\") &&\n def?.variant\n ) {\n const variants = def.variant.variants;\n if (Array.isArray(variants)) {\n const hasIndex0 = variants.some((v) => v.index === 0);\n if (!hasIndex0) {\n variants.unshift({\n index: 0,\n name: \"_Placeholder\",\n fields: [],\n docs: [],\n });\n }\n }\n }\n }\n\n return patched;\n}\n\n/**\n * Convert SS58 address to bytes\n */\nfunction ss58ToBytes(address: SS58String): Uint8Array {\n const [publicKey] = ss58Decode(address);\n return publicKey;\n}\n\n/**\n * Create a promise that rejects after a timeout\n */\nfunction createTimeout<T>(\n ms: number,\n label: string,\n): { promise: Promise<T>; clear: () => void } {\n let timeoutId: ReturnType<typeof setTimeout>;\n const promise = new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new TimeoutError(label, ms));\n }, ms);\n });\n return {\n promise,\n clear: () => clearTimeout(timeoutId),\n };\n}\n\n/**\n * Check if AbortSignal is aborted and throw if so\n */\nfunction checkAborted(signal: AbortSignal | undefined, label: string): void {\n if (signal?.aborted) {\n throw new AbortedError(label, signal.reason);\n }\n}\n\n/**\n * Create a D9 Ink Contract instance\n */\nexport function createD9InkContract<\n S extends InkStorageDescriptor,\n M extends InkCallableDescriptor,\n C extends InkCallableDescriptor,\n E extends InkEvent,\n>(\n descriptor: InkDescriptors<S, M, C, E>,\n address: SS58String,\n options: CreateContractOptions,\n): D9InkContract<M, E> {\n const { client, typedApi, defaultQueryOptions = {}, defaultSendOptions = {} } = options;\n\n if (!descriptor.metadata) {\n throw new MetadataError(\"Contract descriptor must include metadata\");\n }\n\n // Patch and prepare metadata\n const patchedMetadata = patchLangErrorInMetadata(descriptor.metadata);\n const lookup = getInkLookup(patchedMetadata);\n const builder = getInkDynamicBuilder(lookup);\n\n // Create a patched descriptor with the patched metadata for internal use\n const patchedDescriptor = {\n ...descriptor,\n metadata: patchedMetadata,\n } as InkDescriptors<S, M, C, E>;\n\n // Build auto-generated codecs\n let codecRegistry: Map<string, ResponseDecoder>;\n try {\n codecRegistry = createCodecRegistry(patchedMetadata);\n } catch (error) {\n console.warn(\"Failed to auto-generate codecs from metadata:\", error);\n codecRegistry = new Map();\n }\n\n // Convert address to bytes\n const addressBytes = ss58ToBytes(address);\n\n // Cache for message codecs\n type MessageCodec = ReturnType<typeof builder.buildMessage>;\n const messageCodecCache = new Map<string, MessageCodec>();\n\n function getMessageCodec(label: string): MessageCodec {\n const cached = messageCodecCache.get(label);\n if (cached) {\n return cached;\n }\n const codec = builder.buildMessage(label);\n messageCodecCache.set(label, codec);\n return codec;\n }\n\n /**\n * Get the decoder for a message\n */\n function getDecoder(label: string): ResponseDecoder | null {\n return codecRegistry.get(label) ?? null;\n }\n\n /**\n * Execute a query (dry-run)\n */\n async function executeQuery<K extends keyof M & string>(\n method: K,\n queryOptions: QueryOptions<M[K][\"message\"]>,\n ): Promise<QueryResult<M[K][\"response\"]>> {\n const opts = { ...defaultQueryOptions, ...queryOptions };\n const { origin, args, value = 0n, signal, timeout, at } = opts;\n\n try {\n checkAborted(signal, method);\n\n const originBytes = ss58ToBytes(origin);\n const codec = getMessageCodec(method);\n\n // Encode the call\n const callData = codec.call.enc(\n (args ?? {}) as Parameters<typeof codec.call.enc>[0],\n );\n\n // Create the state_call message\n const message = encodeContractCall(\n originBytes,\n addressBytes,\n callData,\n value,\n );\n\n // Get block hash\n const blockHash = at ?? (await client.getFinalizedBlock()).hash;\n\n checkAborted(signal, method);\n\n // Execute state_call with optional timeout\n const executeCall = async () => {\n const response = (await client._request(\"state_call\", [\n \"ContractsApi_call\",\n message,\n blockHash,\n ])) as `0x${string}`;\n\n return fromHex(response);\n };\n\n let rawResponse: Uint8Array;\n if (timeout) {\n const { promise: timeoutPromise, clear } = createTimeout<Uint8Array>(\n timeout,\n method,\n );\n try {\n rawResponse = await Promise.race([executeCall(), timeoutPromise]);\n } finally {\n clear();\n }\n } else {\n rawResponse = await executeCall();\n }\n\n checkAborted(signal, method);\n\n // Decode the ContractsApi_call response\n const callResult = decodeContractCallResult(rawResponse);\n\n // Check for execution error\n if (!callResult.success) {\n return {\n success: false,\n error: new ContractError(\n `Contract execution failed: ${callResult.debugMessage}`,\n \"CONTRACT_ERROR\",\n method,\n ),\n };\n }\n\n // Check for LangError\n if (isLangError(callResult.data)) {\n return {\n success: false,\n error: new LangError(method, callResult.data[1] ?? 1),\n };\n }\n\n // Unwrap the Result<T, LangError>\n const innerData = unwrapInkResult(callResult.data);\n\n // Decode the response\n let decodedResponse: M[K][\"response\"];\n const decoder = getDecoder(method);\n\n if (decoder) {\n try {\n decodedResponse = decoder.dec(innerData) as M[K][\"response\"];\n } catch (decodeError) {\n console.warn(\"D9InkContract: Failed to decode response:\", decodeError);\n // Fall back to papi's value codec\n const fullResult = new Uint8Array(1 + innerData.length);\n fullResult[0] = 0; // Ok variant\n fullResult.set(innerData, 1);\n\n try {\n const papiResult = codec.value.dec(fullResult);\n if (\n papiResult !== null &&\n typeof papiResult === \"object\" &&\n \"success\" in papiResult &&\n \"value\" in papiResult\n ) {\n if (papiResult.success) {\n decodedResponse = papiResult.value as M[K][\"response\"];\n } else {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Contract returned error: ${JSON.stringify(papiResult.value)}`,\n papiResult.value,\n ),\n };\n }\n } else {\n decodedResponse = papiResult as M[K][\"response\"];\n }\n } catch (error) {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Failed to decode response: ${error instanceof Error ? error.message : String(error)}`,\n { error },\n ),\n };\n }\n }\n } else {\n // No custom decoder, use papi's codec\n const fullResult = new Uint8Array(1 + innerData.length);\n fullResult[0] = 0; // Ok variant\n fullResult.set(innerData, 1);\n\n const papiResult = codec.value.dec(fullResult);\n if (\n papiResult !== null &&\n typeof papiResult === \"object\" &&\n \"success\" in papiResult &&\n \"value\" in papiResult\n ) {\n if (papiResult.success) {\n decodedResponse = papiResult.value as M[K][\"response\"];\n } else {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Contract returned error: ${JSON.stringify(papiResult.value)}`,\n papiResult.value,\n ),\n };\n }\n } else {\n decodedResponse = papiResult as M[K][\"response\"];\n }\n }\n\n // Return success with QuerySuccessValue fields spread to same level\n return {\n success: true,\n value: decodedResponse,\n events: [],\n gasConsumed: callResult.gas.gasConsumed,\n gasRequired: callResult.gas.gasRequired,\n storageDeposit: callResult.storageDeposit.amount,\n send: () => createSendableTransaction(method, {\n origin,\n args,\n value,\n gasLimit: callResult.gas.gasRequired,\n }),\n };\n } catch (error) {\n if (error instanceof ContractError) {\n return { success: false, error };\n }\n return {\n success: false,\n error: new ContractError(\n error instanceof Error ? error.message : String(error),\n \"NETWORK_ERROR\",\n method,\n ),\n };\n }\n }\n\n /**\n * Create a sendable transaction\n */\n function createSendableTransaction<K extends keyof M & string>(\n method: K,\n sendOptions: SendOptions<M[K][\"message\"]>,\n ): SendableTransaction<M[K][\"response\"]> {\n const opts = { ...defaultSendOptions, ...sendOptions };\n const { origin, args, value = 0n, gasLimit, storageDepositLimit } = opts;\n\n const originBytes = ss58ToBytes(origin);\n const codec = getMessageCodec(method);\n\n // Encode the call\n const callData = codec.call.enc(\n (args ?? {}) as Parameters<typeof codec.call.enc>[0],\n );\n\n return {\n getEncodedData: () => callData,\n\n async signAndSubmit(signer: PolkadotSigner): Promise<TxResult<M[K][\"response\"]>> {\n if (!typedApi) {\n throw new TransactionError(\n method,\n \"typedApi is required for transaction submission. Pass typedApi in SDK options.\",\n );\n }\n\n try {\n // First do a dry-run to get gas estimate if not provided\n let gas = gasLimit;\n if (!gas) {\n const message = encodeContractCall(\n originBytes,\n addressBytes,\n callData,\n value,\n );\n const blockHash = (await client.getFinalizedBlock()).hash;\n const response = (await client._request(\"state_call\", [\n \"ContractsApi_call\",\n message,\n blockHash,\n ])) as `0x${string}`;\n const callResult = decodeContractCallResult(fromHex(response));\n gas = callResult.gas.gasRequired;\n }\n\n // Build the transaction using typedApi\n const api = typedApi as {\n tx: {\n Contracts: {\n call: (params: {\n dest: { type: \"Id\"; value: SS58String };\n value: bigint;\n gas_limit: { ref_time: bigint; proof_size: bigint };\n storage_deposit_limit: bigint | undefined;\n data: Binary;\n }) => {\n signAndSubmit: (\n signer: PolkadotSigner,\n options?: { at?: \"best\" | \"finalized\" }\n ) => Promise<{\n txHash: string;\n block: { hash: string; number: number };\n events: unknown[];\n }>;\n };\n };\n };\n };\n\n const tx = api.tx.Contracts.call({\n dest: { type: \"Id\", value: address },\n value,\n gas_limit: {\n ref_time: gas.refTime,\n proof_size: gas.proofSize,\n },\n storage_deposit_limit: storageDepositLimit,\n data: Binary.fromBytes(callData),\n });\n\n const txResult = await tx.signAndSubmit(signer, { at: \"finalized\" });\n\n return {\n ok: true,\n txHash: txResult.txHash,\n block: txResult.block,\n events: txResult.events ?? [],\n };\n } catch (error) {\n return {\n ok: false,\n txHash: \"\",\n block: { hash: \"\", number: 0 },\n events: [],\n dispatchError: error,\n };\n }\n },\n };\n }\n\n /**\n * Create send method that returns a sendable transaction\n */\n function send<K extends keyof M & string>(\n method: K,\n sendOptions: SendOptions<M[K][\"message\"]>,\n ): SendableTransaction<M[K][\"response\"]> {\n return createSendableTransaction(method, sendOptions);\n }\n\n /**\n * Create storage query interface\n */\n function getStorage(): ContractStorage {\n return {\n async getRoot() {\n // TODO: Implement storage root query\n console.warn(\"D9InkContract: getRoot not implemented\");\n return {\n success: false,\n value: new ContractError(\n \"Storage queries not yet implemented\",\n \"METADATA_ERROR\",\n ),\n };\n },\n\n async getNested(path: string, ..._keys: unknown[]) {\n // TODO: Implement nested storage query\n console.warn(\"D9InkContract: getNested not implemented\");\n return {\n success: false,\n value: new ContractError(\n `Storage query for \"${path}\" not yet implemented`,\n \"METADATA_ERROR\",\n ),\n };\n },\n };\n }\n\n /**\n * Filter events for this contract\n */\n function filterEvents(events: unknown[]): TypedContractEvent<E>[] {\n const parser = new ContractEventParser<S, M, C, E>(patchedDescriptor, address);\n return parser.filterEvents(events);\n }\n\n /**\n * Filter events by specific type with proper type narrowing\n */\n function filterEventsByType<L extends string>(\n events: unknown[],\n label: L,\n ): Array<TypedContractEvent<E> & { type: L }> {\n const parser = new ContractEventParser<S, M, C, E>(patchedDescriptor, address);\n return parser.filterByType(events, label);\n }\n\n // Create message builder for type-safe message encoding/decoding\n const messageBuilder = createMessageBuilder(descriptor);\n\n /**\n * Get a type-safe message interface\n */\n function message<L extends ExtractMessageLabels<M>>(\n label: L,\n ): TypedMessage<M, L> {\n return messageBuilder.message(label);\n }\n\n /**\n * Subscribe to contract events as an RxJS Observable\n *\n * @param options - Subscription options (contractAddress is automatically set)\n * @param options.getEvents - Function to fetch System.Events at a block hash\n * @param options.eventLabels - Optional filter for specific event names\n * @param options.fromBlock - Optional starting block number\n */\n function subscribeToEvents(\n options: Omit<EventSubscriptionOptions, \"contractAddress\">,\n ) {\n return createContractEventStream<S, M, C, E>(client, patchedDescriptor, {\n ...options,\n contractAddress: address,\n });\n }\n\n // Type assertion needed because the runtime correctly unwraps MessageResult\n // but TypeScript doesn't know that. The UnwrapMessageResult type in D9InkContract\n // matches what we actually return at runtime.\n return {\n address,\n metadata: patchedMetadata,\n query: executeQuery,\n send,\n getStorage,\n filterEvents,\n filterEventsByType,\n message,\n subscribeToEvents,\n } as D9InkContract<M, E>;\n}\n","/**\n * Type-safe RPC wrapper for PolkadotClient\n */\nimport type { PolkadotClient } from \"polkadot-api\";\nimport type { TypedRpcRequest } from \"./rpc-types\";\n\n/**\n * Create a type-safe RPC request function from a PolkadotClient\n *\n * This wraps the client's `_request` method with proper TypeScript types,\n * providing autocomplete for known RPC methods and type inference for\n * parameters and return values.\n *\n * @param client - The PolkadotClient instance\n * @returns A type-safe RPC request function\n *\n * @example\n * ```ts\n * const rpc = createTypedRpc(client);\n *\n * // Autocomplete for method names, typed params and return\n * const hash = await rpc(\"chain_getBlockHash\", [12345]);\n * // hash: HexString | null\n *\n * const header = await rpc(\"chain_getHeader\", [hash]);\n * // header: BlockHeader | null\n *\n * // Custom methods still work with explicit types\n * const custom = await rpc<MyType>(\"my_custom_method\", [arg]);\n * ```\n */\nexport function createTypedRpc(client: PolkadotClient): TypedRpcRequest {\n\treturn ((method: string, params: unknown[]) =>\n\t\tclient._request(method, params)) as TypedRpcRequest;\n}\n","/**\n * D9 Ink SDK entry point\n *\n * Creates an ink SDK that uses state_call + ContractsApi_call\n * instead of ReviveApi for chains that don't support it.\n */\n\nimport type { Enum, PolkadotClient, SS58String } from \"polkadot-api\";\nimport {\n type InkDescriptors,\n type InkCallableDescriptor,\n type InkStorageDescriptor,\n} from \"@polkadot-api/ink-contracts\";\n\nimport type {\n D9InkSdk,\n D9InkSdkOptions,\n D9InkContract,\n QueryOptions,\n SendOptions,\n} from \"./types\";\nimport type { TypedRpcRequest } from \"./rpc-types\";\nimport { createD9InkContract } from \"./contract\";\nimport { createTypedRpc } from \"./rpc\";\n\n/**\n * Options for creating D9 Ink SDK\n */\nexport interface CreateD9InkSdkOptions extends D9InkSdkOptions {\n /**\n * Typed API for transaction submission.\n * Required for submitting real transactions.\n */\n typedApi?: unknown;\n}\n\n/**\n * Extended D9 Ink SDK interface with typed RPC access\n */\nexport interface D9InkSdkWithRpc extends D9InkSdk {\n /**\n * Type-safe RPC request function\n *\n * Provides autocomplete for known Substrate RPC methods and type inference\n * for parameters and return values.\n *\n * @example\n * ```ts\n * // Known method with full type inference\n * const hash = await sdk.rpc(\"chain_getBlockHash\", [12345]);\n * // hash: HexString | null\n *\n * // Custom method with explicit types\n * const custom = await sdk.rpc<MyType>(\"custom_method\", [arg]);\n * ```\n */\n rpc: TypedRpcRequest;\n}\n\n/**\n * Create a D9 Ink SDK instance.\n *\n * This SDK provides a similar API to the official @polkadot-api/sdk-ink,\n * but uses state_call + ContractsApi_call instead of ReviveApi.\n *\n * @example\n * ```ts\n * import { createD9InkSdk } from \"@d9-network/ink\";\n * import { contracts } from \"@polkadot-api/descriptors\";\n *\n * const sdk = createD9InkSdk(client);\n * const usdtContract = sdk.getContract(\n * contracts.d9_usdt,\n * \"uLj9DRUujbpCyK7USZY5ebGbxdtKoWvdRvGyyUsoLWDsNng\"\n * );\n *\n * // Query balance\n * const result = await usdtContract.query(\"PSP22::balance_of\", {\n * origin: aliceAddress,\n * args: { owner: aliceAddress }\n * });\n *\n * if (result.success) {\n * console.log(\"Balance:\", result.value.response);\n *\n * // Send transaction from the query result\n * const txResult = await result.value.send().signAndSubmit(aliceSigner);\n * }\n *\n * // Or send directly\n * const txResult = await usdtContract\n * .send(\"PSP22::transfer\", {\n * origin: aliceAddress,\n * args: { to: bobAddress, value: 1000n, data: [] }\n * })\n * .signAndSubmit(aliceSigner);\n * ```\n *\n * @param client - The PolkadotClient instance\n * @param options - Optional SDK configuration\n * @returns D9 Ink SDK instance with typed RPC access\n */\nexport function createD9InkSdk(\n client: PolkadotClient,\n options: CreateD9InkSdkOptions = {},\n): D9InkSdkWithRpc {\n const { typedApi, defaultQueryOptions, defaultSendOptions } = options;\n\n return {\n getContract<\n S extends InkStorageDescriptor,\n M extends InkCallableDescriptor,\n C extends InkCallableDescriptor,\n E extends Enum<any>,\n >(\n descriptor: InkDescriptors<S, M, C, E>,\n address: SS58String,\n ): D9InkContract<M, E> {\n return createD9InkContract(descriptor, address, {\n client,\n typedApi,\n defaultQueryOptions,\n defaultSendOptions,\n });\n },\n rpc: createTypedRpc(client),\n };\n}\n\n// Re-export types for convenience\nexport type {\n D9InkSdk,\n D9InkSdkOptions,\n D9InkContract,\n QueryOptions,\n SendOptions,\n QueryResult,\n SendableTransaction,\n TxResult,\n ContractStorage,\n} from \"./types\";\n\nexport type { TypedRpcRequest } from \"./rpc-types\";\n","/**\n * Internal codec building utilities\n *\n * This module provides lower-level codec building from metadata type IDs.\n */\nimport {\n\tu8,\n\tu16,\n\tu32,\n\tu64,\n\tu128,\n\ti8,\n\ti16,\n\ti32,\n\ti64,\n\ti128,\n\tbool,\n\tstr,\n\tBytes,\n\tVector,\n\tTuple,\n\tStruct,\n\tVariant,\n\t_void,\n\tOption,\n\tAccountId,\n\ttype Codec,\n} from \"@polkadot-api/substrate-bindings\";\nimport type { InkMetadata } from \"@polkadot-api/ink-contracts\";\n\n// Use 'any' for dynamic codec building\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\ntype CodecCache = Map<number, AnyCodec>;\n\ninterface TypeDef {\n\tprimitive?: string;\n\tcomposite?: {\n\t\tfields: Array<{\n\t\t\tname?: string;\n\t\t\ttype: number;\n\t\t\ttypeName?: string;\n\t\t}>;\n\t};\n\tvariant?: {\n\t\tvariants: Array<{\n\t\t\tname: string;\n\t\t\tindex: number;\n\t\t\tfields: Array<{\n\t\t\t\tname?: string;\n\t\t\t\ttype: number;\n\t\t\t\ttypeName?: string;\n\t\t\t}>;\n\t\t}>;\n\t};\n\tsequence?: {\n\t\ttype: number;\n\t};\n\tarray?: {\n\t\tlen: number;\n\t\ttype: number;\n\t};\n\ttuple?: number[];\n}\n\ninterface TypeEntry {\n\tid: number;\n\ttype: {\n\t\tdef: TypeDef;\n\t\tpath?: string[];\n\t\tparams?: Array<{\n\t\t\tname: string;\n\t\t\ttype?: number;\n\t\t}>;\n\t};\n}\n\n/**\n * Build a SCALE codec from ink metadata type definition\n */\nfunction buildCodecFromTypeInternal(\n\ttypeId: number,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst cached = cache.get(typeId);\n\tif (cached) return cached;\n\n\tconst typeEntry = types.find((t) => t.id === typeId);\n\tif (!typeEntry) {\n\t\tthrow new Error(`Type ${typeId} not found in metadata`);\n\t}\n\n\tconst def = typeEntry.type.def;\n\tconst path = typeEntry.type.path;\n\n\t// Handle primitive types\n\tif (def.primitive) {\n\t\tconst codec = buildPrimitiveCodec(def.primitive);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle special path types\n\tif (path && path.length > 0) {\n\t\tconst specialCodec = buildSpecialTypeCodec(path, typeEntry, types, cache);\n\t\tif (specialCodec) {\n\t\t\tcache.set(typeId, specialCodec);\n\t\t\treturn specialCodec;\n\t\t}\n\t}\n\n\t// Handle tuple\n\tif (def.tuple) {\n\t\tconst codec = buildTupleCodec(def.tuple, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle sequence\n\tif (def.sequence) {\n\t\tconst innerCodec = buildCodecFromTypeInternal(def.sequence.type, types, cache);\n\t\tconst codec = Vector(innerCodec);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle array\n\tif (def.array) {\n\t\tconst innerCodec = buildCodecFromTypeInternal(def.array.type, types, cache);\n\t\tif (def.array.type === findPrimitiveTypeId(types, \"u8\")) {\n\t\t\tconst codec = Bytes(def.array.len);\n\t\t\tcache.set(typeId, codec);\n\t\t\treturn codec;\n\t\t}\n\t\tconst codec = Vector(innerCodec, def.array.len);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle composite\n\tif (def.composite) {\n\t\tconst codec = buildCompositeCodec(def.composite, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle variant\n\tif (def.variant) {\n\t\tconst codec = buildVariantCodec(def.variant, path, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\tthrow new Error(`Unknown type definition for type ${typeId}`);\n}\n\nfunction buildPrimitiveCodec(primitive: string): AnyCodec {\n\tswitch (primitive) {\n\t\tcase \"u8\":\n\t\t\treturn u8;\n\t\tcase \"u16\":\n\t\t\treturn u16;\n\t\tcase \"u32\":\n\t\t\treturn u32;\n\t\tcase \"u64\":\n\t\t\treturn u64;\n\t\tcase \"u128\":\n\t\t\treturn u128;\n\t\tcase \"i8\":\n\t\t\treturn i8;\n\t\tcase \"i16\":\n\t\t\treturn i16;\n\t\tcase \"i32\":\n\t\t\treturn i32;\n\t\tcase \"i64\":\n\t\t\treturn i64;\n\t\tcase \"i128\":\n\t\t\treturn i128;\n\t\tcase \"bool\":\n\t\t\treturn bool;\n\t\tcase \"str\":\n\t\t\treturn str;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown primitive type: ${primitive}`);\n\t}\n}\n\nfunction buildSpecialTypeCodec(\n\tpath: string[],\n\ttypeEntry: TypeEntry,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec | null {\n\tconst fullPath = path.join(\"::\");\n\n\tif (fullPath.includes(\"AccountId\")) {\n\t\treturn AccountId();\n\t}\n\n\tif (path[0] === \"Option\") {\n\t\tconst params = typeEntry.type.params;\n\t\tif (params && params.length > 0 && params[0]?.type !== undefined) {\n\t\t\tconst innerCodec = buildCodecFromTypeInternal(params[0].type, types, cache);\n\t\t\treturn Option(innerCodec);\n\t\t}\n\t}\n\n\tif (path[0] === \"Result\") {\n\t\tconst params = typeEntry.type.params;\n\t\tif (params && params.length >= 2) {\n\t\t\tconst okTypeId = params[0]?.type;\n\t\t\tconst errTypeId = params[1]?.type;\n\t\t\tif (okTypeId !== undefined && errTypeId !== undefined) {\n\t\t\t\tconst okCodec = buildCodecFromTypeInternal(okTypeId, types, cache);\n\t\t\t\tconst errCodec = buildCodecFromTypeInternal(errTypeId, types, cache);\n\t\t\t\treturn Variant({ Ok: okCodec, Err: errCodec }, [0, 1]);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction buildTupleCodec(tupleTypes: number[], types: TypeEntry[], cache: CodecCache): AnyCodec {\n\tif (tupleTypes.length === 0) return _void;\n\n\tconst innerCodecs = tupleTypes.map((t) => buildCodecFromTypeInternal(t, types, cache));\n\n\tswitch (innerCodecs.length) {\n\t\tcase 1:\n\t\t\treturn Tuple(innerCodecs[0]!);\n\t\tcase 2:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!);\n\t\tcase 3:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!);\n\t\tcase 4:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!, innerCodecs[3]!);\n\t\tdefault:\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\treturn (Tuple as any)(...innerCodecs);\n\t}\n}\n\nfunction buildCompositeCodec(\n\tcomposite: NonNullable<TypeDef[\"composite\"]>,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst fields = composite.fields;\n\n\tif (fields.length === 1 && !fields[0]?.name) {\n\t\treturn buildCodecFromTypeInternal(fields[0]!.type, types, cache);\n\t}\n\n\tconst structDef: Record<string, AnyCodec> = {};\n\tfor (const field of fields) {\n\t\tconst fieldName = field.name || `field${fields.indexOf(field)}`;\n\t\tstructDef[fieldName] = buildCodecFromTypeInternal(field.type, types, cache);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treturn Struct(structDef as any);\n}\n\nfunction buildVariantCodec(\n\tvariant: NonNullable<TypeDef[\"variant\"]>,\n\tpath: string[] | undefined,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst variants = variant.variants;\n\tconst isLangError = path?.includes(\"LangError\");\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst variantDef: Record<string, any> = {};\n\tconst indices: number[] = [];\n\n\tif (isLangError && !variants.some((v) => v.index === 0)) {\n\t\tvariantDef[\"_Placeholder\"] = _void;\n\t\tindices.push(0);\n\t}\n\n\tfor (const v of variants) {\n\t\tlet fieldCodec: AnyCodec;\n\t\tconst fields = v.fields ?? [];\n\n\t\tif (fields.length === 0) {\n\t\t\tfieldCodec = _void;\n\t\t} else if (fields.length === 1 && !fields[0]?.name) {\n\t\t\tfieldCodec = buildCodecFromTypeInternal(fields[0]!.type, types, cache);\n\t\t} else {\n\t\t\tconst structDef: Record<string, AnyCodec> = {};\n\t\t\tfor (const field of fields) {\n\t\t\t\tconst fieldName = field.name || `field${fields.indexOf(field)}`;\n\t\t\t\tstructDef[fieldName] = buildCodecFromTypeInternal(field.type, types, cache);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tfieldCodec = Struct(structDef as any);\n\t\t}\n\n\t\tvariantDef[v.name] = fieldCodec;\n\t\tindices.push(v.index);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treturn Variant(variantDef as any, indices as any);\n}\n\nfunction findPrimitiveTypeId(types: TypeEntry[], primitive: string): number {\n\tconst entry = types.find((t) => t.type.def.primitive === primitive);\n\treturn entry?.id ?? -1;\n}\n\n/**\n * Build a codec for a specific type ID from ink metadata\n *\n * @param metadata - The ink contract metadata\n * @param typeId - The type ID to build codec for\n * @returns A codec with encode/decode methods\n */\nexport function buildCodecFromMetadata(\n\tmetadata: InkMetadata,\n\ttypeId: number,\n): { enc: (value: unknown) => Uint8Array; dec: (data: Uint8Array) => unknown } {\n\tconst types = metadata.types as TypeEntry[];\n\tconst cache: CodecCache = new Map();\n\n\tconst codec = buildCodecFromTypeInternal(typeId, types, cache);\n\treturn codec;\n}\n\n/**\n * Build a struct codec for message arguments\n *\n * @param metadata - The ink contract metadata\n * @param args - The argument definitions\n * @returns A struct codec\n */\nexport function buildArgsCodec(\n\tmetadata: InkMetadata,\n\targs: Array<{ label: string; type: { type: number } }>,\n): { enc: (value: unknown) => Uint8Array; dec: (data: Uint8Array) => unknown } {\n\tif (args.length === 0) {\n\t\treturn {\n\t\t\tenc: () => new Uint8Array(0),\n\t\t\tdec: () => ({}),\n\t\t};\n\t}\n\n\tconst types = metadata.types as TypeEntry[];\n\tconst cache: CodecCache = new Map();\n\n\tconst structDef: Record<string, AnyCodec> = {};\n\tfor (const arg of args) {\n\t\tstructDef[arg.label] = buildCodecFromTypeInternal(arg.type.type, types, cache);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst codec = Struct(structDef as any) as any;\n\treturn {\n\t\tenc: (value: unknown) => codec.enc(value),\n\t\tdec: (data: Uint8Array) => codec.dec(data),\n\t};\n}\n","/**\n * Call parsing for ink! contracts\n *\n * Decodes contract call data (selector + args) into type-safe call objects.\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n\tEvent as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport type {\n\tTypedContractCall,\n\tRawContractCall,\n\tCallFilterOptions,\n\tMessageInfo,\n\tExtractMessageLabels,\n} from \"./call-types\";\nimport { buildArgsCodec } from \"./codec-builder-internal\";\n\n/**\n * Build argument decoders for all messages in the metadata\n */\nfunction buildAllMessageDecodersFromMetadata(\n\tmetadata: InkMetadata,\n): Map<string, { selector: Uint8Array; decoder: (data: Uint8Array) => unknown }> {\n\tconst decoders = new Map<\n\t\tstring,\n\t\t{ selector: Uint8Array; decoder: (data: Uint8Array) => unknown }\n\t>();\n\n\tconst messages = metadata.spec.messages as Array<{\n\t\tlabel: string;\n\t\tselector: string; // hex string like \"0xdb20f9f5\"\n\t\targs: Array<{\n\t\t\tlabel: string;\n\t\t\ttype: { type: number };\n\t\t}>;\n\t}>;\n\n\tfor (const message of messages) {\n\t\ttry {\n\t\t\t// Parse selector from hex string\n\t\t\tconst selectorHex = message.selector.startsWith(\"0x\")\n\t\t\t\t? message.selector.slice(2)\n\t\t\t\t: message.selector;\n\t\t\tconst selector = new Uint8Array(\n\t\t\t\tselectorHex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n\t\t\t);\n\n\t\t\t// Build struct decoder for message arguments\n\t\t\tconst argsCodec = buildArgsCodec(metadata, message.args);\n\t\t\tconst decoder = (data: Uint8Array) => argsCodec.dec(data);\n\n\t\t\tdecoders.set(message.label, { selector, decoder });\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to build decoder for message \"${message.label}\":`, error);\n\t\t}\n\t}\n\n\treturn decoders;\n}\n\n/**\n * Type-safe call parser for a specific contract\n *\n * @typeParam S - The storage descriptor type\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam C - The constructors descriptor type\n * @typeParam E - The events Enum type\n */\nexport class ContractCallParser<\n\tS extends InkStorageDescriptor = InkStorageDescriptor,\n\tM extends InkCallableDescriptor = InkCallableDescriptor,\n\tC extends InkCallableDescriptor = InkCallableDescriptor,\n\tE extends InkEvent = InkEvent,\n> {\n\tprivate messageDecoders: Map<\n\t\tstring,\n\t\t{ selector: Uint8Array; decoder: (data: Uint8Array) => unknown }\n\t>;\n\tprivate selectorToLabel: Map<string, string>;\n\tprivate metadata: InkMetadata;\n\n\tconstructor(descriptor: InkDescriptors<S, M, C, E>) {\n\t\tif (!descriptor.metadata) {\n\t\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t\t}\n\t\tthis.metadata = descriptor.metadata;\n\t\tthis.messageDecoders = buildAllMessageDecodersFromMetadata(this.metadata);\n\n\t\t// Build reverse lookup: selector hex -> label\n\t\tthis.selectorToLabel = new Map();\n\t\tfor (const [label, { selector }] of this.messageDecoders) {\n\t\t\tconst selectorHex = Array.from(selector)\n\t\t\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t\t\t.join(\"\");\n\t\t\tthis.selectorToLabel.set(selectorHex, label);\n\t\t}\n\t}\n\n\t/**\n\t * Parse raw call data into a type-safe contract call\n\t *\n\t * @param callData - The raw call data (selector + encoded args) or RawContractCall\n\t * @returns Parsed call or null if cannot parse\n\t *\n\t * @example\n\t * ```ts\n\t * const call = parser.parseCall(callData);\n\t * if (call?.type === \"PSP22::transfer\") {\n\t * // call.args is typed as { to: SS58String; value: bigint; data: Uint8Array }\n\t * console.log(call.args.to);\n\t * }\n\t * ```\n\t */\n\tparseCall(callData: Uint8Array | RawContractCall): TypedContractCall<M> | null {\n\t\tconst data = callData instanceof Uint8Array ? callData : callData.data;\n\t\tconst raw: RawContractCall =\n\t\t\tcallData instanceof Uint8Array ? { data: callData } : callData;\n\n\t\tif (data.length < 4) {\n\t\t\treturn null; // Need at least 4 bytes for selector\n\t\t}\n\n\t\t// Extract selector (first 4 bytes)\n\t\tconst selector = data.slice(0, 4);\n\t\tconst selectorHex = Array.from(selector)\n\t\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t\t.join(\"\");\n\n\t\t// Find message by selector\n\t\tconst label = this.selectorToLabel.get(selectorHex);\n\t\tif (!label) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst messageInfo = this.messageDecoders.get(label);\n\t\tif (!messageInfo) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode arguments (data after selector)\n\t\tconst argsData = data.slice(4);\n\t\ttry {\n\t\t\tconst args = messageInfo.decoder(argsData);\n\n\t\t\treturn {\n\t\t\t\ttype: label,\n\t\t\t\targs,\n\t\t\t\tselector,\n\t\t\t\traw,\n\t\t\t} as TypedContractCall<M>;\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to decode call \"${label}\":`, error);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Parse multiple calls and optionally filter by message labels\n\t *\n\t * @param calls - Array of raw call data\n\t * @param options - Filter options\n\t * @returns Array of parsed calls\n\t */\n\tparseCalls(\n\t\tcalls: Array<Uint8Array | RawContractCall>,\n\t\toptions?: CallFilterOptions,\n\t): TypedContractCall<M>[] {\n\t\tconst results: TypedContractCall<M>[] = [];\n\n\t\tfor (const call of calls) {\n\t\t\tconst parsed = this.parseCall(call);\n\t\t\tif (!parsed) continue;\n\n\t\t\t// Apply label filter\n\t\t\tif (options?.messageLabels && !options.messageLabels.includes(parsed.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresults.push(parsed);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Filter calls by specific type with proper type narrowing\n\t *\n\t * This method provides better type safety than parseCalls with messageLabels\n\t * because TypeScript can narrow the return type to only the specified call type.\n\t *\n\t * @param calls - Array of raw call data\n\t * @param label - The message label to filter by\n\t * @returns Array of calls narrowed to the specific type\n\t *\n\t * @example\n\t * ```ts\n\t * const transfers = parser.filterByType(callDataArray, \"PSP22::transfer\");\n\t *\n\t * for (const t of transfers) {\n\t * // t.args is fully typed as PSP22::transfer args\n\t * console.log(t.args.to, t.args.value);\n\t * }\n\t * ```\n\t */\n\tfilterByType<L extends string>(\n\t\tcalls: Array<Uint8Array | RawContractCall>,\n\t\tlabel: L,\n\t): Array<TypedContractCall<M> & { type: L }> {\n\t\treturn this.parseCalls(calls).filter(\n\t\t\t(c): c is TypedContractCall<M> & { type: L } => c.type === label,\n\t\t);\n\t}\n\n\t/**\n\t * Get information about a message by label\n\t */\n\tgetMessageInfo(label: string): MessageInfo | null {\n\t\tconst info = this.messageDecoders.get(label);\n\t\tif (!info) return null;\n\n\t\tconst messages = this.metadata.spec.messages as Array<{\n\t\t\tlabel: string;\n\t\t\tselector: string;\n\t\t\tmutates: boolean;\n\t\t\tpayable: boolean;\n\t\t\targs: Array<{ label: string; type: { type: number } }>;\n\t\t}>;\n\n\t\tconst message = messages.find((m) => m.label === label);\n\t\tif (!message) return null;\n\n\t\treturn {\n\t\t\tlabel: message.label,\n\t\t\tselector: info.selector,\n\t\t\tmutates: message.mutates,\n\t\t\tpayable: message.payable,\n\t\t\targs: message.args,\n\t\t};\n\t}\n\n\t/**\n\t * Get all available message labels\n\t */\n\tgetMessageLabels(): string[] {\n\t\treturn Array.from(this.messageDecoders.keys());\n\t}\n\n\t/**\n\t * Check if a selector matches a specific message\n\t */\n\tmatchesMessage(selector: Uint8Array, label: string): boolean {\n\t\tconst info = this.messageDecoders.get(label);\n\t\tif (!info) return false;\n\n\t\tif (selector.length !== info.selector.length) return false;\n\n\t\tfor (let i = 0; i < selector.length; i++) {\n\t\t\tif (selector[i] !== info.selector[i]) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Type guard for narrowing call types\n *\n * Use this function when you have a `TypedContractCall` and need to\n * narrow it to a specific call type. This is useful when the type\n * information is lost (e.g., after serialization or in generic functions).\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam L - The specific message label to check\n * @param call - The call to check\n * @param label - The message label to match\n * @returns True if the call type matches the label\n *\n * @example\n * ```ts\n * const call = parser.parseCall(callData);\n *\n * if (call && isCallType(call, \"PSP22::transfer\")) {\n * // TypeScript knows call.args is transfer args\n * console.log(call.args.to);\n * console.log(call.args.value);\n * }\n * ```\n */\nexport function isCallType<\n\tM extends InkCallableDescriptor,\n\tL extends ExtractMessageLabels<M>,\n>(\n\tcall: TypedContractCall<M>,\n\tlabel: L,\n): call is Extract<TypedContractCall<M>, { type: L }> {\n\treturn call.type === label;\n}\n","/**\n * Fee estimation utilities for ink! smart contracts\n */\n\nimport type { GasInfo } from \"../decode\";\n\n/**\n * Gas weight representation\n */\nexport interface GasWeight {\n\trefTime: bigint;\n\tproofSize: bigint;\n}\n\n/**\n * Estimated transaction cost breakdown\n */\nexport interface EstimatedCost {\n\t/** Cost from gas consumption */\n\tgasCost: bigint;\n\t/** Storage deposit (may be refunded) */\n\tstorageDeposit: bigint;\n\t/** Total estimated cost (gas + storage) */\n\ttotal: bigint;\n}\n\n/**\n * Formatted gas information for display\n */\nexport interface FormattedGasInfo {\n\t/** Human-readable ref_time */\n\trefTime: string;\n\t/** Human-readable proof_size */\n\tproofSize: string;\n}\n\n// D9 network weight-to-fee constants\n// These should match the chain's WeightToFee implementation\nconst WEIGHT_REF_TIME_PER_SECOND = 1_000_000_000_000n; // 1 trillion\nconst WEIGHT_FEE_COEFFICIENT = 1n; // Adjust based on chain config\n\n/**\n * Estimate the transaction cost from gas info and storage deposit\n *\n * Note: This is an approximation. Actual fees depend on chain configuration\n * and may vary slightly.\n *\n * @param gasInfo - Gas information from contract query\n * @param storageDeposit - Storage deposit amount (positive for charge, negative for refund)\n * @returns Estimated cost breakdown\n *\n * @example\n * ```typescript\n * const result = await contract.query(\"PSP22::transfer\", { origin, args });\n * if (result.success) {\n * const cost = estimateTransactionCost(\n * { gasConsumed: result.gasConsumed, gasRequired: result.gasRequired },\n * result.storageDeposit\n * );\n * console.log(`Estimated cost: ${formatBalance(cost.total, { decimals: 12 })} D9`);\n * }\n * ```\n */\nexport function estimateTransactionCost(\n\tgasInfo: GasInfo,\n\tstorageDeposit: bigint,\n): EstimatedCost {\n\t// Use gasRequired for estimation as it's the gas that will be charged\n\tconst { gasRequired } = gasInfo;\n\n\t// Simple weight-to-fee conversion\n\t// In production, this should match the chain's actual WeightToFee implementation\n\tconst gasCost =\n\t\t(gasRequired.refTime * WEIGHT_FEE_COEFFICIENT) / WEIGHT_REF_TIME_PER_SECOND +\n\t\tgasRequired.proofSize;\n\n\t// Storage deposit is additional (may be refunded later)\n\tconst effectiveStorageDeposit = storageDeposit > 0n ? storageDeposit : 0n;\n\n\treturn {\n\t\tgasCost,\n\t\tstorageDeposit: effectiveStorageDeposit,\n\t\ttotal: gasCost + effectiveStorageDeposit,\n\t};\n}\n\n/**\n * Format gas information for human-readable display\n *\n * @param gasInfo - Gas information from contract query\n * @returns Formatted strings for ref_time and proof_size\n *\n * @example\n * ```typescript\n * const formatted = formatGasInfo(result.gasRequired);\n * console.log(`Gas: refTime=${formatted.refTime}, proofSize=${formatted.proofSize}`);\n * ```\n */\nexport function formatGasInfo(gasInfo: GasInfo[\"gasRequired\"]): FormattedGasInfo {\n\treturn {\n\t\trefTime: formatWeight(gasInfo.refTime),\n\t\tproofSize: formatWeight(gasInfo.proofSize),\n\t};\n}\n\n/**\n * Format a single weight value with appropriate units\n */\nfunction formatWeight(weight: bigint): string {\n\tif (weight >= 1_000_000_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000_000_000).toFixed(2)}T`;\n\t}\n\tif (weight >= 1_000_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000_000).toFixed(2)}G`;\n\t}\n\tif (weight >= 1_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000).toFixed(2)}M`;\n\t}\n\tif (weight >= 1_000n) {\n\t\treturn `${(Number(weight) / 1_000).toFixed(2)}K`;\n\t}\n\treturn weight.toString();\n}\n\n/**\n * Apply a safety margin to gas limits\n *\n * It's recommended to add a small margin to gas estimates to account for\n * slight variations in execution. 10% (multiplier = 1.1) is a common choice.\n *\n * @param gas - The gas weight to adjust\n * @param multiplier - The multiplier to apply (default: 1.1 for 10% margin)\n * @returns Adjusted gas weight with margin applied\n *\n * @example\n * ```typescript\n * const result = await contract.query(\"PSP22::transfer\", { origin, args });\n * if (result.success) {\n * // Add 10% safety margin\n * const safeGas = applyGasMargin(result.gasRequired, 1.1);\n * await contract.send(\"PSP22::transfer\", {\n * origin,\n * args,\n * gasLimit: safeGas,\n * });\n * }\n * ```\n */\nexport function applyGasMargin(\n\tgas: GasWeight,\n\tmultiplier = 1.1,\n): GasWeight {\n\tif (multiplier <= 0) {\n\t\tthrow new Error(\"Multiplier must be positive\");\n\t}\n\n\t// Convert multiplier to basis points for precise bigint math\n\t// e.g., 1.1 -> 11000, 1.15 -> 11500\n\tconst basisPoints = BigInt(Math.round(multiplier * 10000));\n\n\treturn {\n\t\trefTime: (gas.refTime * basisPoints) / 10000n,\n\t\tproofSize: (gas.proofSize * basisPoints) / 10000n,\n\t};\n}\n\n/**\n * Compare two gas weights\n *\n * @param a - First gas weight\n * @param b - Second gas weight\n * @returns -1 if a < b, 0 if equal, 1 if a > b (compares refTime first, then proofSize)\n */\nexport function compareGasWeight(a: GasWeight, b: GasWeight): -1 | 0 | 1 {\n\tif (a.refTime < b.refTime) return -1;\n\tif (a.refTime > b.refTime) return 1;\n\tif (a.proofSize < b.proofSize) return -1;\n\tif (a.proofSize > b.proofSize) return 1;\n\treturn 0;\n}\n\n/**\n * Check if gas weight exceeds a limit\n *\n * @param gas - The gas to check\n * @param limit - The limit to compare against\n * @returns True if gas exceeds the limit in either dimension\n */\nexport function gasExceedsLimit(gas: GasWeight, limit: GasWeight): boolean {\n\treturn gas.refTime > limit.refTime || gas.proofSize > limit.proofSize;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["HexSink","Src","u128","buildPrimitiveCodec","buildSpecialTypeCodec","buildTupleCodec","findPrimitiveTypeId","codec","buildCompositeCodec","buildVariantCodec","u8","u16","u32","u64","u128","i8","i16","i32","i64","i128","bool","str","_void","structDef: Record<string, AnyCodec>","isLangError","variantDef: Record<string, any>","indices: number[]","fieldCodec: AnyCodec","cache: CodecCache","eventLabel: string | null","results: TypedContractEvent<E>[]","contract: Uint8Array","data: Uint8Array","topics: Uint8Array[]","error: unknown","from","Binary","type: ContractErrorType","label?: string","details?: unknown","errorValue: unknown","variant: number","timeoutMs: number","txHash?: string","timeoutId: ReturnType<typeof setTimeout>","codecRegistry: Map<string, ResponseDecoder>","message","rawResponse: Uint8Array","decodedResponse: M[K][\"response\"]","Binary","options","codec","u8","u16","u32","u64","u128","i8","i16","i32","i64","i128","bool","str","_void","structDef: Record<string, AnyCodec>","isLangError","variantDef: Record<string, any>","indices: number[]","fieldCodec: AnyCodec","cache: CodecCache","raw: RawContractCall","results: TypedContractCall<M>[]"],"sources":["../src/encode.ts","../src/decode.ts","../src/codec-builder.ts","../src/events.ts","../src/subscriptions.ts","../src/message-builder.ts","../src/errors.ts","../src/contract.ts","../src/rpc.ts","../src/sdk.ts","../src/codec-builder-internal.ts","../src/calls.ts","../src/utils/fees.ts"],"sourcesContent":["/**\n * Encoding utilities for ContractsApi_call state_call\n */\n\nimport type { Bytes } from \"@subsquid/scale-codec\";\nimport { HexSink } from \"@subsquid/scale-codec\";\nimport type { Binary } from \"polkadot-api\";\nimport { fromHex } from \"polkadot-api/utils\";\n\n/**\n * Encode a contract call for ContractsApi_call state_call.\n *\n * The encoded format matches the ContractsApi::call runtime API:\n * - origin: AccountId (32 bytes)\n * - dest: AccountId (32 bytes)\n * - value: Balance (u128)\n * - gas_limit: Option<Weight> (1 byte for None)\n * - storage_deposit_limit: Option<Balance> (1 byte for None)\n * - input_data: Vec<u8> (compact length + bytes)\n *\n * @param origin - The origin account (as Uint8Array or hex string)\n * @param dest - The contract address (as Uint8Array or hex string)\n * @param input - The encoded call data (selector + arguments)\n * @param value - Optional value to transfer (default: 0)\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeContractCall(\n origin: Uint8Array | string,\n dest: Uint8Array | string,\n input: Binary | Uint8Array,\n value: bigint = 0n,\n): Bytes {\n const sink = new HexSink();\n\n const originBytes = typeof origin === \"string\" ? fromHex(origin) : origin;\n const destBytes = typeof dest === \"string\" ? fromHex(dest) : dest;\n const inputBytes = \"asBytes\" in input ? input.asBytes() : input;\n\n // origin: AccountId\n sink.bytes(originBytes);\n // dest: AccountId\n sink.bytes(destBytes);\n // value: Balance (u128)\n sink.u128(value);\n // gas_limit: Option<Weight> - None\n sink.u8(0);\n // storage_deposit_limit: Option<Balance> - None\n sink.u8(0);\n // input_data: Vec<u8>\n sink.compact(inputBytes.length);\n sink.bytes(inputBytes);\n\n return sink.toHex();\n}\n\n/**\n * Encode a contract call using the same address for origin and dest.\n * This is a simplified version for query operations where the origin\n * doesn't matter much.\n *\n * @param address - The contract address\n * @param input - The encoded call data\n * @param value - Optional value to transfer\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeCall(\n address: Uint8Array | string,\n input: Binary | Uint8Array,\n value: bigint = 0n,\n): Bytes {\n return encodeContractCall(address, address, input, value);\n}\n\n/**\n * Encode a contract call with specific gas limit and storage deposit limit.\n *\n * @param origin - The origin account\n * @param dest - The contract address\n * @param input - The encoded call data\n * @param options - Call options including value, gas limit, storage deposit limit\n * @returns Hex-encoded bytes for state_call\n */\nexport function encodeContractCallWithLimits(\n origin: Uint8Array | string,\n dest: Uint8Array | string,\n input: Binary | Uint8Array,\n options: {\n value?: bigint;\n gasLimit?: { refTime: bigint; proofSize: bigint };\n storageDepositLimit?: bigint;\n } = {},\n): Bytes {\n const sink = new HexSink();\n\n const originBytes = typeof origin === \"string\" ? fromHex(origin) : origin;\n const destBytes = typeof dest === \"string\" ? fromHex(dest) : dest;\n const inputBytes = \"asBytes\" in input ? input.asBytes() : input;\n\n // origin: AccountId\n sink.bytes(originBytes);\n // dest: AccountId\n sink.bytes(destBytes);\n // value: Balance (u128)\n sink.u128(options.value ?? 0n);\n\n // gas_limit: Option<Weight>\n if (options.gasLimit) {\n sink.u8(1); // Some\n sink.compact(options.gasLimit.refTime);\n sink.compact(options.gasLimit.proofSize);\n } else {\n sink.u8(0); // None\n }\n\n // storage_deposit_limit: Option<Balance>\n if (options.storageDepositLimit !== undefined) {\n sink.u8(1); // Some\n sink.u128(options.storageDepositLimit);\n } else {\n sink.u8(0); // None\n }\n\n // input_data: Vec<u8>\n sink.compact(inputBytes.length);\n sink.bytes(inputBytes);\n\n return sink.toHex();\n}\n","/**\n * Decoding utilities for ContractsApi_call response\n */\n\nimport { Src } from \"@subsquid/scale-codec\";\nimport { type Codec, u128, Tuple } from \"@polkadot-api/substrate-bindings\";\n\n/**\n * Gas information from contract execution\n */\nexport interface GasInfo {\n /** Gas consumed during execution */\n gasConsumed: { refTime: bigint; proofSize: bigint };\n /** Gas required for execution */\n gasRequired: { refTime: bigint; proofSize: bigint };\n}\n\n/**\n * Storage deposit information\n */\nexport interface StorageDepositInfo {\n /** Storage deposit type: 0 = Refund, 1 = Charge */\n type: \"Refund\" | \"Charge\";\n /** Amount of storage deposit */\n amount: bigint;\n}\n\n/**\n * Full decoded result from ContractsApi_call\n */\nexport interface ContractCallResult {\n /** Gas information */\n gas: GasInfo;\n /** Storage deposit information */\n storageDeposit: StorageDepositInfo;\n /** Debug message (if any) */\n debugMessage: string;\n /** Whether the execution was successful */\n success: boolean;\n /** Execution flags */\n flags: number;\n /** The raw execution result bytes (still wrapped in Result<T, LangError>) */\n data: Uint8Array;\n}\n\n/**\n * Decode the raw ContractsApi_call response.\n *\n * The response format is:\n * - gasConsumed: Weight { ref_time: Compact<u64>, proof_size: Compact<u64> }\n * - gasRequired: Weight\n * - storageDeposit: StorageDeposit { variant: u8, amount: u128 }\n * - debugMessage: String\n * - result: Result<ExecReturnValue, DispatchError>\n * - ExecReturnValue: { flags: u32, data: Vec<u8> }\n *\n * @param result - The raw response bytes from state_call ContractsApi_call\n * @returns Decoded contract call result\n */\nexport function decodeContractCallResult(result: Uint8Array): ContractCallResult {\n const src = new Src(result);\n\n // gasConsumed: Weight\n const gasConsumedRefTime = BigInt(src.compact());\n const gasConsumedProofSize = BigInt(src.compact());\n\n // gasRequired: Weight\n const gasRequiredRefTime = BigInt(src.compact());\n const gasRequiredProofSize = BigInt(src.compact());\n\n // storageDeposit: StorageDeposit\n const storageDepositVariant = src.u8();\n const storageDepositAmount = src.u128();\n\n // debugMessage: String\n const debugMessage = src.str();\n\n // result: Result<ExecReturnValue, DispatchError>\n const resultVariant = src.u8(); // 0 = Ok, 1 = Err\n const success = resultVariant === 0;\n\n // ExecReturnValue: { flags: u32, data: Vec<u8> }\n const flags = src.u32();\n const data = src.bytes(src.compactLength());\n\n return {\n gas: {\n gasConsumed: {\n refTime: gasConsumedRefTime,\n proofSize: gasConsumedProofSize,\n },\n gasRequired: {\n refTime: gasRequiredRefTime,\n proofSize: gasRequiredProofSize,\n },\n },\n storageDeposit: {\n type: storageDepositVariant === 0 ? \"Refund\" : \"Charge\",\n amount: storageDepositAmount,\n },\n debugMessage,\n success,\n flags,\n data,\n };\n}\n\n/**\n * Legacy function - decode and return just the exec result data.\n * @deprecated Use decodeContractCallResult for full information\n */\nexport function decodeResult(result: Uint8Array): Uint8Array {\n const decoded = decodeContractCallResult(result);\n return decoded.data;\n}\n\n/**\n * Unwrap the inner value from Result<T, LangError> by checking the variant byte.\n *\n * Ink contracts wrap their return values in Result<T, LangError>.\n * This function handles the unwrapping and throws an error for LangError.\n *\n * @param data - The exec result bytes (Result<T, LangError> encoded)\n * @returns The inner value bytes (T encoded)\n * @throws Error if the result is Err variant (LangError)\n */\nexport function unwrapInkResult(data: Uint8Array): Uint8Array {\n if (data.length === 0) {\n throw new Error(\"Empty result data\");\n }\n\n const variant = data[0];\n\n if (variant === 0) {\n // Ok variant - return the inner data (skip the variant byte)\n return data.slice(1);\n } else if (variant === 1) {\n // Err variant - LangError\n throw new Error(\"Contract call returned LangError\");\n } else {\n throw new Error(`Unknown result variant: ${variant}`);\n }\n}\n\n/**\n * Check if the result indicates a LangError\n *\n * @param data - The exec result bytes\n * @returns True if it's a LangError (Err variant)\n */\nexport function isLangError(data: Uint8Array): boolean {\n return data.length > 0 && data[0] === 1;\n}\n\n/**\n * Decode ink contract message result using a custom SCALE codec.\n * This bypasses polkadot-api's ink decoder which has issues with LangError type.\n *\n * @param data - The exec result bytes (Result<T, LangError> encoded)\n * @param codec - The SCALE codec for the inner value type T\n * @returns The decoded value\n */\nexport function decodeInkValue<T>(data: Uint8Array, codec: Codec<T>): T {\n const innerData = unwrapInkResult(data);\n return codec.dec(innerData);\n}\n\n/**\n * Pre-defined codecs for common types\n */\nexport const InkCodecs = {\n /** u128 codec for Balance type */\n u128,\n /** Tuple of two u128 values, commonly used for (Balance, Balance) */\n balancePair: Tuple(u128, u128),\n};\n","/**\n * Auto-build SCALE decoders from ink metadata type definitions.\n *\n * This module provides a way to automatically construct decoders for ink contract\n * message return types without manually specifying codecs for each message.\n */\n\nimport {\n u8,\n u16,\n u32,\n u64,\n u128,\n i8,\n i16,\n i32,\n i64,\n i128,\n bool,\n str,\n Bytes,\n Vector,\n Tuple,\n Struct,\n Variant,\n _void,\n Option,\n AccountId,\n type Codec,\n} from \"@polkadot-api/substrate-bindings\";\nimport type { InkMetadata } from \"@polkadot-api/ink-contracts\";\nimport { blake2b } from \"@noble/hashes/blake2.js\";\n\n// Use 'any' for dynamic codec building to avoid TypeScript strict type issues\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\n\n/**\n * Type definition from ink metadata\n */\ninterface TypeDef {\n primitive?: string;\n composite?: {\n fields: Array<{\n name?: string;\n type: number;\n typeName?: string;\n }>;\n };\n variant?: {\n variants: Array<{\n name: string;\n index: number;\n fields: Array<{\n name?: string;\n type: number;\n typeName?: string;\n }>;\n }>;\n };\n sequence?: {\n type: number;\n };\n array?: {\n len: number;\n type: number;\n };\n tuple?: number[];\n}\n\ninterface TypeEntry {\n id: number;\n type: {\n def: TypeDef;\n path?: string[];\n params?: Array<{\n name: string;\n type?: number;\n }>;\n };\n}\n\n/**\n * Cache for built codecs to avoid rebuilding the same type\n */\ntype CodecCache = Map<number, AnyCodec>;\n\n/**\n * Build a SCALE codec from ink metadata type definition\n */\nfunction buildCodecFromType(\n typeId: number,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n // Check cache first\n const cached = cache.get(typeId);\n if (cached) {\n return cached;\n }\n\n const typeEntry = types.find((t) => t.id === typeId);\n if (!typeEntry) {\n throw new Error(`Type ${typeId} not found in metadata`);\n }\n\n const def = typeEntry.type.def;\n const path = typeEntry.type.path;\n\n // Handle primitive types\n if (def.primitive) {\n const codec = buildPrimitiveCodec(def.primitive);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle special path types (AccountId, Hash, etc.)\n if (path && path.length > 0) {\n const specialCodec = buildSpecialTypeCodec(path, typeEntry, types, cache);\n if (specialCodec) {\n cache.set(typeId, specialCodec);\n return specialCodec;\n }\n }\n\n // Handle tuple\n if (def.tuple) {\n const codec = buildTupleCodec(def.tuple, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle sequence (Vec<T>)\n if (def.sequence) {\n const innerCodec = buildCodecFromType(def.sequence.type, types, cache);\n const codec = Vector(innerCodec);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle array [T; N]\n if (def.array) {\n const innerCodec = buildCodecFromType(def.array.type, types, cache);\n // For fixed-size byte arrays, use Bytes\n if (def.array.type === findPrimitiveTypeId(types, \"u8\")) {\n const codec = Bytes(def.array.len);\n cache.set(typeId, codec);\n return codec;\n }\n // For other arrays, use Vector with fixed length validation\n const codec = Vector(innerCodec, def.array.len);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle composite (struct)\n if (def.composite) {\n const codec = buildCompositeCodec(def.composite, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n // Handle variant (enum)\n if (def.variant) {\n const codec = buildVariantCodec(def.variant, path, types, cache);\n cache.set(typeId, codec);\n return codec;\n }\n\n throw new Error(\n `Unknown type definition for type ${typeId}: ${JSON.stringify(def)}`,\n );\n}\n\n/**\n * Build codec for primitive types\n */\nfunction buildPrimitiveCodec(primitive: string): AnyCodec {\n switch (primitive) {\n case \"u8\":\n return u8;\n case \"u16\":\n return u16;\n case \"u32\":\n return u32;\n case \"u64\":\n return u64;\n case \"u128\":\n return u128;\n case \"i8\":\n return i8;\n case \"i16\":\n return i16;\n case \"i32\":\n return i32;\n case \"i64\":\n return i64;\n case \"i128\":\n return i128;\n case \"bool\":\n return bool;\n case \"str\":\n return str;\n default:\n throw new Error(`Unknown primitive type: ${primitive}`);\n }\n}\n\n/**\n * Build codec for special types based on path\n */\nfunction buildSpecialTypeCodec(\n path: string[],\n typeEntry: TypeEntry,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec | null {\n const fullPath = path.join(\"::\");\n\n // AccountId type\n if (fullPath.includes(\"AccountId\")) {\n return AccountId();\n }\n\n // Option type\n if (path[0] === \"Option\") {\n const params = typeEntry.type.params;\n if (params && params.length > 0 && params[0]?.type !== undefined) {\n const innerCodec = buildCodecFromType(params[0].type, types, cache);\n return Option(innerCodec);\n }\n }\n\n // Result type - we need special handling\n if (path[0] === \"Result\") {\n const params = typeEntry.type.params;\n if (params && params.length >= 2) {\n const okTypeId = params[0]?.type;\n const errTypeId = params[1]?.type;\n if (okTypeId !== undefined && errTypeId !== undefined) {\n const okCodec = buildCodecFromType(okTypeId, types, cache);\n const errCodec = buildCodecFromType(errTypeId, types, cache);\n // Build a proper Result variant\n return Variant(\n {\n Ok: okCodec,\n Err: errCodec,\n },\n [0, 1],\n );\n }\n }\n }\n\n return null;\n}\n\n/**\n * Build codec for tuple types\n */\nfunction buildTupleCodec(\n tupleTypes: number[],\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n if (tupleTypes.length === 0) {\n return _void;\n }\n\n const innerCodecs = tupleTypes.map((t) => buildCodecFromType(t, types, cache));\n\n // Handle different tuple sizes\n switch (innerCodecs.length) {\n case 1:\n return Tuple(innerCodecs[0]!);\n case 2:\n return Tuple(innerCodecs[0]!, innerCodecs[1]!);\n case 3:\n return Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!);\n case 4:\n return Tuple(\n innerCodecs[0]!,\n innerCodecs[1]!,\n innerCodecs[2]!,\n innerCodecs[3]!,\n );\n default:\n // For larger tuples, use dynamic tuple (cast to any)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (Tuple as any)(...innerCodecs);\n }\n}\n\n/**\n * Build codec for composite (struct) types\n */\nfunction buildCompositeCodec(\n composite: NonNullable<TypeDef[\"composite\"]>,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n const fields = composite.fields;\n\n // Single unnamed field - unwrap it\n if (fields.length === 1 && !fields[0]?.name) {\n return buildCodecFromType(fields[0]!.type, types, cache);\n }\n\n // Multiple fields - build a struct\n const structDef: Record<string, AnyCodec> = {};\n for (const field of fields) {\n const fieldName = field.name || `field${fields.indexOf(field)}`;\n structDef[fieldName] = buildCodecFromType(field.type, types, cache);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Struct(structDef as any);\n}\n\n/**\n * Build codec for variant (enum) types\n */\nfunction buildVariantCodec(\n variant: NonNullable<TypeDef[\"variant\"]>,\n path: string[] | undefined,\n types: TypeEntry[],\n cache: CodecCache,\n): AnyCodec {\n const variants = variant.variants;\n\n // Check if this is a LangError type (ink specific)\n const isLangError = path?.includes(\"LangError\");\n\n // Build variant definition\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const variantDef: Record<string, any> = {};\n const indices: number[] = [];\n\n // For LangError, add a placeholder for index 0 if missing\n if (isLangError && !variants.some((v) => v.index === 0)) {\n variantDef[\"_Placeholder\"] = _void;\n indices.push(0);\n }\n\n for (const v of variants) {\n let fieldCodec: AnyCodec;\n\n // Handle variants with no fields or undefined fields\n const fields = v.fields ?? [];\n\n if (fields.length === 0) {\n fieldCodec = _void;\n } else if (fields.length === 1 && !fields[0]?.name) {\n // Single unnamed field\n fieldCodec = buildCodecFromType(fields[0]!.type, types, cache);\n } else {\n // Multiple or named fields - build struct\n const structDef: Record<string, AnyCodec> = {};\n for (const field of fields) {\n const fieldName = field.name || `field${fields.indexOf(field)}`;\n structDef[fieldName] = buildCodecFromType(field.type, types, cache);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fieldCodec = Struct(structDef as any);\n }\n\n variantDef[v.name] = fieldCodec;\n indices.push(v.index);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Variant(variantDef as any, indices as any);\n}\n\n/**\n * Find the type ID for a primitive type\n */\nfunction findPrimitiveTypeId(types: TypeEntry[], primitive: string): number {\n const entry = types.find((t) => t.type.def.primitive === primitive);\n return entry?.id ?? -1;\n}\n\n/**\n * Extract the inner type from Result<T, LangError>\n * Returns the type ID of T\n */\nfunction extractResultInnerType(typeEntry: TypeEntry): number | null {\n const path = typeEntry.type.path;\n if (!path || path[0] !== \"Result\") {\n return null;\n }\n\n const params = typeEntry.type.params;\n if (!params || params.length < 1) {\n return null;\n }\n\n return params[0]?.type ?? null;\n}\n\n/**\n * Build a decoder for a message's return type from ink metadata.\n * This handles the Result<T, LangError> wrapper and returns a decoder for T.\n *\n * @param metadata - The ink contract metadata\n * @param messageLabel - The message label (e.g., \"PSP22::balance_of\")\n * @returns A decoder function that decodes the inner value bytes\n */\nexport function buildMessageDecoder(\n metadata: InkMetadata,\n messageLabel: string,\n): (data: Uint8Array) => unknown {\n const types = metadata.types as TypeEntry[];\n const message = metadata.spec.messages.find((m) => m.label === messageLabel);\n\n if (!message) {\n throw new Error(`Message \"${messageLabel}\" not found in metadata`);\n }\n\n const returnTypeId = message.returnType.type;\n const returnTypeEntry = types.find((t) => t.id === returnTypeId);\n\n if (!returnTypeEntry) {\n throw new Error(\n `Return type ${returnTypeId} not found for message \"${messageLabel}\"`,\n );\n }\n\n const cache: CodecCache = new Map();\n\n // Check if it's a Result type and extract inner type\n const innerTypeId = extractResultInnerType(returnTypeEntry);\n\n if (innerTypeId !== null) {\n // Build decoder for the inner type (T in Result<T, LangError>)\n const innerCodec = buildCodecFromType(innerTypeId, types, cache);\n return (data: Uint8Array) => innerCodec.dec(data);\n }\n\n // Not a Result type, build decoder for the full return type\n const codec = buildCodecFromType(returnTypeId, types, cache);\n return (data: Uint8Array) => codec.dec(data);\n}\n\n/**\n * Build decoders for all messages in the metadata.\n * Returns a Map of message label -> decoder function.\n */\nexport function buildAllMessageDecoders(\n metadata: InkMetadata,\n): Map<string, (data: Uint8Array) => unknown> {\n const decoders = new Map<string, (data: Uint8Array) => unknown>();\n\n for (const message of metadata.spec.messages as Array<{ label: string }>) {\n try {\n const decoder = buildMessageDecoder(metadata, message.label);\n decoders.set(message.label, decoder);\n } catch (error) {\n console.warn(\n `Failed to build decoder for message \"${message.label}\":`,\n error,\n );\n }\n }\n\n return decoders;\n}\n\n/**\n * Create a codec registry compatible with ResponseDecoder type\n */\nexport function createCodecRegistry(\n metadata: InkMetadata,\n): Map<string, { dec: (data: Uint8Array) => unknown }> {\n const decoders = buildAllMessageDecoders(metadata);\n const registry = new Map<string, { dec: (data: Uint8Array) => unknown }>();\n\n for (const [label, decoder] of decoders) {\n registry.set(label, { dec: decoder });\n }\n\n return registry;\n}\n\n/**\n * Build a SCALE decoder for a contract event from ink metadata\n *\n * @param metadata - The ink contract metadata\n * @param eventLabel - The event label (e.g., \"Transfer\", \"Approval\")\n * @returns A decoder function that decodes the event data bytes\n */\nexport function buildEventDecoder(\n metadata: InkMetadata,\n eventLabel: string,\n): (data: Uint8Array) => unknown {\n const types = metadata.types as TypeEntry[];\n const events = metadata.spec.events as Array<{\n label: string;\n args: Array<{\n label: string;\n type: { type: number };\n }>;\n }>;\n\n const event = events.find((e) => e.label === eventLabel);\n\n if (!event) {\n throw new Error(`Event \"${eventLabel}\" not found in metadata`);\n }\n\n const cache: CodecCache = new Map();\n\n // Build struct codec from event args\n const structDef: Record<string, AnyCodec> = {};\n\n for (const arg of event.args) {\n const fieldName = arg.label;\n const fieldCodec = buildCodecFromType(arg.type.type, types, cache);\n structDef[fieldName] = fieldCodec;\n }\n\n // If event has no args, return void decoder\n if (event.args.length === 0) {\n return () => undefined;\n }\n\n // If event has single unnamed arg, unwrap it\n if (event.args.length === 1) {\n const argCodec = structDef[event.args[0]!.label];\n return (data: Uint8Array) => argCodec!.dec(data);\n }\n\n // Multiple args - return struct\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const codec = Struct(structDef as any);\n return (data: Uint8Array) => codec.dec(data);\n}\n\n/**\n * Build decoders for all events in the metadata\n *\n * @param metadata - The ink contract metadata\n * @returns Map of event label -> decoder function\n */\nexport function buildAllEventDecoders(\n metadata: InkMetadata,\n): Map<string, (data: Uint8Array) => unknown> {\n const decoders = new Map<string, (data: Uint8Array) => unknown>();\n\n const events = metadata.spec.events as Array<{ label: string }>;\n\n for (const event of events) {\n try {\n const decoder = buildEventDecoder(metadata, event.label);\n decoders.set(event.label, decoder);\n } catch (error) {\n console.warn(`Failed to build decoder for event \"${event.label}\":`, error);\n }\n }\n\n return decoders;\n}\n\n/**\n * Get event signature (topic[0]) for filtering\n * Events in ink! use blake2_256 hash of event label as topic[0]\n *\n * @param eventLabel - The event label (e.g., \"Transfer\")\n * @returns Event signature as Uint8Array (32 bytes)\n */\nexport function getEventSignature(eventLabel: string): Uint8Array {\n return blake2b(new TextEncoder().encode(eventLabel), { dkLen: 32 });\n}\n\n/**\n * Create ASCII-encoded event topic (D9 chain format)\n *\n * D9 chain uses a format where:\n * - First byte is 0x00 (null)\n * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`\n * - Total is exactly 32 bytes (truncated/padded as needed)\n *\n * @param contractName - Contract name (e.g., \"MarketMaker\", \"Usdt\")\n * @param eventLabel - Event label (e.g., \"Transfer\", \"USDTToD9Conversion\")\n * @returns 32-byte topic with null prefix and ASCII-encoded path\n */\nexport function createAsciiEventTopic(\n contractName: string,\n eventLabel: string,\n): Uint8Array {\n const topic = new Uint8Array(32);\n topic[0] = 0; // Null prefix\n const encoder = new TextEncoder();\n const fullPath = `${contractName}::${eventLabel}`;\n const encoded = encoder.encode(fullPath);\n // Copy up to 31 bytes (leaving room for null prefix)\n topic.set(encoded.slice(0, 31), 1);\n return topic;\n}\n","/**\n * Event parsing and filtering for ink! contracts\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n\tEvent as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport type { Enum, SS58String } from \"polkadot-api\";\nimport { ss58Decode } from \"@polkadot-labs/hdkd-helpers\";\nimport {\n\tbuildAllEventDecoders,\n\tbuildEventDecoder,\n\tgetEventSignature,\n} from \"./codec-builder\";\nimport type {\n\tTypedContractEvent,\n\tEventFilterOptions,\n\tRawContractEvent,\n\tExtractEnumDef,\n\tExtractEventLabels,\n} from \"./event-types\";\n\n/**\n * Type-safe event parser for a specific contract\n *\n * @typeParam S - The storage descriptor type\n * @typeParam M - The messages descriptor type\n * @typeParam C - The constructors descriptor type\n * @typeParam E - The event type representing all possible events for this contract\n */\nexport class ContractEventParser<\n\tS extends InkStorageDescriptor = InkStorageDescriptor,\n\tM extends InkCallableDescriptor = InkCallableDescriptor,\n\tC extends InkCallableDescriptor = InkCallableDescriptor,\n\tE extends InkEvent = InkEvent,\n> {\n\tprivate eventDecoders: Map<string, (data: Uint8Array) => unknown>;\n\tprivate eventSignatures: Map<string, Uint8Array>;\n\tprivate contractAddressBytes: Uint8Array;\n\tprivate contractAddress: SS58String;\n\tprivate metadata: InkMetadata;\n\n\tconstructor(\n\t\tdescriptor: InkDescriptors<S, M, C, E>,\n\t\tcontractAddress: SS58String,\n\t) {\n\t\tif (!descriptor.metadata) {\n\t\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t\t}\n\t\tthis.metadata = descriptor.metadata;\n\t\tthis.contractAddress = contractAddress;\n\t\tthis.eventDecoders = buildAllEventDecoders(this.metadata);\n\t\tthis.contractAddressBytes = ss58Decode(contractAddress)[0];\n\n\t\t// Build signature map for topic filtering\n\t\tthis.eventSignatures = new Map();\n\t\tconst events = this.metadata.spec.events as Array<{ label: string }>;\n\n\t\tfor (const event of events) {\n\t\t\tconst sig = getEventSignature(event.label);\n\t\t\tthis.eventSignatures.set(event.label, sig);\n\t\t}\n\t}\n\n\t/**\n\t * Parse a raw chain event into a type-safe contract event (if it matches)\n\t * Returns null if the event is not from this contract or cannot be parsed\n\t *\n\t * @example\n\t * ```ts\n\t * const event = parser.parseEvent(chainEvent);\n\t * if (event?.type === \"Transfer\") {\n\t * // event.value is now typed as { from: SS58String; to: SS58String; value: bigint }\n\t * console.log(event.value.from);\n\t * }\n\t * ```\n\t */\n\tparseEvent(chainEvent: unknown): TypedContractEvent<E> | null {\n\t\t// Extract Contracts.ContractEmitted event from chain event\n\t\tconst extracted = this.extractContractEmittedEvent(chainEvent);\n\t\tif (!extracted) return null;\n\n\t\tconst { contract, data, topics, blockNumber, blockHash, eventIndex } =\n\t\t\textracted;\n\n\t\t// Filter by contract address\n\t\tif (!this.bytesEqual(contract, this.contractAddressBytes)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode event based on topic[0] signature\n\t\tif (topics.length === 0) return null;\n\n\t\tconst signature = topics[0];\n\t\tlet eventLabel: string | null = null;\n\n\t\t// Method 1: Try ASCII extraction (D9 chain format)\n\t\t// D9 chain uses format: \\0ContractName::EventLabel (32 bytes, null-prefixed)\n\t\teventLabel = this.extractEventLabelFromAsciiTopic(signature!);\n\n\t\t// Verify the extracted label has a decoder\n\t\tif (eventLabel && !this.eventDecoders.has(eventLabel)) {\n\t\t\teventLabel = null;\n\t\t}\n\n\t\t// Method 2: Fall back to blake2 signature matching (standard ink! format)\n\t\tif (!eventLabel) {\n\t\t\tfor (const [label, sig] of this.eventSignatures) {\n\t\t\t\tif (this.bytesEqual(signature!, sig)) {\n\t\t\t\t\teventLabel = label;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!eventLabel) {\n\t\t\tconsole.warn(\"Unknown event signature:\", signature);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst decoder = this.eventDecoders.get(eventLabel);\n\t\tif (!decoder) {\n\t\t\tconsole.warn(`No decoder for event ${eventLabel}`);\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\t// ink! events include a variant discriminant as first byte, skip it\n\t\t\tconst decodedData = decoder(data.slice(1));\n\t\t\treturn {\n\t\t\t\ttype: eventLabel,\n\t\t\t\tvalue: decodedData,\n\t\t\t\traw: {\n\t\t\t\t\tblockNumber,\n\t\t\t\t\tblockHash,\n\t\t\t\t\teventIndex,\n\t\t\t\t\tcontractAddress: this.getContractAddress(),\n\t\t\t\t\tdata,\n\t\t\t\t\ttopics,\n\t\t\t\t},\n\t\t\t} as TypedContractEvent<E>;\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to decode event ${eventLabel}:`, error);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Extract event label from ASCII-encoded topic (D9 chain format)\n\t *\n\t * D9 chain uses a format where:\n\t * - First byte is 0x00 (null)\n\t * - Remaining 31 bytes are ASCII characters of `ContractName::EventLabel`\n\t * - Total is exactly 32 bytes (truncated/padded as needed)\n\t *\n\t * @param topic - The 32-byte topic from the event\n\t * @returns The extracted event label, or null if not in ASCII format\n\t */\n\tprivate extractEventLabelFromAsciiTopic(topic: Uint8Array): string | null {\n\t\tif (topic.length !== 32) return null;\n\n\t\t// D9 format: first byte is null (0x00)\n\t\tif (topic[0] !== 0) return null;\n\n\t\t// Decode ASCII (skip null prefix, trim trailing nulls)\n\t\tconst ascii = new TextDecoder()\n\t\t\t.decode(topic.slice(1))\n\t\t\t.replace(/\\0+$/, \"\");\n\n\t\t// Extract label after \"::\"\n\t\tconst colonIndex = ascii.lastIndexOf(\"::\");\n\t\tif (colonIndex !== -1) {\n\t\t\treturn ascii.slice(colonIndex + 2);\n\t\t}\n\n\t\t// No \"::\" found, use entire string as label\n\t\treturn ascii || null;\n\t}\n\n\t/**\n\t * Filter a batch of events and return type-safe results\n\t *\n\t * @param chainEvents - Array of chain events to filter\n\t * @param options - Optional filter criteria\n\t * @returns Array of type-safe contract events\n\t */\n\tfilterEvents(\n\t\tchainEvents: unknown[],\n\t\toptions?: EventFilterOptions,\n\t): TypedContractEvent<E>[] {\n\t\tconst results: TypedContractEvent<E>[] = [];\n\n\t\tfor (const chainEvent of chainEvents) {\n\t\t\tconst parsed = this.parseEvent(chainEvent);\n\t\t\tif (!parsed) continue;\n\n\t\t\t// Apply label filter\n\t\t\tif (options?.eventLabels && !options.eventLabels.includes(parsed.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Apply block range filter\n\t\t\tif (options?.fromBlock && parsed.raw.blockNumber < options.fromBlock) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (options?.toBlock && parsed.raw.blockNumber > options.toBlock) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresults.push(parsed);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Filter events by specific type with proper type narrowing\n\t *\n\t * This method provides better type safety than filterEvents with eventLabels\n\t * because TypeScript can narrow the return type to only the specified event type.\n\t *\n\t * @param chainEvents - Array of chain events to filter\n\t * @param label - The event label to filter by\n\t * @returns Array of events narrowed to the specific type\n\t *\n\t * @example\n\t * ```ts\n\t * const transfers = parser.filterByType(events, \"Transfer\");\n\t *\n\t * for (const t of transfers) {\n\t * // t.value is fully typed as Transfer event data\n\t * console.log(t.value.from, \"->\", t.value.to, \":\", t.value.value);\n\t * }\n\t * ```\n\t */\n\tfilterByType<L extends string>(\n\t\tchainEvents: unknown[],\n\t\tlabel: L,\n\t): Array<TypedContractEvent<E> & { type: L }> {\n\t\treturn this.filterEvents(chainEvents).filter(\n\t\t\t(e): e is TypedContractEvent<E> & { type: L } =>\n\t\t\t\t(e.type as string) === label,\n\t\t);\n\t}\n\n\t/**\n\t * Get the contract address as SS58 string\n\t */\n\tprivate getContractAddress(): SS58String {\n\t\treturn this.contractAddress;\n\t}\n\n\t/**\n\t * Extract ContractEmitted event from chain event structure\n\t * Based on polkadot-api event format\n\t */\n\tprivate extractContractEmittedEvent(chainEvent: unknown): {\n\t\tcontract: Uint8Array;\n\t\tdata: Uint8Array;\n\t\ttopics: Uint8Array[];\n\t\tblockNumber: number;\n\t\tblockHash: string;\n\t\teventIndex: number;\n\t} | null {\n\t\t// Type guard and extract event structure\n\t\tif (!chainEvent || typeof chainEvent !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst record = chainEvent as any;\n\n\t\t// Extract event data\n\t\tconst event = record.event;\n\t\tif (!event || typeof event !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Check if this is a Contracts pallet event\n\t\tif (event.type !== \"Contracts\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Check if this is a ContractEmitted event\n\t\tconst eventValue = event.value;\n\t\tif (!eventValue || typeof eventValue !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (eventValue.type !== \"ContractEmitted\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract contract address and data\n\t\tconst contractEmittedData = eventValue.value;\n\t\tif (!contractEmittedData || typeof contractEmittedData !== \"object\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst contractRaw = contractEmittedData.contract;\n\t\tconst dataRaw = contractEmittedData.data;\n\n\t\t// Handle contract address: can be SS58 string or Uint8Array\n\t\tlet contract: Uint8Array;\n\t\tif (contractRaw instanceof Uint8Array) {\n\t\t\tcontract = contractRaw;\n\t\t} else if (typeof contractRaw === \"string\") {\n\t\t\t// SS58 string format\n\t\t\tcontract = ss58Decode(contractRaw)[0];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle data: can be Binary object (with asBytes()) or Uint8Array\n\t\tlet data: Uint8Array;\n\t\tif (dataRaw instanceof Uint8Array) {\n\t\t\tdata = dataRaw;\n\t\t} else if (\n\t\t\tdataRaw &&\n\t\t\ttypeof dataRaw === \"object\" &&\n\t\t\t\"asBytes\" in dataRaw &&\n\t\t\ttypeof dataRaw.asBytes === \"function\"\n\t\t) {\n\t\t\t// Binary object format\n\t\t\tdata = dataRaw.asBytes();\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Extract topics from the event record\n\t\t// Topics are typically stored in the event record, not in the event value\n\t\tconst topics: Uint8Array[] = [];\n\n\t\t// Polkadot-API typically stores topics at the record level\n\t\t// Topics can be Uint8Array or Binary objects (with asBytes())\n\t\tif (record.topics && Array.isArray(record.topics)) {\n\t\t\tfor (const topic of record.topics) {\n\t\t\t\tif (topic instanceof Uint8Array) {\n\t\t\t\t\ttopics.push(topic);\n\t\t\t\t} else if (\n\t\t\t\t\ttopic &&\n\t\t\t\t\ttypeof topic === \"object\" &&\n\t\t\t\t\t\"asBytes\" in topic &&\n\t\t\t\t\ttypeof topic.asBytes === \"function\"\n\t\t\t\t) {\n\t\t\t\t\t// Binary object format\n\t\t\t\t\ttopics.push(topic.asBytes());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extract block metadata\n\t\tconst blockNumber =\n\t\t\ttypeof record.blockNumber === \"number\" ? record.blockNumber : 0;\n\t\tconst blockHash =\n\t\t\ttypeof record.blockHash === \"string\" ? record.blockHash : \"\";\n\t\tconst eventIndex =\n\t\t\ttypeof record.eventIndex === \"number\" ? record.eventIndex : 0;\n\n\t\treturn {\n\t\t\tcontract,\n\t\t\tdata,\n\t\t\ttopics,\n\t\t\tblockNumber,\n\t\t\tblockHash,\n\t\t\teventIndex,\n\t\t};\n\t}\n\n\t/**\n\t * Compare two Uint8Arrays for equality\n\t */\n\tprivate bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n\t\tif (a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tif (a[i] !== b[i]) return false;\n\t\t}\n\t\treturn true;\n\t}\n}\n\n/**\n * Type guard for narrowing event types\n *\n * Use this function when you have a `TypedContractEvent` and need to\n * narrow it to a specific event type. This is useful when the type\n * information is lost (e.g., after serialization or in generic functions).\n *\n * @typeParam E - The Enum type representing all possible events\n * @typeParam L - The specific event label to check\n * @param event - The event to check\n * @param label - The event label to match\n * @returns True if the event type matches the label\n *\n * @example\n * ```ts\n * const event = parser.parseEvent(chainEvent);\n *\n * if (event && isEventType(event, \"Transfer\")) {\n * // TypeScript knows event.value is Transfer event data\n * console.log(event.value.from);\n * console.log(event.value.to);\n * console.log(event.value.value);\n * }\n * ```\n */\nexport function isEventType<\n\tE extends InkEvent,\n\tL extends ExtractEventLabels<E>,\n>(\n\tevent: TypedContractEvent<E>,\n\tlabel: L,\n): event is Extract<TypedContractEvent<E>, { type: L }> {\n\treturn event.type === label;\n}\n","/**\n * Event subscriptions using RxJS\n */\nimport { Observable, filter, map, mergeMap, share, from, of, catchError } from \"rxjs\";\nimport type { PolkadotClient, SS58String } from \"polkadot-api\";\nimport type {\n InkMetadata,\n InkDescriptors,\n InkStorageDescriptor,\n InkCallableDescriptor,\n Event as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport { ContractEventParser } from \"./events\";\nimport type { TypedContractEvent, EventSubscriptionOptions } from \"./event-types\";\n\n/**\n * Block info type for type safety\n */\ninterface BlockInfo {\n number: number;\n hash: string;\n}\n\n/**\n * Create an observable stream of contract events\n *\n * @param client - Polkadot API client\n * @param descriptor - Contract descriptor\n * @param options - Subscription options\n * @returns Observable stream of type-safe contract events\n */\nexport function createContractEventStream<\n S extends InkStorageDescriptor = InkStorageDescriptor,\n M extends InkCallableDescriptor = InkCallableDescriptor,\n C extends InkCallableDescriptor = InkCallableDescriptor,\n E extends InkEvent = InkEvent,\n>(\n client: PolkadotClient,\n descriptor: InkDescriptors<S, M, C, E>,\n options: EventSubscriptionOptions,\n): Observable<TypedContractEvent<E>> {\n const parser = new ContractEventParser<S, M, C, E>(descriptor, options.contractAddress);\n\n // Subscribe to finalized blocks\n return client.finalizedBlock$.pipe(\n // For each finalized block, fetch its events\n mergeMap(async (block: BlockInfo) => {\n try {\n // Fetch System.Events at this block using the provided callback\n const events = await options.getEvents(block.hash);\n return { block, events };\n } catch (error: unknown) {\n console.error(\n \"Error fetching events at block\",\n block.number,\n \":\",\n error instanceof Error ? error.message : String(error),\n );\n // Return empty events on error to keep stream alive\n return { block, events: [] as unknown[] };\n }\n }),\n\n // Parse and filter events for this contract\n map(({ block, events }) => {\n const parsedEvents = events\n .map((event, index) => {\n // Attach block metadata to each event before parsing\n const eventWithMeta = {\n ...(event as object),\n blockNumber: block.number,\n blockHash: block.hash,\n eventIndex: index,\n };\n return parser.parseEvent(eventWithMeta);\n })\n .filter((e): e is TypedContractEvent<E> => e !== null);\n\n return parsedEvents;\n }),\n\n // Flatten array of events to individual emissions\n mergeMap((events) => from(events)),\n\n // Filter by event labels if specified\n filter((event) => {\n if (!options.eventLabels) return true;\n return options.eventLabels.includes(event.type);\n }),\n\n // Handle errors gracefully\n catchError((error: unknown) => {\n console.error(\"Error in contract event stream:\", error);\n return of(); // Return empty observable on error\n }),\n\n // Share subscription among multiple subscribers\n share(),\n );\n}\n\n/**\n * PSP22 Transfer event type\n */\nexport interface PSP22TransferEvent {\n type: \"Transfer\";\n value: {\n from?: SS58String | null;\n to?: SS58String | null;\n value: bigint;\n };\n raw: {\n blockNumber: number;\n blockHash: string;\n eventIndex: number;\n contractAddress: SS58String;\n data: Uint8Array;\n topics: Uint8Array[];\n };\n}\n\n/**\n * Convenience helper to create a Transfer event stream for PSP22 tokens\n *\n * @param client - Polkadot API client\n * @param descriptor - PSP22 contract descriptor\n * @param contractAddress - PSP22 contract address\n * @param getEvents - Function to fetch System.Events at a block hash\n * @param watchAddress - Optional address to filter transfers (only events involving this address)\n * @returns Observable stream of Transfer events\n */\nexport function createPSP22TransferStream<\n S extends InkStorageDescriptor = InkStorageDescriptor,\n M extends InkCallableDescriptor = InkCallableDescriptor,\n C extends InkCallableDescriptor = InkCallableDescriptor,\n E extends InkEvent = InkEvent,\n>(\n client: PolkadotClient,\n descriptor: InkDescriptors<S, M, C, E>,\n contractAddress: SS58String,\n getEvents: (blockHash: string) => Promise<unknown[]>,\n watchAddress?: SS58String,\n): Observable<PSP22TransferEvent> {\n return createContractEventStream<S, M, C, E>(client, descriptor, {\n contractAddress,\n eventLabels: [\"Transfer\"],\n getEvents,\n }).pipe(\n filter((event) => {\n if (!watchAddress) return true;\n\n // Filter transfers where from=watchAddress or to=watchAddress\n const value = event.value as {\n from?: SS58String | null;\n to?: SS58String | null;\n value: bigint;\n };\n\n return value.from === watchAddress || value.to === watchAddress;\n }),\n ) as Observable<PSP22TransferEvent>;\n}\n\n/**\n * Create a native token (D9) transfer event stream\n *\n * This monitors System.Transfer events instead of contract events\n *\n * @param client - Polkadot API client\n * @param getEvents - Function to fetch System.Events at a block hash\n * @param watchAddress - Address to monitor for transfers\n * @returns Observable stream of native transfer events\n */\nexport function createNativeTransferStream(\n client: PolkadotClient,\n getEvents: (blockHash: string) => Promise<unknown[]>,\n watchAddress: SS58String,\n): Observable<{\n from: SS58String;\n to: SS58String;\n amount: bigint;\n blockNumber: number;\n blockHash: string;\n}> {\n return client.finalizedBlock$.pipe(\n // For each block, query system events\n mergeMap(async (block: any) => {\n try {\n const events = await getEvents(block.hash);\n return { block, events };\n } catch (error: unknown) {\n console.error(\n \"Error fetching events for native transfers:\",\n error instanceof Error ? error.message : String(error),\n );\n return { block, events: [] };\n }\n }),\n\n // Filter for Balances.Transfer events\n map(({ block, events }) => {\n const transfers = events\n .map((record: any) => {\n // Check if this is a Balances.Transfer event\n if (record.event?.type !== \"Balances\") return null;\n if (record.event?.value?.type !== \"Transfer\") return null;\n\n const { from, to, amount } = record.event.value.value;\n\n // Filter by watchAddress\n if (from !== watchAddress && to !== watchAddress) return null;\n\n return {\n from: from as SS58String,\n to: to as SS58String,\n amount: amount as bigint,\n blockNumber: block.number,\n blockHash: block.hash,\n };\n })\n .filter((t: any): t is NonNullable<typeof t> => t !== null);\n\n return transfers;\n }),\n\n // Flatten array to individual emissions\n mergeMap((transfers: any[]) => from(transfers)),\n\n // Handle errors\n catchError((error: unknown) => {\n console.error(\"Error in native transfer stream:\", error);\n return of();\n }),\n\n // Share subscription\n share(),\n );\n}\n","/**\n * Type-safe message builder for ink! contracts\n *\n * Provides a polkadot-api compatible API for encoding and decoding\n * contract messages with full TypeScript type inference.\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n} from \"@polkadot-api/ink-contracts\";\nimport { getInkLookup, getInkDynamicBuilder } from \"@polkadot-api/ink-contracts\";\nimport type { Enum } from \"polkadot-api\";\nimport { Binary } from \"polkadot-api\";\nimport type { ExtractMessageLabels } from \"./call-types\";\n\n/**\n * Message attributes from metadata\n */\nexport interface MessageAttributes {\n\t/** Whether the message mutates state */\n\tmutates: boolean;\n\t/** Whether the message is payable */\n\tpayable: boolean;\n\t/** Whether this is the default message */\n\tdefault: boolean;\n}\n\n/**\n * Type-safe message interface with encode/decode methods\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam L - The specific message label\n */\nexport interface TypedMessage<\n\tM extends InkCallableDescriptor,\n\tL extends keyof M & string,\n> {\n\t/**\n\t * Encode message arguments to Binary\n\t *\n\t * @param args - The message arguments (fully typed)\n\t * @returns Encoded call data as Binary\n\t *\n\t * @example\n\t * ```ts\n\t * const transfer = builder.message(\"PSP22::transfer\");\n\t * const encoded = transfer.encode({\n\t * to: recipientAddress,\n\t * value: 1000n,\n\t * data: new Uint8Array(),\n\t * });\n\t * ```\n\t */\n\tencode: {} extends M[L][\"message\"]\n\t\t? (args?: M[L][\"message\"]) => Binary\n\t\t: (args: M[L][\"message\"]) => Binary;\n\n\t/**\n\t * Decode response to typed value\n\t *\n\t * @param response - The response data\n\t * @returns Decoded response value\n\t */\n\tdecode: (response: Binary | Uint8Array) => M[L][\"response\"];\n\n\t/** Message attributes (mutates, payable, default) */\n\tattributes: MessageAttributes;\n\n\t/** 4-byte selector */\n\tselector: Uint8Array;\n\n\t/** Message label */\n\tlabel: L;\n}\n\n/**\n * Contract message builder interface\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n */\nexport interface ContractMessageBuilder<M extends InkCallableDescriptor> {\n\t/**\n\t * Get a type-safe message interface for a specific message\n\t *\n\t * @param label - The message label (e.g., \"PSP22::transfer\")\n\t * @returns Typed message interface with encode/decode methods\n\t *\n\t * @example\n\t * ```ts\n\t * const transfer = builder.message(\"PSP22::transfer\");\n\t * const encoded = transfer.encode({ to, value, data });\n\t * const decoded = transfer.decode(response);\n\t * ```\n\t */\n\tmessage<L extends ExtractMessageLabels<M>>(label: L): TypedMessage<M, L>;\n\n\t/**\n\t * Get all available message labels\n\t *\n\t * @returns Array of message labels\n\t */\n\tgetMessageLabels(): Array<ExtractMessageLabels<M>>;\n}\n\n/**\n * Internal message metadata from ink! spec\n */\ninterface MessageMetadata {\n\tlabel: string;\n\tselector: string;\n\tmutates: boolean;\n\tpayable: boolean;\n\tdefault: boolean;\n\targs: Array<{ label: string; type: { type: number } }>;\n\treturnType: { type: number };\n}\n\n/**\n * Create a type-safe message builder from a contract descriptor\n *\n * @typeParam S - Storage descriptor type\n * @typeParam M - Messages descriptor type\n * @typeParam C - Constructors descriptor type\n * @typeParam E - Events Enum type\n * @param descriptor - The ink! contract descriptor containing metadata\n * @returns A ContractMessageBuilder instance\n *\n * @example\n * ```ts\n * import { createMessageBuilder } from '@d9-network/ink';\n * import { contracts } from '@polkadot-api/descriptors';\n *\n * const builder = createMessageBuilder(contracts.usdt);\n *\n * // Get a typed message interface\n * const transfer = builder.message(\"PSP22::transfer\");\n *\n * // Encode with full type checking on args\n * const encoded = transfer.encode({\n * to: recipientAddress, // Must be SS58String\n * value: 1000000n, // Must be bigint\n * data: new Uint8Array(), // Must be Uint8Array\n * });\n *\n * // Decode response with full type inference\n * const response = transfer.decode(resultBytes);\n * ```\n */\nexport function createMessageBuilder<\n\tS extends InkStorageDescriptor,\n\tM extends InkCallableDescriptor,\n\tC extends InkCallableDescriptor,\n\tE extends Enum<any>,\n>(descriptor: InkDescriptors<S, M, C, E>): ContractMessageBuilder<M> {\n\tif (!descriptor.metadata) {\n\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t}\n\n\tconst metadata = descriptor.metadata;\n\tconst lookup = getInkLookup(metadata);\n\tconst builder = getInkDynamicBuilder(lookup);\n\n\t// Cache for built message codecs\n\ttype MessageCodec = ReturnType<typeof builder.buildMessage>;\n\tconst codecCache = new Map<string, MessageCodec>();\n\n\t// Parse message metadata\n\tconst messagesMetadata = new Map<string, MessageMetadata>();\n\tfor (const msg of metadata.spec.messages as MessageMetadata[]) {\n\t\tmessagesMetadata.set(msg.label, msg);\n\t}\n\n\tfunction getMessageCodec(label: string): MessageCodec {\n\t\tconst cached = codecCache.get(label);\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\t\tconst codec = builder.buildMessage(label);\n\t\tcodecCache.set(label, codec);\n\t\treturn codec;\n\t}\n\n\tfunction parseSelector(selectorHex: string): Uint8Array {\n\t\tconst hex = selectorHex.startsWith(\"0x\")\n\t\t\t? selectorHex.slice(2)\n\t\t\t: selectorHex;\n\t\treturn new Uint8Array(\n\t\t\thex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n\t\t);\n\t}\n\n\tfunction message<L extends ExtractMessageLabels<M>>(\n\t\tlabel: L,\n\t): TypedMessage<M, L> {\n\t\tconst msgMeta = messagesMetadata.get(label);\n\t\tif (!msgMeta) {\n\t\t\tthrow new Error(`Message \"${label}\" not found in metadata`);\n\t\t}\n\n\t\tconst codec = getMessageCodec(label);\n\t\tconst selector = parseSelector(msgMeta.selector);\n\n\t\tconst encode = (args?: M[L][\"message\"]): Binary => {\n\t\t\tconst encoded = codec.call.enc(\n\t\t\t\t(args ?? {}) as Parameters<typeof codec.call.enc>[0],\n\t\t\t);\n\t\t\treturn Binary.fromBytes(encoded);\n\t\t};\n\n\t\tconst decode = (response: Binary | Uint8Array): M[L][\"response\"] => {\n\t\t\tconst bytes =\n\t\t\t\tresponse instanceof Uint8Array ? response : response.asBytes();\n\t\t\treturn codec.value.dec(bytes) as M[L][\"response\"];\n\t\t};\n\n\t\treturn {\n\t\t\tencode: encode as TypedMessage<M, L>[\"encode\"],\n\t\t\tdecode,\n\t\t\tattributes: {\n\t\t\t\tmutates: msgMeta.mutates,\n\t\t\t\tpayable: msgMeta.payable,\n\t\t\t\tdefault: msgMeta.default,\n\t\t\t},\n\t\t\tselector,\n\t\t\tlabel,\n\t\t};\n\t}\n\n\tfunction getMessageLabels(): Array<ExtractMessageLabels<M>> {\n\t\treturn Array.from(messagesMetadata.keys()) as Array<ExtractMessageLabels<M>>;\n\t}\n\n\treturn {\n\t\tmessage,\n\t\tgetMessageLabels,\n\t};\n}\n","/**\n * Structured error types for contract operations.\n * Provides detailed error information for debugging and handling.\n */\n\n/**\n * Error types for contract operations\n */\nexport type ContractErrorType =\n | \"METADATA_ERROR\" // Missing or invalid contract metadata\n | \"ENCODE_ERROR\" // Failed to encode call data\n | \"DECODE_ERROR\" // Failed to decode response\n | \"NETWORK_ERROR\" // Network or RPC error\n | \"CONTRACT_ERROR\" // Contract returned an error\n | \"LANG_ERROR\" // Ink LangError (CouldNotReadInput, etc.)\n | \"TIMEOUT_ERROR\" // Request timeout\n | \"ABORTED\" // Request was aborted\n | \"SIGNER_ERROR\" // Signer related error\n | \"TX_ERROR\"; // Transaction submission error\n\n/**\n * Base error class for all contract-related errors\n */\nexport class ContractError extends Error {\n public readonly timestamp: Date;\n\n public override readonly cause?: Error;\n\n constructor(\n message: string,\n public readonly type: ContractErrorType,\n public readonly label?: string,\n public readonly details?: unknown,\n cause?: Error,\n ) {\n super(message, { cause });\n this.name = \"ContractError\";\n this.timestamp = new Date();\n\n // Maintains proper stack trace for where error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ContractError);\n }\n }\n\n /**\n * Create a formatted error message for logging\n */\n toLogString(): string {\n const parts = [\n `[${this.type}]`,\n this.label ? `${this.label}:` : \"\",\n this.message,\n ].filter(Boolean);\n\n if (this.details) {\n parts.push(`Details: ${JSON.stringify(this.details)}`);\n }\n\n return parts.join(\" \");\n }\n\n /**\n * Convert to a plain object for serialization\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n type: this.type,\n message: this.message,\n label: this.label,\n details: this.details,\n timestamp: this.timestamp.toISOString(),\n stack: this.stack,\n };\n }\n}\n\n/**\n * Error thrown when contract metadata is missing or invalid\n */\nexport class MetadataError extends ContractError {\n constructor(message: string, details?: unknown) {\n super(message, \"METADATA_ERROR\", undefined, details);\n this.name = \"MetadataError\";\n }\n}\n\n/**\n * Error thrown when encoding call data fails\n */\nexport class EncodeError extends ContractError {\n constructor(label: string, message: string, details?: unknown) {\n super(message, \"ENCODE_ERROR\", label, details);\n this.name = \"EncodeError\";\n }\n}\n\n/**\n * Error thrown when decoding response fails\n */\nexport class DecodeError extends ContractError {\n constructor(label: string, message: string, details?: unknown) {\n super(message, \"DECODE_ERROR\", label, details);\n this.name = \"DecodeError\";\n }\n}\n\n/**\n * Error thrown for network/RPC errors\n */\nexport class NetworkError extends ContractError {\n constructor(message: string, cause?: Error, details?: unknown) {\n super(message, \"NETWORK_ERROR\", undefined, details, cause);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Error thrown when contract returns an error result\n */\nexport class ContractExecutionError extends ContractError {\n constructor(\n label: string,\n public readonly errorValue: unknown,\n ) {\n super(\n `Contract execution failed: ${JSON.stringify(errorValue)}`,\n \"CONTRACT_ERROR\",\n label,\n errorValue,\n );\n this.name = \"ContractExecutionError\";\n }\n}\n\n/**\n * Error thrown for Ink LangError\n */\nexport class LangError extends ContractError {\n constructor(\n label: string,\n public readonly variant: number,\n ) {\n const variantName =\n variant === 1 ? \"CouldNotReadInput\" : `Unknown(${variant})`;\n super(`Ink LangError: ${variantName}`, \"LANG_ERROR\", label, {\n variant,\n variantName,\n });\n this.name = \"LangError\";\n }\n}\n\n/**\n * Error thrown when request times out\n */\nexport class TimeoutError extends ContractError {\n constructor(\n label: string,\n public readonly timeoutMs: number,\n ) {\n super(`Request timed out after ${timeoutMs}ms`, \"TIMEOUT_ERROR\", label, {\n timeoutMs,\n });\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Error thrown when request is aborted\n */\nexport class AbortedError extends ContractError {\n constructor(label: string, reason?: string) {\n super(reason || \"Request was aborted\", \"ABORTED\", label, { reason });\n this.name = \"AbortedError\";\n }\n}\n\n/**\n * Error thrown for signer-related issues\n */\nexport class SignerError extends ContractError {\n constructor(message: string, details?: unknown) {\n super(message, \"SIGNER_ERROR\", undefined, details);\n this.name = \"SignerError\";\n }\n}\n\n/**\n * Error thrown when transaction submission fails\n */\nexport class TransactionError extends ContractError {\n constructor(\n label: string,\n message: string,\n public readonly txHash?: string,\n details?: unknown,\n ) {\n super(message, \"TX_ERROR\", label, { ...(details as object), txHash });\n this.name = \"TransactionError\";\n }\n}\n\n/**\n * Type guard to check if an error is a ContractError\n */\nexport function isContractError(error: unknown): error is ContractError {\n return error instanceof ContractError;\n}\n\n/**\n * Type guard to check for specific error types\n */\nexport function isErrorType<T extends ContractErrorType>(\n error: unknown,\n type: T,\n): error is ContractError & { type: T } {\n return isContractError(error) && error.type === type;\n}\n","/**\n * D9 Ink Contract implementation\n *\n * Provides a type-safe interface for interacting with ink! smart contracts\n * using state_call + ContractsApi_call instead of ReviveApi.\n */\n\nimport type { PolkadotSigner, SS58String } from \"polkadot-api\";\nimport { Binary } from \"polkadot-api\";\nimport { fromHex } from \"polkadot-api/utils\";\nimport {\n getInkLookup,\n getInkDynamicBuilder,\n type InkDescriptors,\n type InkCallableDescriptor,\n type InkStorageDescriptor,\n type InkMetadata,\n type Event as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport { ss58Decode } from \"@polkadot-labs/hdkd-helpers\";\n\nimport type {\n D9InkContract,\n QueryOptions,\n QueryResult,\n SendOptions,\n SendableTransaction,\n TxResult,\n ContractStorage,\n CreateContractOptions,\n ResponseDecoder,\n} from \"./types\";\nimport { encodeContractCall } from \"./encode\";\nimport {\n decodeContractCallResult,\n unwrapInkResult,\n isLangError,\n} from \"./decode\";\nimport { createCodecRegistry } from \"./codec-builder\";\nimport { ContractEventParser } from \"./events\";\nimport { createContractEventStream } from \"./subscriptions\";\nimport type {\n TypedContractEvent,\n EventSubscriptionOptions,\n} from \"./event-types\";\nimport type { ExtractMessageLabels } from \"./call-types\";\nimport { createMessageBuilder, type TypedMessage } from \"./message-builder\";\nimport {\n ContractError,\n MetadataError,\n DecodeError,\n LangError,\n TimeoutError,\n AbortedError,\n TransactionError,\n} from \"./errors\";\n\n/**\n * Patch LangError type in ink metadata to fix the missing index 0 variant issue.\n * Uses structuredClone for efficient deep cloning.\n */\nfunction patchLangErrorInMetadata(metadata: InkMetadata): InkMetadata {\n const patched = structuredClone(metadata);\n\n for (const typeEntry of patched.types) {\n const path = typeEntry.type?.path;\n const def = typeEntry.type?.def as {\n variant?: {\n variants: Array<{\n index: number;\n name: string;\n fields: unknown[];\n docs: string[];\n }>;\n };\n };\n if (\n path &&\n Array.isArray(path) &&\n path.includes(\"LangError\") &&\n def?.variant\n ) {\n const variants = def.variant.variants;\n if (Array.isArray(variants)) {\n const hasIndex0 = variants.some((v) => v.index === 0);\n if (!hasIndex0) {\n variants.unshift({\n index: 0,\n name: \"_Placeholder\",\n fields: [],\n docs: [],\n });\n }\n }\n }\n }\n\n return patched;\n}\n\n/**\n * Convert SS58 address to bytes\n */\nfunction ss58ToBytes(address: SS58String): Uint8Array {\n const [publicKey] = ss58Decode(address);\n return publicKey;\n}\n\n/**\n * Create a promise that rejects after a timeout\n */\nfunction createTimeout<T>(\n ms: number,\n label: string,\n): { promise: Promise<T>; clear: () => void } {\n let timeoutId: ReturnType<typeof setTimeout>;\n const promise = new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new TimeoutError(label, ms));\n }, ms);\n });\n return {\n promise,\n clear: () => clearTimeout(timeoutId),\n };\n}\n\n/**\n * Check if AbortSignal is aborted and throw if so\n */\nfunction checkAborted(signal: AbortSignal | undefined, label: string): void {\n if (signal?.aborted) {\n throw new AbortedError(label, signal.reason);\n }\n}\n\n/**\n * Create a D9 Ink Contract instance\n */\nexport function createD9InkContract<\n S extends InkStorageDescriptor,\n M extends InkCallableDescriptor,\n C extends InkCallableDescriptor,\n E extends InkEvent,\n>(\n descriptor: InkDescriptors<S, M, C, E>,\n address: SS58String,\n options: CreateContractOptions,\n): D9InkContract<M, E> {\n const { client, typedApi, defaultQueryOptions = {}, defaultSendOptions = {} } = options;\n\n if (!descriptor.metadata) {\n throw new MetadataError(\"Contract descriptor must include metadata\");\n }\n\n // Patch and prepare metadata\n const patchedMetadata = patchLangErrorInMetadata(descriptor.metadata);\n const lookup = getInkLookup(patchedMetadata);\n const builder = getInkDynamicBuilder(lookup);\n\n // Create a patched descriptor with the patched metadata for internal use\n const patchedDescriptor = {\n ...descriptor,\n metadata: patchedMetadata,\n } as InkDescriptors<S, M, C, E>;\n\n // Build auto-generated codecs\n let codecRegistry: Map<string, ResponseDecoder>;\n try {\n codecRegistry = createCodecRegistry(patchedMetadata);\n } catch (error) {\n console.warn(\"Failed to auto-generate codecs from metadata:\", error);\n codecRegistry = new Map();\n }\n\n // Convert address to bytes\n const addressBytes = ss58ToBytes(address);\n\n // Cache for message codecs\n type MessageCodec = ReturnType<typeof builder.buildMessage>;\n const messageCodecCache = new Map<string, MessageCodec>();\n\n function getMessageCodec(label: string): MessageCodec {\n const cached = messageCodecCache.get(label);\n if (cached) {\n return cached;\n }\n const codec = builder.buildMessage(label);\n messageCodecCache.set(label, codec);\n return codec;\n }\n\n /**\n * Get the decoder for a message\n */\n function getDecoder(label: string): ResponseDecoder | null {\n return codecRegistry.get(label) ?? null;\n }\n\n /**\n * Execute a query (dry-run)\n */\n async function executeQuery<K extends keyof M & string>(\n method: K,\n queryOptions: QueryOptions<M[K][\"message\"]>,\n ): Promise<QueryResult<M[K][\"response\"]>> {\n const opts = { ...defaultQueryOptions, ...queryOptions };\n const { origin, args, value = 0n, signal, timeout, at } = opts;\n\n try {\n checkAborted(signal, method);\n\n const originBytes = ss58ToBytes(origin);\n const codec = getMessageCodec(method);\n\n // Encode the call\n const callData = codec.call.enc(\n (args ?? {}) as Parameters<typeof codec.call.enc>[0],\n );\n\n // Create the state_call message\n const message = encodeContractCall(\n originBytes,\n addressBytes,\n callData,\n value,\n );\n\n // Get block hash\n const blockHash = at ?? (await client.getFinalizedBlock()).hash;\n\n checkAborted(signal, method);\n\n // Execute state_call with optional timeout\n const executeCall = async () => {\n const response = (await client._request(\"state_call\", [\n \"ContractsApi_call\",\n message,\n blockHash,\n ])) as `0x${string}`;\n\n return fromHex(response);\n };\n\n let rawResponse: Uint8Array;\n if (timeout) {\n const { promise: timeoutPromise, clear } = createTimeout<Uint8Array>(\n timeout,\n method,\n );\n try {\n rawResponse = await Promise.race([executeCall(), timeoutPromise]);\n } finally {\n clear();\n }\n } else {\n rawResponse = await executeCall();\n }\n\n checkAborted(signal, method);\n\n // Decode the ContractsApi_call response\n const callResult = decodeContractCallResult(rawResponse);\n\n // Check for execution error\n if (!callResult.success) {\n return {\n success: false,\n error: new ContractError(\n `Contract execution failed: ${callResult.debugMessage}`,\n \"CONTRACT_ERROR\",\n method,\n ),\n };\n }\n\n // Check for LangError\n if (isLangError(callResult.data)) {\n return {\n success: false,\n error: new LangError(method, callResult.data[1] ?? 1),\n };\n }\n\n // Unwrap the Result<T, LangError>\n const innerData = unwrapInkResult(callResult.data);\n\n // Decode the response\n let decodedResponse: M[K][\"response\"];\n const decoder = getDecoder(method);\n\n if (decoder) {\n try {\n decodedResponse = decoder.dec(innerData) as M[K][\"response\"];\n } catch (decodeError) {\n console.warn(\"D9InkContract: Failed to decode response:\", decodeError);\n // Fall back to papi's value codec\n const fullResult = new Uint8Array(1 + innerData.length);\n fullResult[0] = 0; // Ok variant\n fullResult.set(innerData, 1);\n\n try {\n const papiResult = codec.value.dec(fullResult);\n if (\n papiResult !== null &&\n typeof papiResult === \"object\" &&\n \"success\" in papiResult &&\n \"value\" in papiResult\n ) {\n if (papiResult.success) {\n decodedResponse = papiResult.value as M[K][\"response\"];\n } else {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Contract returned error: ${JSON.stringify(papiResult.value)}`,\n papiResult.value,\n ),\n };\n }\n } else {\n decodedResponse = papiResult as M[K][\"response\"];\n }\n } catch (error) {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Failed to decode response: ${error instanceof Error ? error.message : String(error)}`,\n { error },\n ),\n };\n }\n }\n } else {\n // No custom decoder, use papi's codec\n const fullResult = new Uint8Array(1 + innerData.length);\n fullResult[0] = 0; // Ok variant\n fullResult.set(innerData, 1);\n\n const papiResult = codec.value.dec(fullResult);\n if (\n papiResult !== null &&\n typeof papiResult === \"object\" &&\n \"success\" in papiResult &&\n \"value\" in papiResult\n ) {\n if (papiResult.success) {\n decodedResponse = papiResult.value as M[K][\"response\"];\n } else {\n return {\n success: false,\n error: new DecodeError(\n method,\n `Contract returned error: ${JSON.stringify(papiResult.value)}`,\n papiResult.value,\n ),\n };\n }\n } else {\n decodedResponse = papiResult as M[K][\"response\"];\n }\n }\n\n // Return success with QuerySuccessValue fields spread to same level\n return {\n success: true,\n value: decodedResponse,\n events: [],\n gasConsumed: callResult.gas.gasConsumed,\n gasRequired: callResult.gas.gasRequired,\n storageDeposit: callResult.storageDeposit.amount,\n send: () => createSendableTransaction(method, {\n origin,\n args,\n value,\n gasLimit: callResult.gas.gasRequired,\n }),\n };\n } catch (error) {\n if (error instanceof ContractError) {\n return { success: false, error };\n }\n return {\n success: false,\n error: new ContractError(\n error instanceof Error ? error.message : String(error),\n \"NETWORK_ERROR\",\n method,\n ),\n };\n }\n }\n\n /**\n * Create a sendable transaction\n */\n function createSendableTransaction<K extends keyof M & string>(\n method: K,\n sendOptions: SendOptions<M[K][\"message\"]>,\n ): SendableTransaction<M[K][\"response\"]> {\n const opts = { ...defaultSendOptions, ...sendOptions };\n const { origin, args, value = 0n, gasLimit, storageDepositLimit } = opts;\n\n const originBytes = ss58ToBytes(origin);\n const codec = getMessageCodec(method);\n\n // Encode the call\n const callData = codec.call.enc(\n (args ?? {}) as Parameters<typeof codec.call.enc>[0],\n );\n\n return {\n getEncodedData: () => callData,\n\n async signAndSubmit(signer: PolkadotSigner): Promise<TxResult<M[K][\"response\"]>> {\n if (!typedApi) {\n throw new TransactionError(\n method,\n \"typedApi is required for transaction submission. Pass typedApi in SDK options.\",\n );\n }\n\n try {\n // First do a dry-run to get gas estimate if not provided\n let gas = gasLimit;\n if (!gas) {\n const message = encodeContractCall(\n originBytes,\n addressBytes,\n callData,\n value,\n );\n const blockHash = (await client.getFinalizedBlock()).hash;\n const response = (await client._request(\"state_call\", [\n \"ContractsApi_call\",\n message,\n blockHash,\n ])) as `0x${string}`;\n const callResult = decodeContractCallResult(fromHex(response));\n gas = callResult.gas.gasRequired;\n }\n\n // Build the transaction using typedApi\n const api = typedApi as {\n tx: {\n Contracts: {\n call: (params: {\n dest: { type: \"Id\"; value: SS58String };\n value: bigint;\n gas_limit: { ref_time: bigint; proof_size: bigint };\n storage_deposit_limit: bigint | undefined;\n data: Binary;\n }) => {\n signAndSubmit: (\n signer: PolkadotSigner,\n options?: { at?: \"best\" | \"finalized\" }\n ) => Promise<{\n txHash: string;\n block: { hash: string; number: number };\n events: unknown[];\n }>;\n };\n };\n };\n };\n\n const tx = api.tx.Contracts.call({\n dest: { type: \"Id\", value: address },\n value,\n gas_limit: {\n ref_time: gas.refTime,\n proof_size: gas.proofSize,\n },\n storage_deposit_limit: storageDepositLimit,\n data: Binary.fromBytes(callData),\n });\n\n const txResult = await tx.signAndSubmit(signer, { at: \"finalized\" });\n\n return {\n ok: true,\n txHash: txResult.txHash,\n block: txResult.block,\n events: txResult.events ?? [],\n };\n } catch (error) {\n return {\n ok: false,\n txHash: \"\",\n block: { hash: \"\", number: 0 },\n events: [],\n dispatchError: error,\n };\n }\n },\n };\n }\n\n /**\n * Create send method that returns a sendable transaction\n */\n function send<K extends keyof M & string>(\n method: K,\n sendOptions: SendOptions<M[K][\"message\"]>,\n ): SendableTransaction<M[K][\"response\"]> {\n return createSendableTransaction(method, sendOptions);\n }\n\n /**\n * Create storage query interface\n */\n function getStorage(): ContractStorage {\n return {\n async getRoot() {\n // TODO: Implement storage root query\n console.warn(\"D9InkContract: getRoot not implemented\");\n return {\n success: false,\n value: new ContractError(\n \"Storage queries not yet implemented\",\n \"METADATA_ERROR\",\n ),\n };\n },\n\n async getNested(path: string, ..._keys: unknown[]) {\n // TODO: Implement nested storage query\n console.warn(\"D9InkContract: getNested not implemented\");\n return {\n success: false,\n value: new ContractError(\n `Storage query for \"${path}\" not yet implemented`,\n \"METADATA_ERROR\",\n ),\n };\n },\n };\n }\n\n /**\n * Filter events for this contract\n */\n function filterEvents(events: unknown[]): TypedContractEvent<E>[] {\n const parser = new ContractEventParser<S, M, C, E>(patchedDescriptor, address);\n return parser.filterEvents(events);\n }\n\n /**\n * Filter events by specific type with proper type narrowing\n */\n function filterEventsByType<L extends string>(\n events: unknown[],\n label: L,\n ): Array<TypedContractEvent<E> & { type: L }> {\n const parser = new ContractEventParser<S, M, C, E>(patchedDescriptor, address);\n return parser.filterByType(events, label);\n }\n\n // Create message builder for type-safe message encoding/decoding\n const messageBuilder = createMessageBuilder(descriptor);\n\n /**\n * Get a type-safe message interface\n */\n function message<L extends ExtractMessageLabels<M>>(\n label: L,\n ): TypedMessage<M, L> {\n return messageBuilder.message(label);\n }\n\n /**\n * Subscribe to contract events as an RxJS Observable\n *\n * @param options - Subscription options (contractAddress is automatically set)\n * @param options.getEvents - Function to fetch System.Events at a block hash\n * @param options.eventLabels - Optional filter for specific event names\n * @param options.fromBlock - Optional starting block number\n */\n function subscribeToEvents(\n options: Omit<EventSubscriptionOptions, \"contractAddress\">,\n ) {\n return createContractEventStream<S, M, C, E>(client, patchedDescriptor, {\n ...options,\n contractAddress: address,\n });\n }\n\n // Type assertion needed because the runtime correctly unwraps MessageResult\n // but TypeScript doesn't know that. The UnwrapMessageResult type in D9InkContract\n // matches what we actually return at runtime.\n return {\n address,\n metadata: patchedMetadata,\n query: executeQuery,\n send,\n getStorage,\n filterEvents,\n filterEventsByType,\n message,\n subscribeToEvents,\n } as D9InkContract<M, E>;\n}\n","/**\n * Type-safe RPC wrapper for PolkadotClient\n */\nimport type { PolkadotClient } from \"polkadot-api\";\nimport type { TypedRpcRequest } from \"./rpc-types\";\n\n/**\n * Create a type-safe RPC request function from a PolkadotClient\n *\n * This wraps the client's `_request` method with proper TypeScript types,\n * providing autocomplete for known RPC methods and type inference for\n * parameters and return values.\n *\n * @param client - The PolkadotClient instance\n * @returns A type-safe RPC request function\n *\n * @example\n * ```ts\n * const rpc = createTypedRpc(client);\n *\n * // Autocomplete for method names, typed params and return\n * const hash = await rpc(\"chain_getBlockHash\", [12345]);\n * // hash: HexString | null\n *\n * const header = await rpc(\"chain_getHeader\", [hash]);\n * // header: BlockHeader | null\n *\n * // Custom methods still work with explicit types\n * const custom = await rpc<MyType>(\"my_custom_method\", [arg]);\n * ```\n */\nexport function createTypedRpc(client: PolkadotClient): TypedRpcRequest {\n\treturn ((method: string, params: unknown[]) =>\n\t\tclient._request(method, params)) as TypedRpcRequest;\n}\n","/**\n * D9 Ink SDK entry point\n *\n * Creates an ink SDK that uses state_call + ContractsApi_call\n * instead of ReviveApi for chains that don't support it.\n */\n\nimport type { Enum, PolkadotClient, SS58String } from \"polkadot-api\";\nimport {\n type InkDescriptors,\n type InkCallableDescriptor,\n type InkStorageDescriptor,\n} from \"@polkadot-api/ink-contracts\";\n\nimport type {\n D9InkSdk,\n D9InkSdkOptions,\n D9InkContract,\n QueryOptions,\n SendOptions,\n} from \"./types\";\nimport type { TypedRpcRequest } from \"./rpc-types\";\nimport { createD9InkContract } from \"./contract\";\nimport { createTypedRpc } from \"./rpc\";\n\n/**\n * Options for creating D9 Ink SDK\n */\nexport interface CreateD9InkSdkOptions extends D9InkSdkOptions {\n /**\n * Typed API for transaction submission.\n * Required for submitting real transactions.\n */\n typedApi?: unknown;\n}\n\n/**\n * Extended D9 Ink SDK interface with typed RPC access\n */\nexport interface D9InkSdkWithRpc extends D9InkSdk {\n /**\n * Type-safe RPC request function\n *\n * Provides autocomplete for known Substrate RPC methods and type inference\n * for parameters and return values.\n *\n * @example\n * ```ts\n * // Known method with full type inference\n * const hash = await sdk.rpc(\"chain_getBlockHash\", [12345]);\n * // hash: HexString | null\n *\n * // Custom method with explicit types\n * const custom = await sdk.rpc<MyType>(\"custom_method\", [arg]);\n * ```\n */\n rpc: TypedRpcRequest;\n}\n\n/**\n * Create a D9 Ink SDK instance.\n *\n * This SDK provides a similar API to the official @polkadot-api/sdk-ink,\n * but uses state_call + ContractsApi_call instead of ReviveApi.\n *\n * @example\n * ```ts\n * import { createD9InkSdk } from \"@d9-network/ink\";\n * import { contracts } from \"@polkadot-api/descriptors\";\n *\n * const sdk = createD9InkSdk(client);\n * const usdtContract = sdk.getContract(\n * contracts.d9_usdt,\n * \"uLj9DRUujbpCyK7USZY5ebGbxdtKoWvdRvGyyUsoLWDsNng\"\n * );\n *\n * // Query balance\n * const result = await usdtContract.query(\"PSP22::balance_of\", {\n * origin: aliceAddress,\n * args: { owner: aliceAddress }\n * });\n *\n * if (result.success) {\n * console.log(\"Balance:\", result.value.response);\n *\n * // Send transaction from the query result\n * const txResult = await result.value.send().signAndSubmit(aliceSigner);\n * }\n *\n * // Or send directly\n * const txResult = await usdtContract\n * .send(\"PSP22::transfer\", {\n * origin: aliceAddress,\n * args: { to: bobAddress, value: 1000n, data: [] }\n * })\n * .signAndSubmit(aliceSigner);\n * ```\n *\n * @param client - The PolkadotClient instance\n * @param options - Optional SDK configuration\n * @returns D9 Ink SDK instance with typed RPC access\n */\nexport function createD9InkSdk(\n client: PolkadotClient,\n options: CreateD9InkSdkOptions = {},\n): D9InkSdkWithRpc {\n const { typedApi, defaultQueryOptions, defaultSendOptions } = options;\n\n return {\n getContract<\n S extends InkStorageDescriptor,\n M extends InkCallableDescriptor,\n C extends InkCallableDescriptor,\n E extends Enum<any>,\n >(\n descriptor: InkDescriptors<S, M, C, E>,\n address: SS58String,\n ): D9InkContract<M, E> {\n return createD9InkContract(descriptor, address, {\n client,\n typedApi,\n defaultQueryOptions,\n defaultSendOptions,\n });\n },\n rpc: createTypedRpc(client),\n };\n}\n\n// Re-export types for convenience\nexport type {\n D9InkSdk,\n D9InkSdkOptions,\n D9InkContract,\n QueryOptions,\n SendOptions,\n QueryResult,\n SendableTransaction,\n TxResult,\n ContractStorage,\n} from \"./types\";\n\nexport type { TypedRpcRequest } from \"./rpc-types\";\n","/**\n * Internal codec building utilities\n *\n * This module provides lower-level codec building from metadata type IDs.\n */\nimport {\n\tu8,\n\tu16,\n\tu32,\n\tu64,\n\tu128,\n\ti8,\n\ti16,\n\ti32,\n\ti64,\n\ti128,\n\tbool,\n\tstr,\n\tBytes,\n\tVector,\n\tTuple,\n\tStruct,\n\tVariant,\n\t_void,\n\tOption,\n\tAccountId,\n\ttype Codec,\n} from \"@polkadot-api/substrate-bindings\";\nimport type { InkMetadata } from \"@polkadot-api/ink-contracts\";\n\n// Use 'any' for dynamic codec building\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\ntype CodecCache = Map<number, AnyCodec>;\n\ninterface TypeDef {\n\tprimitive?: string;\n\tcomposite?: {\n\t\tfields: Array<{\n\t\t\tname?: string;\n\t\t\ttype: number;\n\t\t\ttypeName?: string;\n\t\t}>;\n\t};\n\tvariant?: {\n\t\tvariants: Array<{\n\t\t\tname: string;\n\t\t\tindex: number;\n\t\t\tfields: Array<{\n\t\t\t\tname?: string;\n\t\t\t\ttype: number;\n\t\t\t\ttypeName?: string;\n\t\t\t}>;\n\t\t}>;\n\t};\n\tsequence?: {\n\t\ttype: number;\n\t};\n\tarray?: {\n\t\tlen: number;\n\t\ttype: number;\n\t};\n\ttuple?: number[];\n}\n\ninterface TypeEntry {\n\tid: number;\n\ttype: {\n\t\tdef: TypeDef;\n\t\tpath?: string[];\n\t\tparams?: Array<{\n\t\t\tname: string;\n\t\t\ttype?: number;\n\t\t}>;\n\t};\n}\n\n/**\n * Build a SCALE codec from ink metadata type definition\n */\nfunction buildCodecFromTypeInternal(\n\ttypeId: number,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst cached = cache.get(typeId);\n\tif (cached) return cached;\n\n\tconst typeEntry = types.find((t) => t.id === typeId);\n\tif (!typeEntry) {\n\t\tthrow new Error(`Type ${typeId} not found in metadata`);\n\t}\n\n\tconst def = typeEntry.type.def;\n\tconst path = typeEntry.type.path;\n\n\t// Handle primitive types\n\tif (def.primitive) {\n\t\tconst codec = buildPrimitiveCodec(def.primitive);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle special path types\n\tif (path && path.length > 0) {\n\t\tconst specialCodec = buildSpecialTypeCodec(path, typeEntry, types, cache);\n\t\tif (specialCodec) {\n\t\t\tcache.set(typeId, specialCodec);\n\t\t\treturn specialCodec;\n\t\t}\n\t}\n\n\t// Handle tuple\n\tif (def.tuple) {\n\t\tconst codec = buildTupleCodec(def.tuple, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle sequence\n\tif (def.sequence) {\n\t\tconst innerCodec = buildCodecFromTypeInternal(def.sequence.type, types, cache);\n\t\tconst codec = Vector(innerCodec);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle array\n\tif (def.array) {\n\t\tconst innerCodec = buildCodecFromTypeInternal(def.array.type, types, cache);\n\t\tif (def.array.type === findPrimitiveTypeId(types, \"u8\")) {\n\t\t\tconst codec = Bytes(def.array.len);\n\t\t\tcache.set(typeId, codec);\n\t\t\treturn codec;\n\t\t}\n\t\tconst codec = Vector(innerCodec, def.array.len);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle composite\n\tif (def.composite) {\n\t\tconst codec = buildCompositeCodec(def.composite, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\t// Handle variant\n\tif (def.variant) {\n\t\tconst codec = buildVariantCodec(def.variant, path, types, cache);\n\t\tcache.set(typeId, codec);\n\t\treturn codec;\n\t}\n\n\tthrow new Error(`Unknown type definition for type ${typeId}`);\n}\n\nfunction buildPrimitiveCodec(primitive: string): AnyCodec {\n\tswitch (primitive) {\n\t\tcase \"u8\":\n\t\t\treturn u8;\n\t\tcase \"u16\":\n\t\t\treturn u16;\n\t\tcase \"u32\":\n\t\t\treturn u32;\n\t\tcase \"u64\":\n\t\t\treturn u64;\n\t\tcase \"u128\":\n\t\t\treturn u128;\n\t\tcase \"i8\":\n\t\t\treturn i8;\n\t\tcase \"i16\":\n\t\t\treturn i16;\n\t\tcase \"i32\":\n\t\t\treturn i32;\n\t\tcase \"i64\":\n\t\t\treturn i64;\n\t\tcase \"i128\":\n\t\t\treturn i128;\n\t\tcase \"bool\":\n\t\t\treturn bool;\n\t\tcase \"str\":\n\t\t\treturn str;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown primitive type: ${primitive}`);\n\t}\n}\n\nfunction buildSpecialTypeCodec(\n\tpath: string[],\n\ttypeEntry: TypeEntry,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec | null {\n\tconst fullPath = path.join(\"::\");\n\n\tif (fullPath.includes(\"AccountId\")) {\n\t\treturn AccountId();\n\t}\n\n\tif (path[0] === \"Option\") {\n\t\tconst params = typeEntry.type.params;\n\t\tif (params && params.length > 0 && params[0]?.type !== undefined) {\n\t\t\tconst innerCodec = buildCodecFromTypeInternal(params[0].type, types, cache);\n\t\t\treturn Option(innerCodec);\n\t\t}\n\t}\n\n\tif (path[0] === \"Result\") {\n\t\tconst params = typeEntry.type.params;\n\t\tif (params && params.length >= 2) {\n\t\t\tconst okTypeId = params[0]?.type;\n\t\t\tconst errTypeId = params[1]?.type;\n\t\t\tif (okTypeId !== undefined && errTypeId !== undefined) {\n\t\t\t\tconst okCodec = buildCodecFromTypeInternal(okTypeId, types, cache);\n\t\t\t\tconst errCodec = buildCodecFromTypeInternal(errTypeId, types, cache);\n\t\t\t\treturn Variant({ Ok: okCodec, Err: errCodec }, [0, 1]);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction buildTupleCodec(tupleTypes: number[], types: TypeEntry[], cache: CodecCache): AnyCodec {\n\tif (tupleTypes.length === 0) return _void;\n\n\tconst innerCodecs = tupleTypes.map((t) => buildCodecFromTypeInternal(t, types, cache));\n\n\tswitch (innerCodecs.length) {\n\t\tcase 1:\n\t\t\treturn Tuple(innerCodecs[0]!);\n\t\tcase 2:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!);\n\t\tcase 3:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!);\n\t\tcase 4:\n\t\t\treturn Tuple(innerCodecs[0]!, innerCodecs[1]!, innerCodecs[2]!, innerCodecs[3]!);\n\t\tdefault:\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\treturn (Tuple as any)(...innerCodecs);\n\t}\n}\n\nfunction buildCompositeCodec(\n\tcomposite: NonNullable<TypeDef[\"composite\"]>,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst fields = composite.fields;\n\n\tif (fields.length === 1 && !fields[0]?.name) {\n\t\treturn buildCodecFromTypeInternal(fields[0]!.type, types, cache);\n\t}\n\n\tconst structDef: Record<string, AnyCodec> = {};\n\tfor (const field of fields) {\n\t\tconst fieldName = field.name || `field${fields.indexOf(field)}`;\n\t\tstructDef[fieldName] = buildCodecFromTypeInternal(field.type, types, cache);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treturn Struct(structDef as any);\n}\n\nfunction buildVariantCodec(\n\tvariant: NonNullable<TypeDef[\"variant\"]>,\n\tpath: string[] | undefined,\n\ttypes: TypeEntry[],\n\tcache: CodecCache,\n): AnyCodec {\n\tconst variants = variant.variants;\n\tconst isLangError = path?.includes(\"LangError\");\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst variantDef: Record<string, any> = {};\n\tconst indices: number[] = [];\n\n\tif (isLangError && !variants.some((v) => v.index === 0)) {\n\t\tvariantDef[\"_Placeholder\"] = _void;\n\t\tindices.push(0);\n\t}\n\n\tfor (const v of variants) {\n\t\tlet fieldCodec: AnyCodec;\n\t\tconst fields = v.fields ?? [];\n\n\t\tif (fields.length === 0) {\n\t\t\tfieldCodec = _void;\n\t\t} else if (fields.length === 1 && !fields[0]?.name) {\n\t\t\tfieldCodec = buildCodecFromTypeInternal(fields[0]!.type, types, cache);\n\t\t} else {\n\t\t\tconst structDef: Record<string, AnyCodec> = {};\n\t\t\tfor (const field of fields) {\n\t\t\t\tconst fieldName = field.name || `field${fields.indexOf(field)}`;\n\t\t\t\tstructDef[fieldName] = buildCodecFromTypeInternal(field.type, types, cache);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tfieldCodec = Struct(structDef as any);\n\t\t}\n\n\t\tvariantDef[v.name] = fieldCodec;\n\t\tindices.push(v.index);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treturn Variant(variantDef as any, indices as any);\n}\n\nfunction findPrimitiveTypeId(types: TypeEntry[], primitive: string): number {\n\tconst entry = types.find((t) => t.type.def.primitive === primitive);\n\treturn entry?.id ?? -1;\n}\n\n/**\n * Build a codec for a specific type ID from ink metadata\n *\n * @param metadata - The ink contract metadata\n * @param typeId - The type ID to build codec for\n * @returns A codec with encode/decode methods\n */\nexport function buildCodecFromMetadata(\n\tmetadata: InkMetadata,\n\ttypeId: number,\n): { enc: (value: unknown) => Uint8Array; dec: (data: Uint8Array) => unknown } {\n\tconst types = metadata.types as TypeEntry[];\n\tconst cache: CodecCache = new Map();\n\n\tconst codec = buildCodecFromTypeInternal(typeId, types, cache);\n\treturn codec;\n}\n\n/**\n * Build a struct codec for message arguments\n *\n * @param metadata - The ink contract metadata\n * @param args - The argument definitions\n * @returns A struct codec\n */\nexport function buildArgsCodec(\n\tmetadata: InkMetadata,\n\targs: Array<{ label: string; type: { type: number } }>,\n): { enc: (value: unknown) => Uint8Array; dec: (data: Uint8Array) => unknown } {\n\tif (args.length === 0) {\n\t\treturn {\n\t\t\tenc: () => new Uint8Array(0),\n\t\t\tdec: () => ({}),\n\t\t};\n\t}\n\n\tconst types = metadata.types as TypeEntry[];\n\tconst cache: CodecCache = new Map();\n\n\tconst structDef: Record<string, AnyCodec> = {};\n\tfor (const arg of args) {\n\t\tstructDef[arg.label] = buildCodecFromTypeInternal(arg.type.type, types, cache);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst codec = Struct(structDef as any) as any;\n\treturn {\n\t\tenc: (value: unknown) => codec.enc(value),\n\t\tdec: (data: Uint8Array) => codec.dec(data),\n\t};\n}\n","/**\n * Call parsing for ink! contracts\n *\n * Decodes contract call data (selector + args) into type-safe call objects.\n */\nimport type {\n\tInkMetadata,\n\tInkDescriptors,\n\tInkStorageDescriptor,\n\tInkCallableDescriptor,\n\tEvent as InkEvent,\n} from \"@polkadot-api/ink-contracts\";\nimport type {\n\tTypedContractCall,\n\tRawContractCall,\n\tCallFilterOptions,\n\tMessageInfo,\n\tExtractMessageLabels,\n} from \"./call-types\";\nimport { buildArgsCodec } from \"./codec-builder-internal\";\n\n/**\n * Build argument decoders for all messages in the metadata\n */\nfunction buildAllMessageDecodersFromMetadata(\n\tmetadata: InkMetadata,\n): Map<string, { selector: Uint8Array; decoder: (data: Uint8Array) => unknown }> {\n\tconst decoders = new Map<\n\t\tstring,\n\t\t{ selector: Uint8Array; decoder: (data: Uint8Array) => unknown }\n\t>();\n\n\tconst messages = metadata.spec.messages as Array<{\n\t\tlabel: string;\n\t\tselector: string; // hex string like \"0xdb20f9f5\"\n\t\targs: Array<{\n\t\t\tlabel: string;\n\t\t\ttype: { type: number };\n\t\t}>;\n\t}>;\n\n\tfor (const message of messages) {\n\t\ttry {\n\t\t\t// Parse selector from hex string\n\t\t\tconst selectorHex = message.selector.startsWith(\"0x\")\n\t\t\t\t? message.selector.slice(2)\n\t\t\t\t: message.selector;\n\t\t\tconst selector = new Uint8Array(\n\t\t\t\tselectorHex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),\n\t\t\t);\n\n\t\t\t// Build struct decoder for message arguments\n\t\t\tconst argsCodec = buildArgsCodec(metadata, message.args);\n\t\t\tconst decoder = (data: Uint8Array) => argsCodec.dec(data);\n\n\t\t\tdecoders.set(message.label, { selector, decoder });\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to build decoder for message \"${message.label}\":`, error);\n\t\t}\n\t}\n\n\treturn decoders;\n}\n\n/**\n * Type-safe call parser for a specific contract\n *\n * @typeParam S - The storage descriptor type\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam C - The constructors descriptor type\n * @typeParam E - The events Enum type\n */\nexport class ContractCallParser<\n\tS extends InkStorageDescriptor = InkStorageDescriptor,\n\tM extends InkCallableDescriptor = InkCallableDescriptor,\n\tC extends InkCallableDescriptor = InkCallableDescriptor,\n\tE extends InkEvent = InkEvent,\n> {\n\tprivate messageDecoders: Map<\n\t\tstring,\n\t\t{ selector: Uint8Array; decoder: (data: Uint8Array) => unknown }\n\t>;\n\tprivate selectorToLabel: Map<string, string>;\n\tprivate metadata: InkMetadata;\n\n\tconstructor(descriptor: InkDescriptors<S, M, C, E>) {\n\t\tif (!descriptor.metadata) {\n\t\t\tthrow new Error(\"Contract descriptor must include metadata\");\n\t\t}\n\t\tthis.metadata = descriptor.metadata;\n\t\tthis.messageDecoders = buildAllMessageDecodersFromMetadata(this.metadata);\n\n\t\t// Build reverse lookup: selector hex -> label\n\t\tthis.selectorToLabel = new Map();\n\t\tfor (const [label, { selector }] of this.messageDecoders) {\n\t\t\tconst selectorHex = Array.from(selector)\n\t\t\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t\t\t.join(\"\");\n\t\t\tthis.selectorToLabel.set(selectorHex, label);\n\t\t}\n\t}\n\n\t/**\n\t * Parse raw call data into a type-safe contract call\n\t *\n\t * @param callData - The raw call data (selector + encoded args) or RawContractCall\n\t * @returns Parsed call or null if cannot parse\n\t *\n\t * @example\n\t * ```ts\n\t * const call = parser.parseCall(callData);\n\t * if (call?.type === \"PSP22::transfer\") {\n\t * // call.args is typed as { to: SS58String; value: bigint; data: Uint8Array }\n\t * console.log(call.args.to);\n\t * }\n\t * ```\n\t */\n\tparseCall(callData: Uint8Array | RawContractCall): TypedContractCall<M> | null {\n\t\tconst data = callData instanceof Uint8Array ? callData : callData.data;\n\t\tconst raw: RawContractCall =\n\t\t\tcallData instanceof Uint8Array ? { data: callData } : callData;\n\n\t\tif (data.length < 4) {\n\t\t\treturn null; // Need at least 4 bytes for selector\n\t\t}\n\n\t\t// Extract selector (first 4 bytes)\n\t\tconst selector = data.slice(0, 4);\n\t\tconst selectorHex = Array.from(selector)\n\t\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t\t.join(\"\");\n\n\t\t// Find message by selector\n\t\tconst label = this.selectorToLabel.get(selectorHex);\n\t\tif (!label) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst messageInfo = this.messageDecoders.get(label);\n\t\tif (!messageInfo) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode arguments (data after selector)\n\t\tconst argsData = data.slice(4);\n\t\ttry {\n\t\t\tconst args = messageInfo.decoder(argsData);\n\n\t\t\treturn {\n\t\t\t\ttype: label,\n\t\t\t\targs,\n\t\t\t\tselector,\n\t\t\t\traw,\n\t\t\t} as TypedContractCall<M>;\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to decode call \"${label}\":`, error);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Parse multiple calls and optionally filter by message labels\n\t *\n\t * @param calls - Array of raw call data\n\t * @param options - Filter options\n\t * @returns Array of parsed calls\n\t */\n\tparseCalls(\n\t\tcalls: Array<Uint8Array | RawContractCall>,\n\t\toptions?: CallFilterOptions,\n\t): TypedContractCall<M>[] {\n\t\tconst results: TypedContractCall<M>[] = [];\n\n\t\tfor (const call of calls) {\n\t\t\tconst parsed = this.parseCall(call);\n\t\t\tif (!parsed) continue;\n\n\t\t\t// Apply label filter\n\t\t\tif (options?.messageLabels && !options.messageLabels.includes(parsed.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresults.push(parsed);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Filter calls by specific type with proper type narrowing\n\t *\n\t * This method provides better type safety than parseCalls with messageLabels\n\t * because TypeScript can narrow the return type to only the specified call type.\n\t *\n\t * @param calls - Array of raw call data\n\t * @param label - The message label to filter by\n\t * @returns Array of calls narrowed to the specific type\n\t *\n\t * @example\n\t * ```ts\n\t * const transfers = parser.filterByType(callDataArray, \"PSP22::transfer\");\n\t *\n\t * for (const t of transfers) {\n\t * // t.args is fully typed as PSP22::transfer args\n\t * console.log(t.args.to, t.args.value);\n\t * }\n\t * ```\n\t */\n\tfilterByType<L extends string>(\n\t\tcalls: Array<Uint8Array | RawContractCall>,\n\t\tlabel: L,\n\t): Array<TypedContractCall<M> & { type: L }> {\n\t\treturn this.parseCalls(calls).filter(\n\t\t\t(c): c is TypedContractCall<M> & { type: L } => c.type === label,\n\t\t);\n\t}\n\n\t/**\n\t * Get information about a message by label\n\t */\n\tgetMessageInfo(label: string): MessageInfo | null {\n\t\tconst info = this.messageDecoders.get(label);\n\t\tif (!info) return null;\n\n\t\tconst messages = this.metadata.spec.messages as Array<{\n\t\t\tlabel: string;\n\t\t\tselector: string;\n\t\t\tmutates: boolean;\n\t\t\tpayable: boolean;\n\t\t\targs: Array<{ label: string; type: { type: number } }>;\n\t\t}>;\n\n\t\tconst message = messages.find((m) => m.label === label);\n\t\tif (!message) return null;\n\n\t\treturn {\n\t\t\tlabel: message.label,\n\t\t\tselector: info.selector,\n\t\t\tmutates: message.mutates,\n\t\t\tpayable: message.payable,\n\t\t\targs: message.args,\n\t\t};\n\t}\n\n\t/**\n\t * Get all available message labels\n\t */\n\tgetMessageLabels(): string[] {\n\t\treturn Array.from(this.messageDecoders.keys());\n\t}\n\n\t/**\n\t * Check if a selector matches a specific message\n\t */\n\tmatchesMessage(selector: Uint8Array, label: string): boolean {\n\t\tconst info = this.messageDecoders.get(label);\n\t\tif (!info) return false;\n\n\t\tif (selector.length !== info.selector.length) return false;\n\n\t\tfor (let i = 0; i < selector.length; i++) {\n\t\t\tif (selector[i] !== info.selector[i]) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Type guard for narrowing call types\n *\n * Use this function when you have a `TypedContractCall` and need to\n * narrow it to a specific call type. This is useful when the type\n * information is lost (e.g., after serialization or in generic functions).\n *\n * @typeParam M - The InkCallableDescriptor type (message definitions)\n * @typeParam L - The specific message label to check\n * @param call - The call to check\n * @param label - The message label to match\n * @returns True if the call type matches the label\n *\n * @example\n * ```ts\n * const call = parser.parseCall(callData);\n *\n * if (call && isCallType(call, \"PSP22::transfer\")) {\n * // TypeScript knows call.args is transfer args\n * console.log(call.args.to);\n * console.log(call.args.value);\n * }\n * ```\n */\nexport function isCallType<\n\tM extends InkCallableDescriptor,\n\tL extends ExtractMessageLabels<M>,\n>(\n\tcall: TypedContractCall<M>,\n\tlabel: L,\n): call is Extract<TypedContractCall<M>, { type: L }> {\n\treturn call.type === label;\n}\n","/**\n * Fee estimation utilities for ink! smart contracts\n */\n\nimport type { GasInfo } from \"../decode\";\n\n/**\n * Gas weight representation\n */\nexport interface GasWeight {\n\trefTime: bigint;\n\tproofSize: bigint;\n}\n\n/**\n * Estimated transaction cost breakdown\n */\nexport interface EstimatedCost {\n\t/** Cost from gas consumption */\n\tgasCost: bigint;\n\t/** Storage deposit (may be refunded) */\n\tstorageDeposit: bigint;\n\t/** Total estimated cost (gas + storage) */\n\ttotal: bigint;\n}\n\n/**\n * Formatted gas information for display\n */\nexport interface FormattedGasInfo {\n\t/** Human-readable ref_time */\n\trefTime: string;\n\t/** Human-readable proof_size */\n\tproofSize: string;\n}\n\n// D9 network weight-to-fee constants\n// These should match the chain's WeightToFee implementation\nconst WEIGHT_REF_TIME_PER_SECOND = 1_000_000_000_000n; // 1 trillion\nconst WEIGHT_FEE_COEFFICIENT = 1n; // Adjust based on chain config\n\n/**\n * Estimate the transaction cost from gas info and storage deposit\n *\n * Note: This is an approximation. Actual fees depend on chain configuration\n * and may vary slightly.\n *\n * @param gasInfo - Gas information from contract query\n * @param storageDeposit - Storage deposit amount (positive for charge, negative for refund)\n * @returns Estimated cost breakdown\n *\n * @example\n * ```typescript\n * const result = await contract.query(\"PSP22::transfer\", { origin, args });\n * if (result.success) {\n * const cost = estimateTransactionCost(\n * { gasConsumed: result.gasConsumed, gasRequired: result.gasRequired },\n * result.storageDeposit\n * );\n * console.log(`Estimated cost: ${formatBalance(cost.total, { decimals: 12 })} D9`);\n * }\n * ```\n */\nexport function estimateTransactionCost(\n\tgasInfo: GasInfo,\n\tstorageDeposit: bigint,\n): EstimatedCost {\n\t// Use gasRequired for estimation as it's the gas that will be charged\n\tconst { gasRequired } = gasInfo;\n\n\t// Simple weight-to-fee conversion\n\t// In production, this should match the chain's actual WeightToFee implementation\n\tconst gasCost =\n\t\t(gasRequired.refTime * WEIGHT_FEE_COEFFICIENT) / WEIGHT_REF_TIME_PER_SECOND +\n\t\tgasRequired.proofSize;\n\n\t// Storage deposit is additional (may be refunded later)\n\tconst effectiveStorageDeposit = storageDeposit > 0n ? storageDeposit : 0n;\n\n\treturn {\n\t\tgasCost,\n\t\tstorageDeposit: effectiveStorageDeposit,\n\t\ttotal: gasCost + effectiveStorageDeposit,\n\t};\n}\n\n/**\n * Format gas information for human-readable display\n *\n * @param gasInfo - Gas information from contract query\n * @returns Formatted strings for ref_time and proof_size\n *\n * @example\n * ```typescript\n * const formatted = formatGasInfo(result.gasRequired);\n * console.log(`Gas: refTime=${formatted.refTime}, proofSize=${formatted.proofSize}`);\n * ```\n */\nexport function formatGasInfo(gasInfo: GasInfo[\"gasRequired\"]): FormattedGasInfo {\n\treturn {\n\t\trefTime: formatWeight(gasInfo.refTime),\n\t\tproofSize: formatWeight(gasInfo.proofSize),\n\t};\n}\n\n/**\n * Format a single weight value with appropriate units\n */\nfunction formatWeight(weight: bigint): string {\n\tif (weight >= 1_000_000_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000_000_000).toFixed(2)}T`;\n\t}\n\tif (weight >= 1_000_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000_000).toFixed(2)}G`;\n\t}\n\tif (weight >= 1_000_000n) {\n\t\treturn `${(Number(weight) / 1_000_000).toFixed(2)}M`;\n\t}\n\tif (weight >= 1_000n) {\n\t\treturn `${(Number(weight) / 1_000).toFixed(2)}K`;\n\t}\n\treturn weight.toString();\n}\n\n/**\n * Apply a safety margin to gas limits\n *\n * It's recommended to add a small margin to gas estimates to account for\n * slight variations in execution. 10% (multiplier = 1.1) is a common choice.\n *\n * @param gas - The gas weight to adjust\n * @param multiplier - The multiplier to apply (default: 1.1 for 10% margin)\n * @returns Adjusted gas weight with margin applied\n *\n * @example\n * ```typescript\n * const result = await contract.query(\"PSP22::transfer\", { origin, args });\n * if (result.success) {\n * // Add 10% safety margin\n * const safeGas = applyGasMargin(result.gasRequired, 1.1);\n * await contract.send(\"PSP22::transfer\", {\n * origin,\n * args,\n * gasLimit: safeGas,\n * });\n * }\n * ```\n */\nexport function applyGasMargin(\n\tgas: GasWeight,\n\tmultiplier = 1.1,\n): GasWeight {\n\tif (multiplier <= 0) {\n\t\tthrow new Error(\"Multiplier must be positive\");\n\t}\n\n\t// Convert multiplier to basis points for precise bigint math\n\t// e.g., 1.1 -> 11000, 1.15 -> 11500\n\tconst basisPoints = BigInt(Math.round(multiplier * 10000));\n\n\treturn {\n\t\trefTime: (gas.refTime * basisPoints) / 10000n,\n\t\tproofSize: (gas.proofSize * basisPoints) / 10000n,\n\t};\n}\n\n/**\n * Compare two gas weights\n *\n * @param a - First gas weight\n * @param b - Second gas weight\n * @returns -1 if a < b, 0 if equal, 1 if a > b (compares refTime first, then proofSize)\n */\nexport function compareGasWeight(a: GasWeight, b: GasWeight): -1 | 0 | 1 {\n\tif (a.refTime < b.refTime) return -1;\n\tif (a.refTime > b.refTime) return 1;\n\tif (a.proofSize < b.proofSize) return -1;\n\tif (a.proofSize > b.proofSize) return 1;\n\treturn 0;\n}\n\n/**\n * Check if gas weight exceeds a limit\n *\n * @param gas - The gas to check\n * @param limit - The limit to compare against\n * @returns True if gas exceeds the limit in either dimension\n */\nexport function gasExceedsLimit(gas: GasWeight, limit: GasWeight): boolean {\n\treturn gas.refTime > limit.refTime || gas.proofSize > limit.proofSize;\n}\n"],"mappings":"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"}