@cofhe/abi 1.0.0-alpha.0 → 1.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/index.cjs +22 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/encryptedInputs.ts +36 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @cofhe/abi Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 84ccdb7: For overloaded functions, `extractEncryptableValues` and `insertEncryptedValues` (and so `useCofheEncryptAndWriteContract`) now pick the overload by argument count, preferring the one with encrypted inputs. Previously they took the first ABI entry with that name, which could send the value unencrypted.
|
|
8
|
+
- b9ea2d4: Preserve positional tuple shapes when ABI components are unnamed while transforming encrypted inputs and return values.
|
|
9
|
+
- Updated dependencies [d711ce2]
|
|
10
|
+
- Updated dependencies [d711ce2]
|
|
11
|
+
- Updated dependencies [5a192ee]
|
|
12
|
+
- Updated dependencies [757e448]
|
|
13
|
+
- Updated dependencies [73d5297]
|
|
14
|
+
- Updated dependencies [6dcfb7d]
|
|
15
|
+
- Updated dependencies [8fad647]
|
|
16
|
+
- Updated dependencies [a4fcea7]
|
|
17
|
+
- @cofhe/sdk@1.0.0
|
|
18
|
+
|
|
3
19
|
## 0.8.0
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -68,6 +68,20 @@ var EXTERNAL_INPUT_INTERNAL_TYPES = [
|
|
|
68
68
|
function internalTypeIsExternalInput(internalType) {
|
|
69
69
|
return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType);
|
|
70
70
|
}
|
|
71
|
+
function getInputFunction(abi, functionName, args) {
|
|
72
|
+
const overloads = abi.filter((item) => isAbiFunction(item) && item.name === functionName);
|
|
73
|
+
if (overloads.length <= 1) return overloads[0];
|
|
74
|
+
const hasExternalInputs = (fn) => fn.inputs.some((input) => paramHasExternalInput(input));
|
|
75
|
+
const byArity = overloads.filter((fn) => fn.inputs.length - (hasExternalInputs(fn) ? 1 : 0) === args.length);
|
|
76
|
+
const encrypted = byArity.filter(hasExternalInputs);
|
|
77
|
+
const candidates = encrypted.length > 0 ? encrypted : byArity;
|
|
78
|
+
if (candidates.length !== 1) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Function ${functionName} is overloaded and ${args.length} argument(s) do not select a single overload`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return candidates[0];
|
|
84
|
+
}
|
|
71
85
|
function paramHasExternalInput(param) {
|
|
72
86
|
const [internalTypeHead] = extractArrayParameterType(param.internalType);
|
|
73
87
|
if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;
|
|
@@ -106,14 +120,14 @@ function transformArrayOfExternalsToEncryptables(internalType, size, data) {
|
|
|
106
120
|
return data.map((item) => transformSingleExternalToEncryptable(internalType, item));
|
|
107
121
|
}
|
|
108
122
|
function extractEncryptableValues(abi, functionName, args) {
|
|
109
|
-
|
|
123
|
+
if (!Array.isArray(args)) {
|
|
124
|
+
throw new Error("Arguments must be an array");
|
|
125
|
+
}
|
|
126
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
110
127
|
const inputs = abiFunction?.inputs;
|
|
111
128
|
if (abiFunction == null || inputs == null) {
|
|
112
129
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
113
130
|
}
|
|
114
|
-
if (!Array.isArray(args)) {
|
|
115
|
-
throw new Error("Arguments must be an array");
|
|
116
|
-
}
|
|
117
131
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
118
132
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
119
133
|
const encryptableItems = [];
|
|
@@ -198,14 +212,14 @@ function findSignatureSlotIndex(inputs, hasExternalInputs, functionName) {
|
|
|
198
212
|
return slotIndex;
|
|
199
213
|
}
|
|
200
214
|
function insertEncryptedValues(abi, functionName, args, encryptedResult) {
|
|
201
|
-
|
|
215
|
+
if (!Array.isArray(args)) {
|
|
216
|
+
throw new Error("Arguments must be an array");
|
|
217
|
+
}
|
|
218
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
202
219
|
const inputs = abiFunction?.inputs;
|
|
203
220
|
if (abiFunction == null || inputs == null) {
|
|
204
221
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
205
222
|
}
|
|
206
|
-
if (!Array.isArray(args)) {
|
|
207
|
-
throw new Error("Arguments must be an array");
|
|
208
|
-
}
|
|
209
223
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
210
224
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
211
225
|
const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/encryptedInputs.ts","../src/utils.ts","../src/encryptedReturnTypes.ts"],"sourcesContent":["export * from './encryptedInputs';\nexport * from './encryptedReturnTypes';\nexport * from './fhenixMap';\nexport type { Abi } from 'abitype';\nexport type { ContractReturnType } from './utils';\nexport { transformEncryptedReturnTypes } from './encryptedReturnTypes';\n","import {\n Encryptable,\n type AnyExternalHash,\n type EncryptableAddress,\n type EncryptableBool,\n type EncryptableItem,\n type EncryptableUint128,\n type EncryptableUint16,\n type EncryptableUint32,\n type EncryptableUint64,\n type EncryptableUint8,\n type ExternalAddressHash,\n type ExternalBoolHash,\n type ExternalUint128Hash,\n type ExternalUint16Hash,\n type ExternalUint32Hash,\n type ExternalUint64Hash,\n type ExternalUint8Hash,\n type LiteralToPrimitive,\n type Primitive,\n} from '@cofhe/sdk';\nimport type { Abi, AbiFunction, AbiParameter, ExtractAbiFunction } from 'abitype';\nimport type { CofheAbiParametersToPrimitiveTypes } from './fhenixMap';\nimport {\n extractArrayParameterType,\n getAbiFunction,\n type MaybeExtractArrayParameterType,\n type MaybePartialBy,\n type ReadonlyWiden,\n tupleComponentsAreNamed,\n} from './utils';\n\nexport type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<\n abi,\n functionName\n>['args'];\n\ntype ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash\n ? EncryptableBool['data']\n : E extends ExternalUint8Hash\n ? EncryptableUint8['data']\n : E extends ExternalUint16Hash\n ? EncryptableUint16['data']\n : E extends ExternalUint32Hash\n ? EncryptableUint32['data']\n : E extends ExternalUint64Hash\n ? EncryptableUint64['data']\n : E extends ExternalUint128Hash\n ? EncryptableUint128['data']\n : E extends ExternalAddressHash\n ? EncryptableAddress['data']\n : never;\n\n// Note: AnyExternalHash is checked before Primitive - the branded hash types are structurally\n// `0x${string}` (a subtype of `string`, which is itself a Primitive), so Primitive must not be\n// checked first or every hash would be (incorrectly) widened via LiteralToPrimitive instead.\ntype EncryptedInputsToInputs<T> = T extends AnyExternalHash\n ? ExternalHashToInputMap<T>\n : T extends Primitive\n ? LiteralToPrimitive<T>\n : {\n [K in keyof T]: EncryptedInputsToInputs<T[K]>;\n };\n\n/**\n * Drops the batch-signature argument from an args tuple.\n *\n * The signature slot is the first non-`external*` parameter that follows the contiguous run of\n * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the\n * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters\n * and the args tuple in lockstep and elides the arg at that position.\n */\ntype DropSignatureSlotTuple<\n params extends readonly unknown[],\n args extends readonly unknown[],\n afterExternalRun extends boolean = false,\n> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]]\n ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]]\n ? P extends AbiParameter\n ? ParamHasExternalInput<P> extends true\n ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>]\n : afterExternalRun extends true\n ? DropSignatureSlotTuple<PRest, ARest, false>\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>]\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>]\n : readonly []\n : args;\n\n/** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */\ntype DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[]\n ? DropSignatureSlotTuple<params, args>\n : args;\n\nconst EXTERNAL_INPUT_INTERNAL_TYPES = [\n 'externalEbool',\n 'externalEuint8',\n 'externalEuint16',\n 'externalEuint32',\n 'externalEuint64',\n 'externalEuint128',\n 'externalEaddress',\n] as const;\ntype ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];\n\n/** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */\ntype ParamHasExternalInput<param extends AbiParameter> =\n MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any]\n ? head extends ExternalInputInternalType\n ? true\n : // A struct array (`tuple[]` / `tuple[N]`) lands here too, with `head` the struct's own\n // internalType. Falling through to the components keeps `Order[]` visible as carrying\n // encrypted inputs, the way the runtime `paramHasExternalInput` already sees it.\n ParamComponentsHaveExternalInput<param>\n : param['internalType'] extends ExternalInputInternalType\n ? true\n : ParamComponentsHaveExternalInput<param>;\n\n/** Recurses into a parameter's `components`, for tuples at any array depth. */\ntype ParamComponentsHaveExternalInput<param extends AbiParameter> = param extends {\n components: infer components extends readonly AbiParameter[];\n}\n ? ParamsHaveExternalInput<components>\n : false;\n\ntype ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [\n infer Head extends AbiParameter,\n ...infer Rest extends readonly AbiParameter[],\n]\n ? ParamHasExternalInput<Head> extends true\n ? true\n : ParamsHaveExternalInput<Rest>\n : false;\n\n/**\n * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.\n *\n * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter\n * immediately following them is the shared batch signature slot - the caller never supplies it\n * directly (the SDK injects it after encryption), so it's dropped from this type entirely.\n */\nexport type CofheInputArgsPreTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n> = EncryptedInputsToInputs<\n ParamsHaveExternalInput<abiFunction['inputs']> extends true\n ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>>\n : CofheInputArgs<abi, functionName>\n>;\n\n/// GetArgs from abitype (not exported from abitype)\ntype GetArgs<\n abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly [],\n ///\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>,\n args_ =\n | primitiveTypes // show all values\n | (abi extends Abi\n ? args extends primitiveTypes // infer value (if valid)\n ? primitiveTypes extends args // make sure `args` exactly matches `primitiveTypes` (e.g. avoid `args: readonly [{ foo: string; bar: number; }] | readonly [{ foo: string; }]`)\n ? // make inferred value of `args` match `primitiveTypes` (e.g. avoid union `args: readonly [123n] | readonly [bigint]`)\n ReadonlyWiden<args>\n : never\n : never\n : never)\n | (Abi extends abi ? readonly unknown[] : never), // fallback if `abi` is declared as `Abi`\n> = MaybePartialBy<{ args: args_ }, readonly [] extends primitiveTypes ? 'args' : Abi extends abi ? 'args' : string>;\n\nfunction internalTypeIsExternalInput(internalType: string): internalType is ExternalInputInternalType {\n return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType as any);\n}\n\nfunction paramHasExternalInput(param: AbiParameter): boolean {\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;\n if ('components' in param && Array.isArray(param.components)) {\n return param.components.some((component) => paramHasExternalInput(component));\n }\n return false;\n}\n\nfunction transformSingleExternalToEncryptable(internalType: ExternalInputInternalType, data: unknown): EncryptableItem {\n switch (internalType) {\n case 'externalEbool':\n return Encryptable.bool(data as boolean);\n case 'externalEuint8':\n return Encryptable.uint8(data as string | bigint);\n case 'externalEuint16':\n return Encryptable.uint16(data as string | bigint);\n case 'externalEuint32':\n return Encryptable.uint32(data as string | bigint);\n case 'externalEuint64':\n return Encryptable.uint64(data as string | bigint);\n case 'externalEuint128':\n return Encryptable.uint128(data as string | bigint);\n case 'externalEaddress':\n return Encryptable.address(data as string | bigint);\n default:\n throw new Error(`Unknown external input type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfExternalsToEncryptables(\n internalType: ExternalInputInternalType,\n size: string | undefined,\n data: unknown\n): EncryptableItem[] {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n return data.map((item) => transformSingleExternalToEncryptable(internalType, item));\n}\n\n/**\n * Extracts encryptable values from function arguments based on the ABI.\n * Transforms raw data values into EncryptableItem objects that can be passed to the encrypt function.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;\n * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)\n * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order\n */\nexport function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>\n): EncryptableItem[] {\n const abiFunction = getAbiFunction(abi, functionName);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n // Collect encrypted values as EncryptableItem objects in order (flat array)\n const encryptableItems: EncryptableItem[] = [];\n\n function processParameter(param: AbiParameter, value: unknown): void {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Bare external input (e.g. `externalEuint32`, type: 'bytes32')\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n encryptableItems.push(transformSingleExternalToEncryptable(internalTypeHead, value));\n return;\n }\n\n // Array of external inputs (e.g. `externalEuint32[]`/`externalEuint32[2]`, type: 'bytes32[]'/'bytes32[2]')\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const encryptables = transformArrayOfExternalsToEncryptables(internalTypeHead, typeSize, value);\n encryptableItems.push(...encryptables);\n return;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): void => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n components.forEach((component) => {\n processParameter(component, valueObj[component.name]);\n });\n return;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n components.forEach((component, index) => {\n processParameter(component, tupleValue[index]);\n });\n };\n\n // `tuple[]` / `tuple[N]`: walk each element as its own tuple. Treating the array\n // itself as one tuple would look up named components on the array object, find\n // none, and hand `undefined` to the encryptable transform.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n value.forEach(processTuple);\n return;\n }\n\n processTuple(value);\n }\n return;\n }\n\n // Not an external input, and cannot contain one\n return;\n }\n\n // Process all inputs, skipping the batch-signature slot (nothing to extract there). `args` is the\n // pre-transform tuple, which omits that slot, so its indices lag by one past the signature.\n let argIndex = 0;\n inputs.forEach((input, index) => {\n if (index === signatureSlotIndex) return;\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n processParameter(input, arg);\n });\n\n return encryptableItems;\n}\n\n/**\n * Index of the shared batch-signature parameter: the plain `bytes` immediately after the\n * contiguous run of `external*` parameters. Returns -1 when the function has no encrypted inputs.\n *\n * The proof pairs with the hashes it authenticates (`FHE.asEuintXX(hash, proof)`), so it does not\n * have to be the last parameter - anything may follow it.\n */\nfunction findSignatureSlotIndex(\n inputs: readonly AbiParameter[],\n hasExternalInputs: boolean,\n functionName: string\n): number {\n if (!hasExternalInputs) return -1;\n\n const externalIndices = inputs.reduce<number[]>((acc, input, index) => {\n if (paramHasExternalInput(input)) acc.push(index);\n return acc;\n }, []);\n\n const first = externalIndices[0]!;\n const last = externalIndices[externalIndices.length - 1]!;\n if (last - first + 1 !== externalIndices.length) {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs at non-adjacent positions ` +\n `(${externalIndices.join(', ')}). They share one batch signature, so they must be contiguous ` +\n `with the 'bytes' signature parameter immediately after them`\n );\n }\n\n const slotIndex = last + 1;\n const slot = inputs[slotIndex];\n if (slot?.type !== 'bytes') {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs, so the parameter immediately after ` +\n `them must be a plain 'bytes' parameter to receive the shared batch signature - found ` +\n `'${slot?.type ?? 'nothing'}' at position ${slotIndex} instead`\n );\n }\n\n return slotIndex;\n}\n\n/**\n * Re-inserts encrypted values back into function arguments based on the ABI.\n * Takes the batch-verified result (per-input hashes, in order, followed by the single shared\n * signature) and the original args structure, and produces the final call args: each `external*`\n * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.\n *\n * This function mirrors the extraction logic in extractEncryptableValues, ensuring values\n * are inserted in the exact same order and locations where they were extracted.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Original function arguments in the format of CofheInputArgsPreTransform\n * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`\n * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)\n */\nexport function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>,\n encryptedResult: readonly `0x${string}`[]\n): CofheInputArgs<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];\n const signature = hasExternalInputs ? encryptedResult[encryptedResult.length - 1] : undefined;\n\n // Track position in the hashes array\n let hashIndex = 0;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n\n // Bare external input - substitute its hash\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n if (hashIndex >= hashes.length) {\n throw new Error(`Not enough encrypted hashes: expected at least ${hashIndex + 1}, got ${hashes.length}`);\n }\n const hash = hashes[hashIndex];\n hashIndex++;\n return hash;\n }\n\n // Array of external inputs - substitute the corresponding slice of hashes\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const arrayLength = Array.isArray(value) ? value.length : 0;\n if (arrayLength === 0) {\n return [];\n }\n\n if (hashIndex + arrayLength > hashes.length) {\n throw new Error(\n `Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`\n );\n }\n\n const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);\n hashIndex += arrayLength;\n return hashArray;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: rebuild each element as its own tuple, in the same order\n // extractEncryptableValues walked them, so the hashes line up. Treating the array as\n // one tuple would consume no hashes and collapse the argument to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n return value;\n }\n\n // Not an external input, return original value\n return value;\n }\n\n // Rebuild the full arg list; the signature slot is injected directly. `args` omits that slot, so\n // its indices lag by one past the signature position.\n let argIndex = 0;\n const result = inputs.map((input, index) => {\n if (index === signatureSlotIndex) {\n return signature;\n }\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n return processParameter(input, arg);\n });\n\n // Verify we used all encrypted hashes\n if (hashIndex !== hashes.length) {\n throw new Error(`Mismatch in encrypted hashes count: used ${hashIndex}, but provided ${hashes.length}`);\n }\n\n return result as CofheInputArgs<TAbi, TFunctionName>;\n}\n","import type {\n Abi,\n AbiConstructor,\n AbiError,\n AbiEvent,\n AbiFallback,\n AbiFunction,\n AbiParameter,\n AbiParametersToPrimitiveTypes,\n AbiReceive,\n AbiType,\n Address,\n ExtractAbiFunction,\n ResolvedRegister,\n SolidityArray,\n SolidityFixedArrayRange,\n SolidityTuple,\n} from 'abitype';\n\nexport type ContractReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends AbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = AbiParametersToPrimitiveTypes<outputs, 'outputs', true>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\nexport type Error<messages extends string | string[]> = messages extends string\n ? [\n // Surrounding with array to prevent `messages` from being widened to `string`\n `Error: ${messages}`,\n ]\n : {\n [key in keyof messages]: messages[key] extends infer message extends string ? `Error: ${message}` : never;\n };\n\ntype PartialBy<TType, TKeys extends keyof TType> = ExactPartial<Pick<TType, TKeys>> & Omit<TType, TKeys>;\ntype ExactPartial<T> = { [K in keyof T]?: T[K] | undefined };\n\nexport type MaybePartialBy<TType, TKeys extends string> = TKeys extends keyof TType ? PartialBy<TType, TKeys> : TType;\n\nexport type ReadonlyWiden<TType> =\n | (TType extends Function ? TType : never)\n | (TType extends ResolvedRegister['bigIntType'] ? bigint : never)\n | (TType extends boolean ? boolean : never)\n | (TType extends ResolvedRegister['intType'] ? number : never)\n | (TType extends string\n ? TType extends Address\n ? Address\n : TType extends ResolvedRegister['bytesType']['inputs']\n ? ResolvedRegister['bytesType']\n : string\n : never)\n | (TType extends readonly [] ? readonly [] : never)\n | (TType extends Record<string, unknown> ? { [K in keyof TType]: ReadonlyWiden<TType[K]> } : never)\n | (TType extends { length: number }\n ? {\n [K in keyof TType]: ReadonlyWiden<TType[K]>;\n } extends infer Val extends unknown[]\n ? readonly [...Val]\n : never\n : never);\n\nexport type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>;\n\n/**\n * First, infer `Head` against a known size type (either fixed-length array value or `\"\"`).\n *\n * | Input | Head |\n * | --------------- | ------------ |\n * | `string[]` | `string` |\n * | `string[][][3]` | `string[][]` |\n */\nexport type MaybeExtractArrayParameterType<type> = type extends `${infer head}[${'' | `${SolidityFixedArrayRange}`}]`\n ? // * Then, infer in the opposite direction, using the known `head` to infer the exact `size` value.\n // *\n // * | Input | Size |\n // * | ------------ | ---- |\n // * | `${head}[]` | `\"\"` |\n // * | `${head}[3]` | `3` |\n // */\n type extends `${head}[${infer size}]`\n ? [head, size]\n : undefined\n : undefined;\n\nexport type IsUnion<T, C = T> = T extends C ? ([C] extends [T] ? false : true) : never;\nexport type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]\n ? []\n : [...UnionToTuple<Exclude<U, Last>>, Last];\ntype LastInUnion<U> =\n UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;\ntype UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;\n\n/**\n * Create tuple of {@link type} type with {@link size} size\n *\n * @param Type - Type of tuple\n * @param Size - Size of tuple\n * @returns Tuple of {@link type} type with {@link size} size\n *\n * @example\n * type Result = Tuple<string, 2>\n * // ^? type Result = [string, string]\n */\n// https://github.com/Microsoft/TypeScript/issues/26223#issuecomment-674500430\nexport type Tuple<type, size extends number> = size extends size\n ? number extends size\n ? type[]\n : _TupleOf<type, size, []>\n : never;\ntype _TupleOf<length, size extends number, acc extends readonly unknown[]> = acc['length'] extends size\n ? acc\n : _TupleOf<length, size, readonly [length, ...acc]>;\n\n/**\n * Merges two object types into new type\n *\n * @param object1 - Object to merge into\n * @param object2 - Object to merge and override keys from {@link object1}\n * @returns New object type with keys from {@link object1} and {@link object2}. If a key exists in both {@link object1} and {@link object2}, the key from {@link object2} will be used.\n *\n * @example\n * type Result = Merge<{ foo: string }, { foo: number; bar: string }>\n * // ^? type Result = { foo: number; bar: string }\n */\nexport type Merge<object1, object2> = Omit<object1, keyof object2> & object2;\n\n// FUNCTIONS\n\n/**\n * Extracts array parameter type information from a type string.\n * Always returns a tuple, with undefined for non-array types.\n *\n * @param type - Type string like \"tuple\", \"tuple[]\", or \"tuple[2]\"\n * @returns [head, size] where:\n * - head is the base type\n * - size is undefined for non-arrays, \"\" for dynamic arrays, or the number as a string for fixed arrays\n *\n * @example\n * extractArrayParameterType(\"tuple\") // [\"tuple\", undefined]\n * extractArrayParameterType(\"tuple[]\") // [\"tuple\", \"\"]\n * extractArrayParameterType(\"tuple[2]\") // [\"tuple\", \"2\"]\n */\nexport function extractArrayParameterType<T extends string | undefined>(type: T): [T, string | undefined] {\n if (type == null) return [type, undefined];\n\n const match = type.match(/^(.+)\\[(\\d*)\\]$/);\n\n if (!match) {\n // Not an array type, return [type, undefined]\n return [type, undefined];\n }\n\n const head = match[1];\n const size = match[2]; // Empty string for dynamic arrays, or digits for fixed arrays\n\n // Return empty string for dynamic arrays, or the size string for fixed arrays\n return [head as T, size === '' ? '' : size];\n}\n\n/**\n * Matches the tuple-shape rule used by `CofheAbiComponentsToPrimitiveType`:\n * tuples are objects only when every component has a name. Otherwise they are\n * represented positionally as arrays.\n */\nexport function tupleComponentsAreNamed(components: readonly AbiParameter[]): boolean {\n return components.length > 0 && components.every((component) => component.name != null && component.name !== '');\n}\n\ntype AbiItem = AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive;\n\nexport function isAbiFunction(item: AbiItem | unknown): item is AbiFunction {\n if (typeof item !== 'object' || item === null) return false;\n return 'type' in item && item.type === 'function' && 'name' in item && 'outputs' in item;\n}\n\nexport function getAbiFunction<TAbi extends Abi | readonly unknown[], TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName\n): AbiFunction | undefined {\n return abi.find((item) => {\n const isFunction = isAbiFunction(item);\n if (!isFunction) return false;\n return item.name === functionName;\n }) as AbiFunction | undefined;\n}\n","import { type Primitive, type LiteralToPrimitive, FheTypes } from '@cofhe/sdk';\nimport type { Abi, AbiFunction, ExtractAbiFunction, AbiParameter } from 'abitype';\nimport type {\n EncryptedReturnType,\n CofheAbiParametersToPrimitiveTypes,\n EBool,\n EAddress,\n EUint128,\n EUint16,\n EUint32,\n EUint64,\n EUint8,\n} from './fhenixMap';\nimport {\n getAbiFunction,\n type IsUnion,\n type UnionToTuple,\n type ContractReturnType,\n extractArrayParameterType,\n tupleComponentsAreNamed,\n} from './utils';\n\ntype FirstCofheReturnValue<T> = [T] extends [void]\n ? never\n : T extends readonly [infer Head, ...(readonly unknown[])]\n ? Head\n : T;\n\ntype FheTypeFromCofheReturnValue<T> = T extends { utype: infer U }\n ? U\n : T extends readonly (infer Element)[]\n ? FheTypeFromCofheReturnValue<Element>\n : never;\n\n/**\n * Extracts the `FheTypes` of the first returned value of a CoFHE call.\n *\n * Examples:\n * - `returns (ebool)` -> `FheTypes.Bool`\n * - `returns (euint8, euint64)` -> `FheTypes.Uint8`\n * - `returns (euint16[])` -> `FheTypes.Uint16`\n */\nexport type CofheFirstReturnFheType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = FheTypeFromCofheReturnValue<FirstCofheReturnValue<CofheReturnType<abi, functionName, args>>>;\n\nexport type CofheReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends CofheAbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = CofheAbiParametersToPrimitiveTypes<outputs, 'outputs'>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\ntype EncryptedReturnTypeToReturnTypeMap<E extends EncryptedReturnType> = E extends EBool\n ? boolean\n : E extends EUint8\n ? bigint\n : E extends EUint16\n ? bigint\n : E extends EUint32\n ? bigint\n : E extends EUint64\n ? bigint\n : E extends EUint128\n ? bigint\n : E extends EAddress\n ? string\n : never;\n\ntype EncryptedReturnTypesToReturnTypes<T> = T extends Primitive\n ? LiteralToPrimitive<T>\n : T extends EncryptedReturnType\n ? EncryptedReturnTypeToReturnTypeMap<T>\n : {\n [K in keyof T]: EncryptedReturnTypesToReturnTypes<T[K]>;\n };\n\nexport type CofheReturnTypePostTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = EncryptedReturnTypesToReturnTypes<CofheReturnType<abi, functionName, args>>;\n\nconst ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES = [\n 'ebool',\n 'euint8',\n 'euint16',\n 'euint32',\n 'euint64',\n 'euint128',\n 'eaddress',\n] as const;\ntype EncryptedReturnTypeInternalType = (typeof ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES)[number];\n\ntype EncryptedReturnTypeInternalTypeToReturnTypeMap<T extends EncryptedReturnTypeInternalType> = T extends 'ebool'\n ? EBool\n : T extends 'euint8'\n ? EUint8\n : T extends 'euint16'\n ? EUint16\n : T extends 'euint32'\n ? EUint32\n : T extends 'euint64'\n ? EUint64\n : T extends 'euint128'\n ? EUint128\n : T extends 'eaddress'\n ? EAddress\n : never;\n\nfunction transformSingleEncryptedReturnTypeToReturnType<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n data: string\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T> {\n switch (internalType) {\n case 'ebool':\n return {\n ctHash: data,\n utype: FheTypes.Bool,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint8':\n return {\n ctHash: data,\n utype: FheTypes.Uint8,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint16':\n return {\n ctHash: data,\n utype: FheTypes.Uint16,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint32':\n return {\n ctHash: data,\n utype: FheTypes.Uint32,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint64':\n return {\n ctHash: data,\n utype: FheTypes.Uint64,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint128':\n return {\n ctHash: data,\n utype: FheTypes.Uint128,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'eaddress':\n return {\n ctHash: data,\n utype: FheTypes.Uint160,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n default:\n throw new Error(`Unknown encrypted return type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfEncryptedReturnTypesToReturnTypes<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n size: string | undefined,\n data: string[]\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T>[] {\n // Ensure data is an array\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n // Ensure length of fixed length tuple matches the length of the data array\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n // Transform each item in the data array into an return type\n return data.map((item) => transformSingleEncryptedReturnTypeToReturnType(internalType, item));\n}\n\nfunction internalTypeIsEncryptedReturnType(internalType: string): internalType is EncryptedReturnTypeInternalType {\n return ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES.includes(internalType as any);\n}\n\nexport function transformEncryptedReturnTypes<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n data: ContractReturnType<TAbi, TFunctionName>\n): CofheReturnType<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const outputs = abiFunction?.outputs;\n if (abiFunction == null || outputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n const outputsLength = outputs.length;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Is encrypted return type\n if (internalTypeHead != null && internalTypeIsEncryptedReturnType(internalTypeHead)) {\n // Is single encrypted return type\n if (internalTypeSize == null) {\n return transformSingleEncryptedReturnTypeToReturnType(internalTypeHead, value as string);\n }\n\n // Is array of encrypted return types\n if (internalTypeSize != null) {\n return transformArrayOfEncryptedReturnTypesToReturnTypes(internalTypeHead, internalTypeSize, value as string[]);\n }\n }\n\n // Tuple but not an encrypted return type (recursive case)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: transform each element as its own tuple. Treating the\n // array itself as one tuple would look up named components on the array object,\n // find none, and collapse the whole result to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n\n return value;\n }\n\n // Not an encrypted return type, return original value\n return value;\n }\n\n // Process results (array case)\n if (outputsLength > 1) {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n if (outputsLength !== data.length) {\n throw new Error(`Mismatch in outputs length: ${outputsLength} !== ${data.length}`);\n }\n return data.map((item, index) => {\n return processParameter(outputs[index], item);\n }) as CofheReturnType<TAbi, TFunctionName>;\n }\n\n // Process retuls (single item case)\n return processParameter(outputs[0], data) as CofheReturnType<TAbi, TFunctionName>;\n}\n"],"mappings":"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","names":["result","import_sdk"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/encryptedInputs.ts","../src/utils.ts","../src/encryptedReturnTypes.ts"],"sourcesContent":["export * from './encryptedInputs';\nexport * from './encryptedReturnTypes';\nexport * from './fhenixMap';\nexport type { Abi } from 'abitype';\nexport type { ContractReturnType } from './utils';\nexport { transformEncryptedReturnTypes } from './encryptedReturnTypes';\n","import {\n Encryptable,\n type AnyExternalHash,\n type EncryptableAddress,\n type EncryptableBool,\n type EncryptableItem,\n type EncryptableUint128,\n type EncryptableUint16,\n type EncryptableUint32,\n type EncryptableUint64,\n type EncryptableUint8,\n type ExternalAddressHash,\n type ExternalBoolHash,\n type ExternalUint128Hash,\n type ExternalUint16Hash,\n type ExternalUint32Hash,\n type ExternalUint64Hash,\n type ExternalUint8Hash,\n type LiteralToPrimitive,\n type Primitive,\n} from '@cofhe/sdk';\nimport type { Abi, AbiFunction, AbiParameter, ExtractAbiFunction } from 'abitype';\nimport type { CofheAbiParametersToPrimitiveTypes } from './fhenixMap';\nimport {\n extractArrayParameterType,\n isAbiFunction,\n type MaybeExtractArrayParameterType,\n type MaybePartialBy,\n type ReadonlyWiden,\n tupleComponentsAreNamed,\n} from './utils';\n\nexport type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<\n abi,\n functionName\n>['args'];\n\ntype ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash\n ? EncryptableBool['data']\n : E extends ExternalUint8Hash\n ? EncryptableUint8['data']\n : E extends ExternalUint16Hash\n ? EncryptableUint16['data']\n : E extends ExternalUint32Hash\n ? EncryptableUint32['data']\n : E extends ExternalUint64Hash\n ? EncryptableUint64['data']\n : E extends ExternalUint128Hash\n ? EncryptableUint128['data']\n : E extends ExternalAddressHash\n ? EncryptableAddress['data']\n : never;\n\n// Note: AnyExternalHash is checked before Primitive - the branded hash types are structurally\n// `0x${string}` (a subtype of `string`, which is itself a Primitive), so Primitive must not be\n// checked first or every hash would be (incorrectly) widened via LiteralToPrimitive instead.\ntype EncryptedInputsToInputs<T> = T extends AnyExternalHash\n ? ExternalHashToInputMap<T>\n : T extends Primitive\n ? LiteralToPrimitive<T>\n : {\n [K in keyof T]: EncryptedInputsToInputs<T[K]>;\n };\n\n/**\n * Drops the batch-signature argument from an args tuple.\n *\n * The signature slot is the first non-`external*` parameter that follows the contiguous run of\n * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the\n * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters\n * and the args tuple in lockstep and elides the arg at that position.\n */\ntype DropSignatureSlotTuple<\n params extends readonly unknown[],\n args extends readonly unknown[],\n afterExternalRun extends boolean = false,\n> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]]\n ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]]\n ? P extends AbiParameter\n ? ParamHasExternalInput<P> extends true\n ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>]\n : afterExternalRun extends true\n ? DropSignatureSlotTuple<PRest, ARest, false>\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>]\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>]\n : readonly []\n : args;\n\n/** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */\ntype DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[]\n ? DropSignatureSlotTuple<params, args>\n : args;\n\nconst EXTERNAL_INPUT_INTERNAL_TYPES = [\n 'externalEbool',\n 'externalEuint8',\n 'externalEuint16',\n 'externalEuint32',\n 'externalEuint64',\n 'externalEuint128',\n 'externalEaddress',\n] as const;\ntype ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];\n\n/** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */\ntype ParamHasExternalInput<param extends AbiParameter> =\n MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any]\n ? head extends ExternalInputInternalType\n ? true\n : // A struct array (`tuple[]` / `tuple[N]`) lands here too, with `head` the struct's own\n // internalType. Falling through to the components keeps `Order[]` visible as carrying\n // encrypted inputs, the way the runtime `paramHasExternalInput` already sees it.\n ParamComponentsHaveExternalInput<param>\n : param['internalType'] extends ExternalInputInternalType\n ? true\n : ParamComponentsHaveExternalInput<param>;\n\n/** Recurses into a parameter's `components`, for tuples at any array depth. */\ntype ParamComponentsHaveExternalInput<param extends AbiParameter> = param extends {\n components: infer components extends readonly AbiParameter[];\n}\n ? ParamsHaveExternalInput<components>\n : false;\n\ntype ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [\n infer Head extends AbiParameter,\n ...infer Rest extends readonly AbiParameter[],\n]\n ? ParamHasExternalInput<Head> extends true\n ? true\n : ParamsHaveExternalInput<Rest>\n : false;\n\n/**\n * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.\n *\n * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter\n * immediately following them is the shared batch signature slot - the caller never supplies it\n * directly (the SDK injects it after encryption), so it's dropped from this type entirely.\n */\nexport type CofheInputArgsPreTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n> = EncryptedInputsToInputs<\n ParamsHaveExternalInput<abiFunction['inputs']> extends true\n ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>>\n : CofheInputArgs<abi, functionName>\n>;\n\n/// GetArgs from abitype (not exported from abitype)\ntype GetArgs<\n abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly [],\n ///\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>,\n args_ =\n | primitiveTypes // show all values\n | (abi extends Abi\n ? args extends primitiveTypes // infer value (if valid)\n ? primitiveTypes extends args // make sure `args` exactly matches `primitiveTypes` (e.g. avoid `args: readonly [{ foo: string; bar: number; }] | readonly [{ foo: string; }]`)\n ? // make inferred value of `args` match `primitiveTypes` (e.g. avoid union `args: readonly [123n] | readonly [bigint]`)\n ReadonlyWiden<args>\n : never\n : never\n : never)\n | (Abi extends abi ? readonly unknown[] : never), // fallback if `abi` is declared as `Abi`\n> = MaybePartialBy<{ args: args_ }, readonly [] extends primitiveTypes ? 'args' : Abi extends abi ? 'args' : string>;\n\nfunction internalTypeIsExternalInput(internalType: string): internalType is ExternalInputInternalType {\n return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType as any);\n}\n\n/**\n * Resolves `functionName` to a single ABI entry. When the name is overloaded, the\n * overload is chosen by argument count: `args` leaves out the batch signature slot, so\n * an overload with `external*` inputs takes one ABI parameter more than it gets args.\n * Overloads with `external*` inputs win, since these helpers only run for calls that\n * are being encrypted. Solidity tooling sorts overloads by selector, so the first\n * entry by name is often the plaintext one.\n */\nfunction getInputFunction(abi: readonly unknown[], functionName: string, args: readonly unknown[]) {\n const overloads = abi.filter((item): item is AbiFunction => isAbiFunction(item) && item.name === functionName);\n if (overloads.length <= 1) return overloads[0];\n\n const hasExternalInputs = (fn: AbiFunction) => fn.inputs.some((input) => paramHasExternalInput(input));\n const byArity = overloads.filter((fn) => fn.inputs.length - (hasExternalInputs(fn) ? 1 : 0) === args.length);\n const encrypted = byArity.filter(hasExternalInputs);\n const candidates = encrypted.length > 0 ? encrypted : byArity;\n\n if (candidates.length !== 1) {\n throw new Error(\n `Function ${functionName} is overloaded and ${args.length} argument(s) do not select a single overload`\n );\n }\n return candidates[0];\n}\n\nfunction paramHasExternalInput(param: AbiParameter): boolean {\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;\n if ('components' in param && Array.isArray(param.components)) {\n return param.components.some((component) => paramHasExternalInput(component));\n }\n return false;\n}\n\nfunction transformSingleExternalToEncryptable(internalType: ExternalInputInternalType, data: unknown): EncryptableItem {\n switch (internalType) {\n case 'externalEbool':\n return Encryptable.bool(data as boolean);\n case 'externalEuint8':\n return Encryptable.uint8(data as string | bigint);\n case 'externalEuint16':\n return Encryptable.uint16(data as string | bigint);\n case 'externalEuint32':\n return Encryptable.uint32(data as string | bigint);\n case 'externalEuint64':\n return Encryptable.uint64(data as string | bigint);\n case 'externalEuint128':\n return Encryptable.uint128(data as string | bigint);\n case 'externalEaddress':\n return Encryptable.address(data as string | bigint);\n default:\n throw new Error(`Unknown external input type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfExternalsToEncryptables(\n internalType: ExternalInputInternalType,\n size: string | undefined,\n data: unknown\n): EncryptableItem[] {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n return data.map((item) => transformSingleExternalToEncryptable(internalType, item));\n}\n\n/**\n * Extracts encryptable values from function arguments based on the ABI.\n * Transforms raw data values into EncryptableItem objects that can be passed to the encrypt function.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;\n * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)\n * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order\n */\nexport function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>\n): EncryptableItem[] {\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const abiFunction = getInputFunction(abi, functionName, args);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n // Collect encrypted values as EncryptableItem objects in order (flat array)\n const encryptableItems: EncryptableItem[] = [];\n\n function processParameter(param: AbiParameter, value: unknown): void {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Bare external input (e.g. `externalEuint32`, type: 'bytes32')\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n encryptableItems.push(transformSingleExternalToEncryptable(internalTypeHead, value));\n return;\n }\n\n // Array of external inputs (e.g. `externalEuint32[]`/`externalEuint32[2]`, type: 'bytes32[]'/'bytes32[2]')\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const encryptables = transformArrayOfExternalsToEncryptables(internalTypeHead, typeSize, value);\n encryptableItems.push(...encryptables);\n return;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): void => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n components.forEach((component) => {\n processParameter(component, valueObj[component.name]);\n });\n return;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n components.forEach((component, index) => {\n processParameter(component, tupleValue[index]);\n });\n };\n\n // `tuple[]` / `tuple[N]`: walk each element as its own tuple. Treating the array\n // itself as one tuple would look up named components on the array object, find\n // none, and hand `undefined` to the encryptable transform.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n value.forEach(processTuple);\n return;\n }\n\n processTuple(value);\n }\n return;\n }\n\n // Not an external input, and cannot contain one\n return;\n }\n\n // Process all inputs, skipping the batch-signature slot (nothing to extract there). `args` is the\n // pre-transform tuple, which omits that slot, so its indices lag by one past the signature.\n let argIndex = 0;\n inputs.forEach((input, index) => {\n if (index === signatureSlotIndex) return;\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n processParameter(input, arg);\n });\n\n return encryptableItems;\n}\n\n/**\n * Index of the shared batch-signature parameter: the plain `bytes` immediately after the\n * contiguous run of `external*` parameters. Returns -1 when the function has no encrypted inputs.\n *\n * The proof pairs with the hashes it authenticates (`FHE.asEuintXX(hash, proof)`), so it does not\n * have to be the last parameter - anything may follow it.\n */\nfunction findSignatureSlotIndex(\n inputs: readonly AbiParameter[],\n hasExternalInputs: boolean,\n functionName: string\n): number {\n if (!hasExternalInputs) return -1;\n\n const externalIndices = inputs.reduce<number[]>((acc, input, index) => {\n if (paramHasExternalInput(input)) acc.push(index);\n return acc;\n }, []);\n\n const first = externalIndices[0]!;\n const last = externalIndices[externalIndices.length - 1]!;\n if (last - first + 1 !== externalIndices.length) {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs at non-adjacent positions ` +\n `(${externalIndices.join(', ')}). They share one batch signature, so they must be contiguous ` +\n `with the 'bytes' signature parameter immediately after them`\n );\n }\n\n const slotIndex = last + 1;\n const slot = inputs[slotIndex];\n if (slot?.type !== 'bytes') {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs, so the parameter immediately after ` +\n `them must be a plain 'bytes' parameter to receive the shared batch signature - found ` +\n `'${slot?.type ?? 'nothing'}' at position ${slotIndex} instead`\n );\n }\n\n return slotIndex;\n}\n\n/**\n * Re-inserts encrypted values back into function arguments based on the ABI.\n * Takes the batch-verified result (per-input hashes, in order, followed by the single shared\n * signature) and the original args structure, and produces the final call args: each `external*`\n * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.\n *\n * This function mirrors the extraction logic in extractEncryptableValues, ensuring values\n * are inserted in the exact same order and locations where they were extracted.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Original function arguments in the format of CofheInputArgsPreTransform\n * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`\n * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)\n */\nexport function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>,\n encryptedResult: readonly `0x${string}`[]\n): CofheInputArgs<TAbi, TFunctionName> {\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const abiFunction = getInputFunction(abi, functionName, args);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];\n const signature = hasExternalInputs ? encryptedResult[encryptedResult.length - 1] : undefined;\n\n // Track position in the hashes array\n let hashIndex = 0;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n\n // Bare external input - substitute its hash\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n if (hashIndex >= hashes.length) {\n throw new Error(`Not enough encrypted hashes: expected at least ${hashIndex + 1}, got ${hashes.length}`);\n }\n const hash = hashes[hashIndex];\n hashIndex++;\n return hash;\n }\n\n // Array of external inputs - substitute the corresponding slice of hashes\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const arrayLength = Array.isArray(value) ? value.length : 0;\n if (arrayLength === 0) {\n return [];\n }\n\n if (hashIndex + arrayLength > hashes.length) {\n throw new Error(\n `Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`\n );\n }\n\n const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);\n hashIndex += arrayLength;\n return hashArray;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: rebuild each element as its own tuple, in the same order\n // extractEncryptableValues walked them, so the hashes line up. Treating the array as\n // one tuple would consume no hashes and collapse the argument to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n return value;\n }\n\n // Not an external input, return original value\n return value;\n }\n\n // Rebuild the full arg list; the signature slot is injected directly. `args` omits that slot, so\n // its indices lag by one past the signature position.\n let argIndex = 0;\n const result = inputs.map((input, index) => {\n if (index === signatureSlotIndex) {\n return signature;\n }\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n return processParameter(input, arg);\n });\n\n // Verify we used all encrypted hashes\n if (hashIndex !== hashes.length) {\n throw new Error(`Mismatch in encrypted hashes count: used ${hashIndex}, but provided ${hashes.length}`);\n }\n\n return result as CofheInputArgs<TAbi, TFunctionName>;\n}\n","import type {\n Abi,\n AbiConstructor,\n AbiError,\n AbiEvent,\n AbiFallback,\n AbiFunction,\n AbiParameter,\n AbiParametersToPrimitiveTypes,\n AbiReceive,\n AbiType,\n Address,\n ExtractAbiFunction,\n ResolvedRegister,\n SolidityArray,\n SolidityFixedArrayRange,\n SolidityTuple,\n} from 'abitype';\n\nexport type ContractReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends AbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = AbiParametersToPrimitiveTypes<outputs, 'outputs', true>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\nexport type Error<messages extends string | string[]> = messages extends string\n ? [\n // Surrounding with array to prevent `messages` from being widened to `string`\n `Error: ${messages}`,\n ]\n : {\n [key in keyof messages]: messages[key] extends infer message extends string ? `Error: ${message}` : never;\n };\n\ntype PartialBy<TType, TKeys extends keyof TType> = ExactPartial<Pick<TType, TKeys>> & Omit<TType, TKeys>;\ntype ExactPartial<T> = { [K in keyof T]?: T[K] | undefined };\n\nexport type MaybePartialBy<TType, TKeys extends string> = TKeys extends keyof TType ? PartialBy<TType, TKeys> : TType;\n\nexport type ReadonlyWiden<TType> =\n | (TType extends Function ? TType : never)\n | (TType extends ResolvedRegister['bigIntType'] ? bigint : never)\n | (TType extends boolean ? boolean : never)\n | (TType extends ResolvedRegister['intType'] ? number : never)\n | (TType extends string\n ? TType extends Address\n ? Address\n : TType extends ResolvedRegister['bytesType']['inputs']\n ? ResolvedRegister['bytesType']\n : string\n : never)\n | (TType extends readonly [] ? readonly [] : never)\n | (TType extends Record<string, unknown> ? { [K in keyof TType]: ReadonlyWiden<TType[K]> } : never)\n | (TType extends { length: number }\n ? {\n [K in keyof TType]: ReadonlyWiden<TType[K]>;\n } extends infer Val extends unknown[]\n ? readonly [...Val]\n : never\n : never);\n\nexport type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>;\n\n/**\n * First, infer `Head` against a known size type (either fixed-length array value or `\"\"`).\n *\n * | Input | Head |\n * | --------------- | ------------ |\n * | `string[]` | `string` |\n * | `string[][][3]` | `string[][]` |\n */\nexport type MaybeExtractArrayParameterType<type> = type extends `${infer head}[${'' | `${SolidityFixedArrayRange}`}]`\n ? // * Then, infer in the opposite direction, using the known `head` to infer the exact `size` value.\n // *\n // * | Input | Size |\n // * | ------------ | ---- |\n // * | `${head}[]` | `\"\"` |\n // * | `${head}[3]` | `3` |\n // */\n type extends `${head}[${infer size}]`\n ? [head, size]\n : undefined\n : undefined;\n\nexport type IsUnion<T, C = T> = T extends C ? ([C] extends [T] ? false : true) : never;\nexport type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]\n ? []\n : [...UnionToTuple<Exclude<U, Last>>, Last];\ntype LastInUnion<U> =\n UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;\ntype UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;\n\n/**\n * Create tuple of {@link type} type with {@link size} size\n *\n * @param Type - Type of tuple\n * @param Size - Size of tuple\n * @returns Tuple of {@link type} type with {@link size} size\n *\n * @example\n * type Result = Tuple<string, 2>\n * // ^? type Result = [string, string]\n */\n// https://github.com/Microsoft/TypeScript/issues/26223#issuecomment-674500430\nexport type Tuple<type, size extends number> = size extends size\n ? number extends size\n ? type[]\n : _TupleOf<type, size, []>\n : never;\ntype _TupleOf<length, size extends number, acc extends readonly unknown[]> = acc['length'] extends size\n ? acc\n : _TupleOf<length, size, readonly [length, ...acc]>;\n\n/**\n * Merges two object types into new type\n *\n * @param object1 - Object to merge into\n * @param object2 - Object to merge and override keys from {@link object1}\n * @returns New object type with keys from {@link object1} and {@link object2}. If a key exists in both {@link object1} and {@link object2}, the key from {@link object2} will be used.\n *\n * @example\n * type Result = Merge<{ foo: string }, { foo: number; bar: string }>\n * // ^? type Result = { foo: number; bar: string }\n */\nexport type Merge<object1, object2> = Omit<object1, keyof object2> & object2;\n\n// FUNCTIONS\n\n/**\n * Extracts array parameter type information from a type string.\n * Always returns a tuple, with undefined for non-array types.\n *\n * @param type - Type string like \"tuple\", \"tuple[]\", or \"tuple[2]\"\n * @returns [head, size] where:\n * - head is the base type\n * - size is undefined for non-arrays, \"\" for dynamic arrays, or the number as a string for fixed arrays\n *\n * @example\n * extractArrayParameterType(\"tuple\") // [\"tuple\", undefined]\n * extractArrayParameterType(\"tuple[]\") // [\"tuple\", \"\"]\n * extractArrayParameterType(\"tuple[2]\") // [\"tuple\", \"2\"]\n */\nexport function extractArrayParameterType<T extends string | undefined>(type: T): [T, string | undefined] {\n if (type == null) return [type, undefined];\n\n const match = type.match(/^(.+)\\[(\\d*)\\]$/);\n\n if (!match) {\n // Not an array type, return [type, undefined]\n return [type, undefined];\n }\n\n const head = match[1];\n const size = match[2]; // Empty string for dynamic arrays, or digits for fixed arrays\n\n // Return empty string for dynamic arrays, or the size string for fixed arrays\n return [head as T, size === '' ? '' : size];\n}\n\n/**\n * Matches the tuple-shape rule used by `CofheAbiComponentsToPrimitiveType`:\n * tuples are objects only when every component has a name. Otherwise they are\n * represented positionally as arrays.\n */\nexport function tupleComponentsAreNamed(components: readonly AbiParameter[]): boolean {\n return components.length > 0 && components.every((component) => component.name != null && component.name !== '');\n}\n\ntype AbiItem = AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive;\n\nexport function isAbiFunction(item: AbiItem | unknown): item is AbiFunction {\n if (typeof item !== 'object' || item === null) return false;\n return 'type' in item && item.type === 'function' && 'name' in item && 'outputs' in item;\n}\n\nexport function getAbiFunction<TAbi extends Abi | readonly unknown[], TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName\n): AbiFunction | undefined {\n return abi.find((item) => {\n const isFunction = isAbiFunction(item);\n if (!isFunction) return false;\n return item.name === functionName;\n }) as AbiFunction | undefined;\n}\n","import { type Primitive, type LiteralToPrimitive, FheTypes } from '@cofhe/sdk';\nimport type { Abi, AbiFunction, ExtractAbiFunction, AbiParameter } from 'abitype';\nimport type {\n EncryptedReturnType,\n CofheAbiParametersToPrimitiveTypes,\n EBool,\n EAddress,\n EUint128,\n EUint16,\n EUint32,\n EUint64,\n EUint8,\n} from './fhenixMap';\nimport {\n getAbiFunction,\n type IsUnion,\n type UnionToTuple,\n type ContractReturnType,\n extractArrayParameterType,\n tupleComponentsAreNamed,\n} from './utils';\n\ntype FirstCofheReturnValue<T> = [T] extends [void]\n ? never\n : T extends readonly [infer Head, ...(readonly unknown[])]\n ? Head\n : T;\n\ntype FheTypeFromCofheReturnValue<T> = T extends { utype: infer U }\n ? U\n : T extends readonly (infer Element)[]\n ? FheTypeFromCofheReturnValue<Element>\n : never;\n\n/**\n * Extracts the `FheTypes` of the first returned value of a CoFHE call.\n *\n * Examples:\n * - `returns (ebool)` -> `FheTypes.Bool`\n * - `returns (euint8, euint64)` -> `FheTypes.Uint8`\n * - `returns (euint16[])` -> `FheTypes.Uint16`\n */\nexport type CofheFirstReturnFheType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = FheTypeFromCofheReturnValue<FirstCofheReturnValue<CofheReturnType<abi, functionName, args>>>;\n\nexport type CofheReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends CofheAbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = CofheAbiParametersToPrimitiveTypes<outputs, 'outputs'>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\ntype EncryptedReturnTypeToReturnTypeMap<E extends EncryptedReturnType> = E extends EBool\n ? boolean\n : E extends EUint8\n ? bigint\n : E extends EUint16\n ? bigint\n : E extends EUint32\n ? bigint\n : E extends EUint64\n ? bigint\n : E extends EUint128\n ? bigint\n : E extends EAddress\n ? string\n : never;\n\ntype EncryptedReturnTypesToReturnTypes<T> = T extends Primitive\n ? LiteralToPrimitive<T>\n : T extends EncryptedReturnType\n ? EncryptedReturnTypeToReturnTypeMap<T>\n : {\n [K in keyof T]: EncryptedReturnTypesToReturnTypes<T[K]>;\n };\n\nexport type CofheReturnTypePostTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = EncryptedReturnTypesToReturnTypes<CofheReturnType<abi, functionName, args>>;\n\nconst ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES = [\n 'ebool',\n 'euint8',\n 'euint16',\n 'euint32',\n 'euint64',\n 'euint128',\n 'eaddress',\n] as const;\ntype EncryptedReturnTypeInternalType = (typeof ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES)[number];\n\ntype EncryptedReturnTypeInternalTypeToReturnTypeMap<T extends EncryptedReturnTypeInternalType> = T extends 'ebool'\n ? EBool\n : T extends 'euint8'\n ? EUint8\n : T extends 'euint16'\n ? EUint16\n : T extends 'euint32'\n ? EUint32\n : T extends 'euint64'\n ? EUint64\n : T extends 'euint128'\n ? EUint128\n : T extends 'eaddress'\n ? EAddress\n : never;\n\nfunction transformSingleEncryptedReturnTypeToReturnType<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n data: string\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T> {\n switch (internalType) {\n case 'ebool':\n return {\n ctHash: data,\n utype: FheTypes.Bool,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint8':\n return {\n ctHash: data,\n utype: FheTypes.Uint8,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint16':\n return {\n ctHash: data,\n utype: FheTypes.Uint16,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint32':\n return {\n ctHash: data,\n utype: FheTypes.Uint32,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint64':\n return {\n ctHash: data,\n utype: FheTypes.Uint64,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint128':\n return {\n ctHash: data,\n utype: FheTypes.Uint128,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'eaddress':\n return {\n ctHash: data,\n utype: FheTypes.Uint160,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n default:\n throw new Error(`Unknown encrypted return type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfEncryptedReturnTypesToReturnTypes<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n size: string | undefined,\n data: string[]\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T>[] {\n // Ensure data is an array\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n // Ensure length of fixed length tuple matches the length of the data array\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n // Transform each item in the data array into an return type\n return data.map((item) => transformSingleEncryptedReturnTypeToReturnType(internalType, item));\n}\n\nfunction internalTypeIsEncryptedReturnType(internalType: string): internalType is EncryptedReturnTypeInternalType {\n return ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES.includes(internalType as any);\n}\n\nexport function transformEncryptedReturnTypes<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n data: ContractReturnType<TAbi, TFunctionName>\n): CofheReturnType<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const outputs = abiFunction?.outputs;\n if (abiFunction == null || outputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n const outputsLength = outputs.length;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Is encrypted return type\n if (internalTypeHead != null && internalTypeIsEncryptedReturnType(internalTypeHead)) {\n // Is single encrypted return type\n if (internalTypeSize == null) {\n return transformSingleEncryptedReturnTypeToReturnType(internalTypeHead, value as string);\n }\n\n // Is array of encrypted return types\n if (internalTypeSize != null) {\n return transformArrayOfEncryptedReturnTypesToReturnTypes(internalTypeHead, internalTypeSize, value as string[]);\n }\n }\n\n // Tuple but not an encrypted return type (recursive case)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: transform each element as its own tuple. Treating the\n // array itself as one tuple would look up named components on the array object,\n // find none, and collapse the whole result to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n\n return value;\n }\n\n // Not an encrypted return type, return original value\n return value;\n }\n\n // Process results (array case)\n if (outputsLength > 1) {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n if (outputsLength !== data.length) {\n throw new Error(`Mismatch in outputs length: ${outputsLength} !== ${data.length}`);\n }\n return data.map((item, index) => {\n return processParameter(outputs[index], item);\n }) as CofheReturnType<TAbi, TFunctionName>;\n }\n\n // Process retuls (single item case)\n return processParameter(outputs[0], data) as CofheReturnType<TAbi, TFunctionName>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAoBO;;;ACuJA,SAAS,0BAAwD,MAAkC;AACxG,MAAI,QAAQ,KAAM,QAAO,CAAC,MAAM,MAAS;AAEzC,QAAM,QAAQ,KAAK,MAAM,iBAAiB;AAE1C,MAAI,CAAC,OAAO;AAEV,WAAO,CAAC,MAAM,MAAS;AAAA,EACzB;AAEA,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,OAAO,MAAM,CAAC;AAGpB,SAAO,CAAC,MAAW,SAAS,KAAK,KAAK,IAAI;AAC5C;AAOO,SAAS,wBAAwB,YAA8C;AACpF,SAAO,WAAW,SAAS,KAAK,WAAW,MAAM,CAAC,cAAc,UAAU,QAAQ,QAAQ,UAAU,SAAS,EAAE;AACjH;AAIO,SAAS,cAAc,MAA8C;AAC1E,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,SAAO,UAAU,QAAQ,KAAK,SAAS,cAAc,UAAU,QAAQ,aAAa;AACtF;AAEO,SAAS,eACd,KACA,cACyB;AACzB,SAAO,IAAI,KAAK,CAAC,SAAS;AACxB,UAAM,aAAa,cAAc,IAAI;AACrC,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,KAAK,SAAS;AAAA,EACvB,CAAC;AACH;;;ADxHA,IAAM,gCAAgC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsEA,SAAS,4BAA4B,cAAiE;AACpG,SAAO,8BAA8B,SAAS,YAAmB;AACnE;AAUA,SAAS,iBAAiB,KAAyB,cAAsB,MAA0B;AACjG,QAAM,YAAY,IAAI,OAAO,CAAC,SAA8B,cAAc,IAAI,KAAK,KAAK,SAAS,YAAY;AAC7G,MAAI,UAAU,UAAU,EAAG,QAAO,UAAU,CAAC;AAE7C,QAAM,oBAAoB,CAAC,OAAoB,GAAG,OAAO,KAAK,CAAC,UAAU,sBAAsB,KAAK,CAAC;AACrG,QAAM,UAAU,UAAU,OAAO,CAAC,OAAO,GAAG,OAAO,UAAU,kBAAkB,EAAE,IAAI,IAAI,OAAO,KAAK,MAAM;AAC3G,QAAM,YAAY,QAAQ,OAAO,iBAAiB;AAClD,QAAM,aAAa,UAAU,SAAS,IAAI,YAAY;AAEtD,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,YAAY,YAAY,sBAAsB,KAAK,MAAM;AAAA,IAC3D;AAAA,EACF;AACA,SAAO,WAAW,CAAC;AACrB;AAEA,SAAS,sBAAsB,OAA8B;AAC3D,QAAM,CAAC,gBAAgB,IAAI,0BAA0B,MAAM,YAAY;AACvE,MAAI,oBAAoB,QAAQ,4BAA4B,gBAAgB,EAAG,QAAO;AACtF,MAAI,gBAAgB,SAAS,MAAM,QAAQ,MAAM,UAAU,GAAG;AAC5D,WAAO,MAAM,WAAW,KAAK,CAAC,cAAc,sBAAsB,SAAS,CAAC;AAAA,EAC9E;AACA,SAAO;AACT;AAEA,SAAS,qCAAqC,cAAyC,MAAgC;AACrH,UAAQ,cAAc;AAAA,IACpB,KAAK;AACH,aAAO,uBAAY,KAAK,IAAe;AAAA,IACzC,KAAK;AACH,aAAO,uBAAY,MAAM,IAAuB;AAAA,IAClD,KAAK;AACH,aAAO,uBAAY,OAAO,IAAuB;AAAA,IACnD,KAAK;AACH,aAAO,uBAAY,OAAO,IAAuB;AAAA,IACnD,KAAK;AACH,aAAO,uBAAY,OAAO,IAAuB;AAAA,IACnD,KAAK;AACH,aAAO,uBAAY,QAAQ,IAAuB;AAAA,IACpD,KAAK;AACH,aAAO,uBAAY,QAAQ,IAAuB;AAAA,IACpD;AACE,YAAM,IAAI,MAAM,gCAAgC,YAAY,EAAE;AAAA,EAClE;AACF;AAEA,SAAS,wCACP,cACA,MACA,MACmB;AACnB,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,MAAI,QAAQ,QAAQ,SAAS,MAAM,SAAS,IAAI,MAAM,KAAK,QAAQ;AACjE,UAAM,IAAI,MAAM,wBAAwB,IAAI,QAAQ,KAAK,MAAM,EAAE;AAAA,EACnE;AAEA,SAAO,KAAK,IAAI,CAAC,SAAS,qCAAqC,cAAc,IAAI,CAAC;AACpF;AAYO,SAAS,yBACd,KACA,cACA,MACmB;AACnB,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,cAAc,iBAAiB,KAAK,cAAc,IAAI;AAC5D,QAAM,SAAS,aAAa;AAC5B,MAAI,eAAe,QAAQ,UAAU,MAAM;AACzC,UAAM,IAAI,MAAM,YAAY,YAAY,mBAAmB;AAAA,EAC7D;AAEA,QAAM,oBAAoB,OAAO,KAAK,CAAC,UAAU,sBAAsB,KAAK,CAAC;AAC7E,QAAM,qBAAqB,uBAAuB,QAAQ,mBAAmB,YAAY;AAGzF,QAAM,mBAAsC,CAAC;AAE7C,WAAS,iBAAiB,OAAqB,OAAsB;AACnE,UAAM,CAAC,UAAU,QAAQ,IAAI,0BAA0B,MAAM,IAAI;AACjE,UAAM,CAAC,kBAAkB,gBAAgB,IAAI,0BAA0B,MAAM,YAAY;AAGzF,QAAI,YAAY,QAAQ,oBAAoB,QAAQ,4BAA4B,gBAAgB,GAAG;AACjG,uBAAiB,KAAK,qCAAqC,kBAAkB,KAAK,CAAC;AACnF;AAAA,IACF;AAGA,QAAI,YAAY,QAAQ,oBAAoB,QAAQ,4BAA4B,gBAAgB,GAAG;AACjG,YAAM,eAAe,wCAAwC,kBAAkB,UAAU,KAAK;AAC9F,uBAAiB,KAAK,GAAG,YAAY;AACrC;AAAA,IACF;AAGA,QAAI,aAAa,SAAS;AACxB,UAAI,gBAAgB,SAAS,MAAM,QAAQ,MAAM,UAAU,GAAG;AAC5D,cAAM,aAAa,MAAM;AAEzB,cAAM,eAAe,CAAC,eAA8B;AAClD,cAAI,wBAAwB,UAAU,GAAG;AACvC,kBAAM,WAAW;AACjB,uBAAW,QAAQ,CAAC,cAAc;AAChC,+BAAiB,WAAW,SAAS,UAAU,IAAI,CAAC;AAAA,YACtD,CAAC;AACD;AAAA,UACF;AAEA,cAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC9B,kBAAM,IAAI,MAAM,2DAA2D;AAAA,UAC7E;AAEA,qBAAW,QAAQ,CAAC,WAAW,UAAU;AACvC,6BAAiB,WAAW,WAAW,KAAK,CAAC;AAAA,UAC/C,CAAC;AAAA,QACH;AAKA,YAAI,YAAY,MAAM;AACpB,cAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,kBAAM,IAAI,MAAM,+BAA+B,MAAM,IAAI,EAAE;AAAA,UAC7D;AACA,cAAI,aAAa,MAAM,SAAS,QAAQ,MAAM,MAAM,QAAQ;AAC1D,kBAAM,IAAI,MAAM,wBAAwB,QAAQ,QAAQ,MAAM,MAAM,EAAE;AAAA,UACxE;AACA,gBAAM,QAAQ,YAAY;AAC1B;AAAA,QACF;AAEA,qBAAa,KAAK;AAAA,MACpB;AACA;AAAA,IACF;AAGA;AAAA,EACF;AAIA,MAAI,WAAW;AACf,SAAO,QAAQ,CAAC,OAAO,UAAU;AAC/B,QAAI,UAAU,mBAAoB;AAClC,UAAM,MAAM,KAAK,QAAQ;AACzB,QAAI,OAAO,MAAM;AACf,YAAM,IAAI,MAAM,YAAY,QAAQ,eAAe;AAAA,IACrD;AACA;AACA,qBAAiB,OAAO,GAAG;AAAA,EAC7B,CAAC;AAED,SAAO;AACT;AASA,SAAS,uBACP,QACA,mBACA,cACQ;AACR,MAAI,CAAC,kBAAmB,QAAO;AAE/B,QAAM,kBAAkB,OAAO,OAAiB,CAAC,KAAK,OAAO,UAAU;AACrE,QAAI,sBAAsB,KAAK,EAAG,KAAI,KAAK,KAAK;AAChD,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,gBAAgB,CAAC;AAC/B,QAAM,OAAO,gBAAgB,gBAAgB,SAAS,CAAC;AACvD,MAAI,OAAO,QAAQ,MAAM,gBAAgB,QAAQ;AAC/C,UAAM,IAAI;AAAA,MACR,YAAY,YAAY,gEAClB,gBAAgB,KAAK,IAAI,CAAC;AAAA,IAElC;AAAA,EACF;AAEA,QAAM,YAAY,OAAO;AACzB,QAAM,OAAO,OAAO,SAAS;AAC7B,MAAI,MAAM,SAAS,SAAS;AAC1B,UAAM,IAAI;AAAA,MACR,YAAY,YAAY,+JAElB,MAAM,QAAQ,SAAS,iBAAiB,SAAS;AAAA,IACzD;AAAA,EACF;AAEA,SAAO;AACT;AAiBO,SAAS,sBACd,KACA,cACA,MACA,iBACqC;AACrC,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,cAAc,iBAAiB,KAAK,cAAc,IAAI;AAC5D,QAAM,SAAS,aAAa;AAC5B,MAAI,eAAe,QAAQ,UAAU,MAAM;AACzC,UAAM,IAAI,MAAM,YAAY,YAAY,mBAAmB;AAAA,EAC7D;AAEA,QAAM,oBAAoB,OAAO,KAAK,CAAC,UAAU,sBAAsB,KAAK,CAAC;AAC7E,QAAM,qBAAqB,uBAAuB,QAAQ,mBAAmB,YAAY;AAEzF,QAAM,SAAS,oBAAoB,gBAAgB,MAAM,GAAG,EAAE,IAAI,CAAC;AACnE,QAAM,YAAY,oBAAoB,gBAAgB,gBAAgB,SAAS,CAAC,IAAI;AAGpF,MAAI,YAAY;AAEhB,WAAS,iBAAiB,OAAqB,OAAyB;AACtE,UAAM,CAAC,UAAU,QAAQ,IAAI,0BAA0B,MAAM,IAAI;AACjE,UAAM,CAAC,gBAAgB,IAAI,0BAA0B,MAAM,YAAY;AAGvE,QAAI,YAAY,QAAQ,oBAAoB,QAAQ,4BAA4B,gBAAgB,GAAG;AACjG,UAAI,aAAa,OAAO,QAAQ;AAC9B,cAAM,IAAI,MAAM,kDAAkD,YAAY,CAAC,SAAS,OAAO,MAAM,EAAE;AAAA,MACzG;AACA,YAAM,OAAO,OAAO,SAAS;AAC7B;AACA,aAAO;AAAA,IACT;AAGA,QAAI,YAAY,QAAQ,oBAAoB,QAAQ,4BAA4B,gBAAgB,GAAG;AACjG,YAAM,cAAc,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS;AAC1D,UAAI,gBAAgB,GAAG;AACrB,eAAO,CAAC;AAAA,MACV;AAEA,UAAI,YAAY,cAAc,OAAO,QAAQ;AAC3C,cAAM,IAAI;AAAA,UACR,kDAAkD,YAAY,WAAW,SAAS,OAAO,MAAM;AAAA,QACjG;AAAA,MACF;AAEA,YAAM,YAAY,OAAO,MAAM,WAAW,YAAY,WAAW;AACjE,mBAAa;AACb,aAAO;AAAA,IACT;AAGA,QAAI,aAAa,SAAS;AACxB,UAAI,gBAAgB,SAAS,MAAM,QAAQ,MAAM,UAAU,GAAG;AAC5D,cAAM,aAAa,MAAM;AAEzB,cAAM,eAAe,CAAC,eAAiC;AACrD,cAAI,wBAAwB,UAAU,GAAG;AACvC,kBAAM,WAAW;AACjB,kBAAMA,UAAkC,CAAC;AAEzC,uBAAW,QAAQ,CAAC,cAAc;AAChC,oBAAM,gBAAgB,UAAU;AAChC,kBAAI,eAAe;AACjB,sBAAM,iBAAiB,SAAS,aAAa;AAC7C,oBAAI,mBAAmB,QAAW;AAChC,kBAAAA,QAAO,aAAa,IAAI,iBAAiB,WAAW,cAAc;AAAA,gBACpE;AAAA,cACF;AAAA,YACF,CAAC;AAED,mBAAOA;AAAA,UACT;AAEA,cAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC9B,kBAAM,IAAI,MAAM,2DAA2D;AAAA,UAC7E;AAEA,iBAAO,WAAW,IAAI,CAAC,WAAW,UAAU,iBAAiB,WAAW,WAAW,KAAK,CAAC,CAAC;AAAA,QAC5F;AAKA,YAAI,YAAY,MAAM;AACpB,cAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,kBAAM,IAAI,MAAM,+BAA+B,MAAM,IAAI,EAAE;AAAA,UAC7D;AACA,cAAI,aAAa,MAAM,SAAS,QAAQ,MAAM,MAAM,QAAQ;AAC1D,kBAAM,IAAI,MAAM,wBAAwB,QAAQ,QAAQ,MAAM,MAAM,EAAE;AAAA,UACxE;AACA,iBAAO,MAAM,IAAI,YAAY;AAAA,QAC/B;AAEA,eAAO,aAAa,KAAK;AAAA,MAC3B;AACA,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT;AAIA,MAAI,WAAW;AACf,QAAM,SAAS,OAAO,IAAI,CAAC,OAAO,UAAU;AAC1C,QAAI,UAAU,oBAAoB;AAChC,aAAO;AAAA,IACT;AACA,UAAM,MAAM,KAAK,QAAQ;AACzB,QAAI,OAAO,MAAM;AACf,YAAM,IAAI,MAAM,YAAY,QAAQ,eAAe;AAAA,IACrD;AACA;AACA,WAAO,iBAAiB,OAAO,GAAG;AAAA,EACpC,CAAC;AAGD,MAAI,cAAc,OAAO,QAAQ;AAC/B,UAAM,IAAI,MAAM,4CAA4C,SAAS,kBAAkB,OAAO,MAAM,EAAE;AAAA,EACxG;AAEA,SAAO;AACT;;;AE/hBA,IAAAC,cAAkE;AAiHlE,IAAM,uCAAuC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAmBA,SAAS,+CACP,cACA,MACmD;AACnD,UAAQ,cAAc;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,qBAAS;AAAA,MAClB;AAAA,IACF;AACE,YAAM,IAAI,MAAM,kCAAkC,YAAY,EAAE;AAAA,EACpE;AACF;AAEA,SAAS,kDACP,cACA,MACA,MACqD;AAErD,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAGA,MAAI,QAAQ,QAAQ,SAAS,MAAM,SAAS,IAAI,MAAM,KAAK,QAAQ;AACjE,UAAM,IAAI,MAAM,wBAAwB,IAAI,QAAQ,KAAK,MAAM,EAAE;AAAA,EACnE;AAGA,SAAO,KAAK,IAAI,CAAC,SAAS,+CAA+C,cAAc,IAAI,CAAC;AAC9F;AAEA,SAAS,kCAAkC,cAAuE;AAChH,SAAO,qCAAqC,SAAS,YAAmB;AAC1E;AAEO,SAAS,8BACd,KACA,cACA,MACsC;AACtC,QAAM,cAAc,eAAe,KAAK,YAAY;AACpD,QAAM,UAAU,aAAa;AAC7B,MAAI,eAAe,QAAQ,WAAW,MAAM;AAC1C,UAAM,IAAI,MAAM,YAAY,YAAY,mBAAmB;AAAA,EAC7D;AACA,QAAM,gBAAgB,QAAQ;AAE9B,WAAS,iBAAiB,OAAqB,OAAyB;AACtE,UAAM,CAAC,UAAU,QAAQ,IAAI,0BAA0B,MAAM,IAAI;AACjE,UAAM,CAAC,kBAAkB,gBAAgB,IAAI,0BAA0B,MAAM,YAAY;AAGzF,QAAI,oBAAoB,QAAQ,kCAAkC,gBAAgB,GAAG;AAEnF,UAAI,oBAAoB,MAAM;AAC5B,eAAO,+CAA+C,kBAAkB,KAAe;AAAA,MACzF;AAGA,UAAI,oBAAoB,MAAM;AAC5B,eAAO,kDAAkD,kBAAkB,kBAAkB,KAAiB;AAAA,MAChH;AAAA,IACF;AAGA,QAAI,aAAa,SAAS;AACxB,UAAI,gBAAgB,SAAS,MAAM,QAAQ,MAAM,UAAU,GAAG;AAC5D,cAAM,aAAa,MAAM;AAEzB,cAAM,eAAe,CAAC,eAAiC;AACrD,cAAI,wBAAwB,UAAU,GAAG;AACvC,kBAAM,WAAW;AACjB,kBAAM,SAAkC,CAAC;AAEzC,uBAAW,QAAQ,CAAC,cAAc;AAChC,oBAAM,gBAAgB,UAAU;AAChC,kBAAI,eAAe;AACjB,sBAAM,iBAAiB,SAAS,aAAa;AAC7C,oBAAI,mBAAmB,QAAW;AAChC,yBAAO,aAAa,IAAI,iBAAiB,WAAW,cAAc;AAAA,gBACpE;AAAA,cACF;AAAA,YACF,CAAC;AAED,mBAAO;AAAA,UACT;AAEA,cAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC9B,kBAAM,IAAI,MAAM,2DAA2D;AAAA,UAC7E;AAEA,iBAAO,WAAW,IAAI,CAAC,WAAW,UAAU,iBAAiB,WAAW,WAAW,KAAK,CAAC,CAAC;AAAA,QAC5F;AAKA,YAAI,YAAY,MAAM;AACpB,cAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,kBAAM,IAAI,MAAM,+BAA+B,MAAM,IAAI,EAAE;AAAA,UAC7D;AACA,cAAI,aAAa,MAAM,SAAS,QAAQ,MAAM,MAAM,QAAQ;AAC1D,kBAAM,IAAI,MAAM,wBAAwB,QAAQ,QAAQ,MAAM,MAAM,EAAE;AAAA,UACxE;AACA,iBAAO,MAAM,IAAI,YAAY;AAAA,QAC/B;AAEA,eAAO,aAAa,KAAK;AAAA,MAC3B;AAEA,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT;AAGA,MAAI,gBAAgB,GAAG;AACrB,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AACA,QAAI,kBAAkB,KAAK,QAAQ;AACjC,YAAM,IAAI,MAAM,+BAA+B,aAAa,QAAQ,KAAK,MAAM,EAAE;AAAA,IACnF;AACA,WAAO,KAAK,IAAI,CAAC,MAAM,UAAU;AAC/B,aAAO,iBAAiB,QAAQ,KAAK,GAAG,IAAI;AAAA,IAC9C,CAAC;AAAA,EACH;AAGA,SAAO,iBAAiB,QAAQ,CAAC,GAAG,IAAI;AAC1C;","names":["result","import_sdk"]}
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,20 @@ var EXTERNAL_INPUT_INTERNAL_TYPES = [
|
|
|
42
42
|
function internalTypeIsExternalInput(internalType) {
|
|
43
43
|
return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType);
|
|
44
44
|
}
|
|
45
|
+
function getInputFunction(abi, functionName, args) {
|
|
46
|
+
const overloads = abi.filter((item) => isAbiFunction(item) && item.name === functionName);
|
|
47
|
+
if (overloads.length <= 1) return overloads[0];
|
|
48
|
+
const hasExternalInputs = (fn) => fn.inputs.some((input) => paramHasExternalInput(input));
|
|
49
|
+
const byArity = overloads.filter((fn) => fn.inputs.length - (hasExternalInputs(fn) ? 1 : 0) === args.length);
|
|
50
|
+
const encrypted = byArity.filter(hasExternalInputs);
|
|
51
|
+
const candidates = encrypted.length > 0 ? encrypted : byArity;
|
|
52
|
+
if (candidates.length !== 1) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Function ${functionName} is overloaded and ${args.length} argument(s) do not select a single overload`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return candidates[0];
|
|
58
|
+
}
|
|
45
59
|
function paramHasExternalInput(param) {
|
|
46
60
|
const [internalTypeHead] = extractArrayParameterType(param.internalType);
|
|
47
61
|
if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;
|
|
@@ -80,14 +94,14 @@ function transformArrayOfExternalsToEncryptables(internalType, size, data) {
|
|
|
80
94
|
return data.map((item) => transformSingleExternalToEncryptable(internalType, item));
|
|
81
95
|
}
|
|
82
96
|
function extractEncryptableValues(abi, functionName, args) {
|
|
83
|
-
|
|
97
|
+
if (!Array.isArray(args)) {
|
|
98
|
+
throw new Error("Arguments must be an array");
|
|
99
|
+
}
|
|
100
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
84
101
|
const inputs = abiFunction?.inputs;
|
|
85
102
|
if (abiFunction == null || inputs == null) {
|
|
86
103
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
87
104
|
}
|
|
88
|
-
if (!Array.isArray(args)) {
|
|
89
|
-
throw new Error("Arguments must be an array");
|
|
90
|
-
}
|
|
91
105
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
92
106
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
93
107
|
const encryptableItems = [];
|
|
@@ -172,14 +186,14 @@ function findSignatureSlotIndex(inputs, hasExternalInputs, functionName) {
|
|
|
172
186
|
return slotIndex;
|
|
173
187
|
}
|
|
174
188
|
function insertEncryptedValues(abi, functionName, args, encryptedResult) {
|
|
175
|
-
|
|
189
|
+
if (!Array.isArray(args)) {
|
|
190
|
+
throw new Error("Arguments must be an array");
|
|
191
|
+
}
|
|
192
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
176
193
|
const inputs = abiFunction?.inputs;
|
|
177
194
|
if (abiFunction == null || inputs == null) {
|
|
178
195
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
179
196
|
}
|
|
180
|
-
if (!Array.isArray(args)) {
|
|
181
|
-
throw new Error("Arguments must be an array");
|
|
182
|
-
}
|
|
183
197
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
184
198
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
185
199
|
const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/encryptedInputs.ts","../src/utils.ts","../src/encryptedReturnTypes.ts"],"sourcesContent":["import {\n Encryptable,\n type AnyExternalHash,\n type EncryptableAddress,\n type EncryptableBool,\n type EncryptableItem,\n type EncryptableUint128,\n type EncryptableUint16,\n type EncryptableUint32,\n type EncryptableUint64,\n type EncryptableUint8,\n type ExternalAddressHash,\n type ExternalBoolHash,\n type ExternalUint128Hash,\n type ExternalUint16Hash,\n type ExternalUint32Hash,\n type ExternalUint64Hash,\n type ExternalUint8Hash,\n type LiteralToPrimitive,\n type Primitive,\n} from '@cofhe/sdk';\nimport type { Abi, AbiFunction, AbiParameter, ExtractAbiFunction } from 'abitype';\nimport type { CofheAbiParametersToPrimitiveTypes } from './fhenixMap';\nimport {\n extractArrayParameterType,\n getAbiFunction,\n type MaybeExtractArrayParameterType,\n type MaybePartialBy,\n type ReadonlyWiden,\n tupleComponentsAreNamed,\n} from './utils';\n\nexport type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<\n abi,\n functionName\n>['args'];\n\ntype ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash\n ? EncryptableBool['data']\n : E extends ExternalUint8Hash\n ? EncryptableUint8['data']\n : E extends ExternalUint16Hash\n ? EncryptableUint16['data']\n : E extends ExternalUint32Hash\n ? EncryptableUint32['data']\n : E extends ExternalUint64Hash\n ? EncryptableUint64['data']\n : E extends ExternalUint128Hash\n ? EncryptableUint128['data']\n : E extends ExternalAddressHash\n ? EncryptableAddress['data']\n : never;\n\n// Note: AnyExternalHash is checked before Primitive - the branded hash types are structurally\n// `0x${string}` (a subtype of `string`, which is itself a Primitive), so Primitive must not be\n// checked first or every hash would be (incorrectly) widened via LiteralToPrimitive instead.\ntype EncryptedInputsToInputs<T> = T extends AnyExternalHash\n ? ExternalHashToInputMap<T>\n : T extends Primitive\n ? LiteralToPrimitive<T>\n : {\n [K in keyof T]: EncryptedInputsToInputs<T[K]>;\n };\n\n/**\n * Drops the batch-signature argument from an args tuple.\n *\n * The signature slot is the first non-`external*` parameter that follows the contiguous run of\n * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the\n * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters\n * and the args tuple in lockstep and elides the arg at that position.\n */\ntype DropSignatureSlotTuple<\n params extends readonly unknown[],\n args extends readonly unknown[],\n afterExternalRun extends boolean = false,\n> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]]\n ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]]\n ? P extends AbiParameter\n ? ParamHasExternalInput<P> extends true\n ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>]\n : afterExternalRun extends true\n ? DropSignatureSlotTuple<PRest, ARest, false>\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>]\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>]\n : readonly []\n : args;\n\n/** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */\ntype DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[]\n ? DropSignatureSlotTuple<params, args>\n : args;\n\nconst EXTERNAL_INPUT_INTERNAL_TYPES = [\n 'externalEbool',\n 'externalEuint8',\n 'externalEuint16',\n 'externalEuint32',\n 'externalEuint64',\n 'externalEuint128',\n 'externalEaddress',\n] as const;\ntype ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];\n\n/** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */\ntype ParamHasExternalInput<param extends AbiParameter> =\n MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any]\n ? head extends ExternalInputInternalType\n ? true\n : // A struct array (`tuple[]` / `tuple[N]`) lands here too, with `head` the struct's own\n // internalType. Falling through to the components keeps `Order[]` visible as carrying\n // encrypted inputs, the way the runtime `paramHasExternalInput` already sees it.\n ParamComponentsHaveExternalInput<param>\n : param['internalType'] extends ExternalInputInternalType\n ? true\n : ParamComponentsHaveExternalInput<param>;\n\n/** Recurses into a parameter's `components`, for tuples at any array depth. */\ntype ParamComponentsHaveExternalInput<param extends AbiParameter> = param extends {\n components: infer components extends readonly AbiParameter[];\n}\n ? ParamsHaveExternalInput<components>\n : false;\n\ntype ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [\n infer Head extends AbiParameter,\n ...infer Rest extends readonly AbiParameter[],\n]\n ? ParamHasExternalInput<Head> extends true\n ? true\n : ParamsHaveExternalInput<Rest>\n : false;\n\n/**\n * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.\n *\n * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter\n * immediately following them is the shared batch signature slot - the caller never supplies it\n * directly (the SDK injects it after encryption), so it's dropped from this type entirely.\n */\nexport type CofheInputArgsPreTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n> = EncryptedInputsToInputs<\n ParamsHaveExternalInput<abiFunction['inputs']> extends true\n ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>>\n : CofheInputArgs<abi, functionName>\n>;\n\n/// GetArgs from abitype (not exported from abitype)\ntype GetArgs<\n abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly [],\n ///\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>,\n args_ =\n | primitiveTypes // show all values\n | (abi extends Abi\n ? args extends primitiveTypes // infer value (if valid)\n ? primitiveTypes extends args // make sure `args` exactly matches `primitiveTypes` (e.g. avoid `args: readonly [{ foo: string; bar: number; }] | readonly [{ foo: string; }]`)\n ? // make inferred value of `args` match `primitiveTypes` (e.g. avoid union `args: readonly [123n] | readonly [bigint]`)\n ReadonlyWiden<args>\n : never\n : never\n : never)\n | (Abi extends abi ? readonly unknown[] : never), // fallback if `abi` is declared as `Abi`\n> = MaybePartialBy<{ args: args_ }, readonly [] extends primitiveTypes ? 'args' : Abi extends abi ? 'args' : string>;\n\nfunction internalTypeIsExternalInput(internalType: string): internalType is ExternalInputInternalType {\n return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType as any);\n}\n\nfunction paramHasExternalInput(param: AbiParameter): boolean {\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;\n if ('components' in param && Array.isArray(param.components)) {\n return param.components.some((component) => paramHasExternalInput(component));\n }\n return false;\n}\n\nfunction transformSingleExternalToEncryptable(internalType: ExternalInputInternalType, data: unknown): EncryptableItem {\n switch (internalType) {\n case 'externalEbool':\n return Encryptable.bool(data as boolean);\n case 'externalEuint8':\n return Encryptable.uint8(data as string | bigint);\n case 'externalEuint16':\n return Encryptable.uint16(data as string | bigint);\n case 'externalEuint32':\n return Encryptable.uint32(data as string | bigint);\n case 'externalEuint64':\n return Encryptable.uint64(data as string | bigint);\n case 'externalEuint128':\n return Encryptable.uint128(data as string | bigint);\n case 'externalEaddress':\n return Encryptable.address(data as string | bigint);\n default:\n throw new Error(`Unknown external input type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfExternalsToEncryptables(\n internalType: ExternalInputInternalType,\n size: string | undefined,\n data: unknown\n): EncryptableItem[] {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n return data.map((item) => transformSingleExternalToEncryptable(internalType, item));\n}\n\n/**\n * Extracts encryptable values from function arguments based on the ABI.\n * Transforms raw data values into EncryptableItem objects that can be passed to the encrypt function.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;\n * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)\n * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order\n */\nexport function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>\n): EncryptableItem[] {\n const abiFunction = getAbiFunction(abi, functionName);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n // Collect encrypted values as EncryptableItem objects in order (flat array)\n const encryptableItems: EncryptableItem[] = [];\n\n function processParameter(param: AbiParameter, value: unknown): void {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Bare external input (e.g. `externalEuint32`, type: 'bytes32')\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n encryptableItems.push(transformSingleExternalToEncryptable(internalTypeHead, value));\n return;\n }\n\n // Array of external inputs (e.g. `externalEuint32[]`/`externalEuint32[2]`, type: 'bytes32[]'/'bytes32[2]')\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const encryptables = transformArrayOfExternalsToEncryptables(internalTypeHead, typeSize, value);\n encryptableItems.push(...encryptables);\n return;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): void => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n components.forEach((component) => {\n processParameter(component, valueObj[component.name]);\n });\n return;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n components.forEach((component, index) => {\n processParameter(component, tupleValue[index]);\n });\n };\n\n // `tuple[]` / `tuple[N]`: walk each element as its own tuple. Treating the array\n // itself as one tuple would look up named components on the array object, find\n // none, and hand `undefined` to the encryptable transform.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n value.forEach(processTuple);\n return;\n }\n\n processTuple(value);\n }\n return;\n }\n\n // Not an external input, and cannot contain one\n return;\n }\n\n // Process all inputs, skipping the batch-signature slot (nothing to extract there). `args` is the\n // pre-transform tuple, which omits that slot, so its indices lag by one past the signature.\n let argIndex = 0;\n inputs.forEach((input, index) => {\n if (index === signatureSlotIndex) return;\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n processParameter(input, arg);\n });\n\n return encryptableItems;\n}\n\n/**\n * Index of the shared batch-signature parameter: the plain `bytes` immediately after the\n * contiguous run of `external*` parameters. Returns -1 when the function has no encrypted inputs.\n *\n * The proof pairs with the hashes it authenticates (`FHE.asEuintXX(hash, proof)`), so it does not\n * have to be the last parameter - anything may follow it.\n */\nfunction findSignatureSlotIndex(\n inputs: readonly AbiParameter[],\n hasExternalInputs: boolean,\n functionName: string\n): number {\n if (!hasExternalInputs) return -1;\n\n const externalIndices = inputs.reduce<number[]>((acc, input, index) => {\n if (paramHasExternalInput(input)) acc.push(index);\n return acc;\n }, []);\n\n const first = externalIndices[0]!;\n const last = externalIndices[externalIndices.length - 1]!;\n if (last - first + 1 !== externalIndices.length) {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs at non-adjacent positions ` +\n `(${externalIndices.join(', ')}). They share one batch signature, so they must be contiguous ` +\n `with the 'bytes' signature parameter immediately after them`\n );\n }\n\n const slotIndex = last + 1;\n const slot = inputs[slotIndex];\n if (slot?.type !== 'bytes') {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs, so the parameter immediately after ` +\n `them must be a plain 'bytes' parameter to receive the shared batch signature - found ` +\n `'${slot?.type ?? 'nothing'}' at position ${slotIndex} instead`\n );\n }\n\n return slotIndex;\n}\n\n/**\n * Re-inserts encrypted values back into function arguments based on the ABI.\n * Takes the batch-verified result (per-input hashes, in order, followed by the single shared\n * signature) and the original args structure, and produces the final call args: each `external*`\n * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.\n *\n * This function mirrors the extraction logic in extractEncryptableValues, ensuring values\n * are inserted in the exact same order and locations where they were extracted.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Original function arguments in the format of CofheInputArgsPreTransform\n * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`\n * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)\n */\nexport function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>,\n encryptedResult: readonly `0x${string}`[]\n): CofheInputArgs<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];\n const signature = hasExternalInputs ? encryptedResult[encryptedResult.length - 1] : undefined;\n\n // Track position in the hashes array\n let hashIndex = 0;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n\n // Bare external input - substitute its hash\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n if (hashIndex >= hashes.length) {\n throw new Error(`Not enough encrypted hashes: expected at least ${hashIndex + 1}, got ${hashes.length}`);\n }\n const hash = hashes[hashIndex];\n hashIndex++;\n return hash;\n }\n\n // Array of external inputs - substitute the corresponding slice of hashes\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const arrayLength = Array.isArray(value) ? value.length : 0;\n if (arrayLength === 0) {\n return [];\n }\n\n if (hashIndex + arrayLength > hashes.length) {\n throw new Error(\n `Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`\n );\n }\n\n const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);\n hashIndex += arrayLength;\n return hashArray;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: rebuild each element as its own tuple, in the same order\n // extractEncryptableValues walked them, so the hashes line up. Treating the array as\n // one tuple would consume no hashes and collapse the argument to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n return value;\n }\n\n // Not an external input, return original value\n return value;\n }\n\n // Rebuild the full arg list; the signature slot is injected directly. `args` omits that slot, so\n // its indices lag by one past the signature position.\n let argIndex = 0;\n const result = inputs.map((input, index) => {\n if (index === signatureSlotIndex) {\n return signature;\n }\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n return processParameter(input, arg);\n });\n\n // Verify we used all encrypted hashes\n if (hashIndex !== hashes.length) {\n throw new Error(`Mismatch in encrypted hashes count: used ${hashIndex}, but provided ${hashes.length}`);\n }\n\n return result as CofheInputArgs<TAbi, TFunctionName>;\n}\n","import type {\n Abi,\n AbiConstructor,\n AbiError,\n AbiEvent,\n AbiFallback,\n AbiFunction,\n AbiParameter,\n AbiParametersToPrimitiveTypes,\n AbiReceive,\n AbiType,\n Address,\n ExtractAbiFunction,\n ResolvedRegister,\n SolidityArray,\n SolidityFixedArrayRange,\n SolidityTuple,\n} from 'abitype';\n\nexport type ContractReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends AbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = AbiParametersToPrimitiveTypes<outputs, 'outputs', true>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\nexport type Error<messages extends string | string[]> = messages extends string\n ? [\n // Surrounding with array to prevent `messages` from being widened to `string`\n `Error: ${messages}`,\n ]\n : {\n [key in keyof messages]: messages[key] extends infer message extends string ? `Error: ${message}` : never;\n };\n\ntype PartialBy<TType, TKeys extends keyof TType> = ExactPartial<Pick<TType, TKeys>> & Omit<TType, TKeys>;\ntype ExactPartial<T> = { [K in keyof T]?: T[K] | undefined };\n\nexport type MaybePartialBy<TType, TKeys extends string> = TKeys extends keyof TType ? PartialBy<TType, TKeys> : TType;\n\nexport type ReadonlyWiden<TType> =\n | (TType extends Function ? TType : never)\n | (TType extends ResolvedRegister['bigIntType'] ? bigint : never)\n | (TType extends boolean ? boolean : never)\n | (TType extends ResolvedRegister['intType'] ? number : never)\n | (TType extends string\n ? TType extends Address\n ? Address\n : TType extends ResolvedRegister['bytesType']['inputs']\n ? ResolvedRegister['bytesType']\n : string\n : never)\n | (TType extends readonly [] ? readonly [] : never)\n | (TType extends Record<string, unknown> ? { [K in keyof TType]: ReadonlyWiden<TType[K]> } : never)\n | (TType extends { length: number }\n ? {\n [K in keyof TType]: ReadonlyWiden<TType[K]>;\n } extends infer Val extends unknown[]\n ? readonly [...Val]\n : never\n : never);\n\nexport type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>;\n\n/**\n * First, infer `Head` against a known size type (either fixed-length array value or `\"\"`).\n *\n * | Input | Head |\n * | --------------- | ------------ |\n * | `string[]` | `string` |\n * | `string[][][3]` | `string[][]` |\n */\nexport type MaybeExtractArrayParameterType<type> = type extends `${infer head}[${'' | `${SolidityFixedArrayRange}`}]`\n ? // * Then, infer in the opposite direction, using the known `head` to infer the exact `size` value.\n // *\n // * | Input | Size |\n // * | ------------ | ---- |\n // * | `${head}[]` | `\"\"` |\n // * | `${head}[3]` | `3` |\n // */\n type extends `${head}[${infer size}]`\n ? [head, size]\n : undefined\n : undefined;\n\nexport type IsUnion<T, C = T> = T extends C ? ([C] extends [T] ? false : true) : never;\nexport type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]\n ? []\n : [...UnionToTuple<Exclude<U, Last>>, Last];\ntype LastInUnion<U> =\n UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;\ntype UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;\n\n/**\n * Create tuple of {@link type} type with {@link size} size\n *\n * @param Type - Type of tuple\n * @param Size - Size of tuple\n * @returns Tuple of {@link type} type with {@link size} size\n *\n * @example\n * type Result = Tuple<string, 2>\n * // ^? type Result = [string, string]\n */\n// https://github.com/Microsoft/TypeScript/issues/26223#issuecomment-674500430\nexport type Tuple<type, size extends number> = size extends size\n ? number extends size\n ? type[]\n : _TupleOf<type, size, []>\n : never;\ntype _TupleOf<length, size extends number, acc extends readonly unknown[]> = acc['length'] extends size\n ? acc\n : _TupleOf<length, size, readonly [length, ...acc]>;\n\n/**\n * Merges two object types into new type\n *\n * @param object1 - Object to merge into\n * @param object2 - Object to merge and override keys from {@link object1}\n * @returns New object type with keys from {@link object1} and {@link object2}. If a key exists in both {@link object1} and {@link object2}, the key from {@link object2} will be used.\n *\n * @example\n * type Result = Merge<{ foo: string }, { foo: number; bar: string }>\n * // ^? type Result = { foo: number; bar: string }\n */\nexport type Merge<object1, object2> = Omit<object1, keyof object2> & object2;\n\n// FUNCTIONS\n\n/**\n * Extracts array parameter type information from a type string.\n * Always returns a tuple, with undefined for non-array types.\n *\n * @param type - Type string like \"tuple\", \"tuple[]\", or \"tuple[2]\"\n * @returns [head, size] where:\n * - head is the base type\n * - size is undefined for non-arrays, \"\" for dynamic arrays, or the number as a string for fixed arrays\n *\n * @example\n * extractArrayParameterType(\"tuple\") // [\"tuple\", undefined]\n * extractArrayParameterType(\"tuple[]\") // [\"tuple\", \"\"]\n * extractArrayParameterType(\"tuple[2]\") // [\"tuple\", \"2\"]\n */\nexport function extractArrayParameterType<T extends string | undefined>(type: T): [T, string | undefined] {\n if (type == null) return [type, undefined];\n\n const match = type.match(/^(.+)\\[(\\d*)\\]$/);\n\n if (!match) {\n // Not an array type, return [type, undefined]\n return [type, undefined];\n }\n\n const head = match[1];\n const size = match[2]; // Empty string for dynamic arrays, or digits for fixed arrays\n\n // Return empty string for dynamic arrays, or the size string for fixed arrays\n return [head as T, size === '' ? '' : size];\n}\n\n/**\n * Matches the tuple-shape rule used by `CofheAbiComponentsToPrimitiveType`:\n * tuples are objects only when every component has a name. Otherwise they are\n * represented positionally as arrays.\n */\nexport function tupleComponentsAreNamed(components: readonly AbiParameter[]): boolean {\n return components.length > 0 && components.every((component) => component.name != null && component.name !== '');\n}\n\ntype AbiItem = AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive;\n\nexport function isAbiFunction(item: AbiItem | unknown): item is AbiFunction {\n if (typeof item !== 'object' || item === null) return false;\n return 'type' in item && item.type === 'function' && 'name' in item && 'outputs' in item;\n}\n\nexport function getAbiFunction<TAbi extends Abi | readonly unknown[], TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName\n): AbiFunction | undefined {\n return abi.find((item) => {\n const isFunction = isAbiFunction(item);\n if (!isFunction) return false;\n return item.name === functionName;\n }) as AbiFunction | undefined;\n}\n","import { type Primitive, type LiteralToPrimitive, FheTypes } from '@cofhe/sdk';\nimport type { Abi, AbiFunction, ExtractAbiFunction, AbiParameter } from 'abitype';\nimport type {\n EncryptedReturnType,\n CofheAbiParametersToPrimitiveTypes,\n EBool,\n EAddress,\n EUint128,\n EUint16,\n EUint32,\n EUint64,\n EUint8,\n} from './fhenixMap';\nimport {\n getAbiFunction,\n type IsUnion,\n type UnionToTuple,\n type ContractReturnType,\n extractArrayParameterType,\n tupleComponentsAreNamed,\n} from './utils';\n\ntype FirstCofheReturnValue<T> = [T] extends [void]\n ? never\n : T extends readonly [infer Head, ...(readonly unknown[])]\n ? Head\n : T;\n\ntype FheTypeFromCofheReturnValue<T> = T extends { utype: infer U }\n ? U\n : T extends readonly (infer Element)[]\n ? FheTypeFromCofheReturnValue<Element>\n : never;\n\n/**\n * Extracts the `FheTypes` of the first returned value of a CoFHE call.\n *\n * Examples:\n * - `returns (ebool)` -> `FheTypes.Bool`\n * - `returns (euint8, euint64)` -> `FheTypes.Uint8`\n * - `returns (euint16[])` -> `FheTypes.Uint16`\n */\nexport type CofheFirstReturnFheType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = FheTypeFromCofheReturnValue<FirstCofheReturnValue<CofheReturnType<abi, functionName, args>>>;\n\nexport type CofheReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends CofheAbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = CofheAbiParametersToPrimitiveTypes<outputs, 'outputs'>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\ntype EncryptedReturnTypeToReturnTypeMap<E extends EncryptedReturnType> = E extends EBool\n ? boolean\n : E extends EUint8\n ? bigint\n : E extends EUint16\n ? bigint\n : E extends EUint32\n ? bigint\n : E extends EUint64\n ? bigint\n : E extends EUint128\n ? bigint\n : E extends EAddress\n ? string\n : never;\n\ntype EncryptedReturnTypesToReturnTypes<T> = T extends Primitive\n ? LiteralToPrimitive<T>\n : T extends EncryptedReturnType\n ? EncryptedReturnTypeToReturnTypeMap<T>\n : {\n [K in keyof T]: EncryptedReturnTypesToReturnTypes<T[K]>;\n };\n\nexport type CofheReturnTypePostTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = EncryptedReturnTypesToReturnTypes<CofheReturnType<abi, functionName, args>>;\n\nconst ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES = [\n 'ebool',\n 'euint8',\n 'euint16',\n 'euint32',\n 'euint64',\n 'euint128',\n 'eaddress',\n] as const;\ntype EncryptedReturnTypeInternalType = (typeof ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES)[number];\n\ntype EncryptedReturnTypeInternalTypeToReturnTypeMap<T extends EncryptedReturnTypeInternalType> = T extends 'ebool'\n ? EBool\n : T extends 'euint8'\n ? EUint8\n : T extends 'euint16'\n ? EUint16\n : T extends 'euint32'\n ? EUint32\n : T extends 'euint64'\n ? EUint64\n : T extends 'euint128'\n ? EUint128\n : T extends 'eaddress'\n ? EAddress\n : never;\n\nfunction transformSingleEncryptedReturnTypeToReturnType<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n data: string\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T> {\n switch (internalType) {\n case 'ebool':\n return {\n ctHash: data,\n utype: FheTypes.Bool,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint8':\n return {\n ctHash: data,\n utype: FheTypes.Uint8,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint16':\n return {\n ctHash: data,\n utype: FheTypes.Uint16,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint32':\n return {\n ctHash: data,\n utype: FheTypes.Uint32,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint64':\n return {\n ctHash: data,\n utype: FheTypes.Uint64,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint128':\n return {\n ctHash: data,\n utype: FheTypes.Uint128,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'eaddress':\n return {\n ctHash: data,\n utype: FheTypes.Uint160,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n default:\n throw new Error(`Unknown encrypted return type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfEncryptedReturnTypesToReturnTypes<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n size: string | undefined,\n data: string[]\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T>[] {\n // Ensure data is an array\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n // Ensure length of fixed length tuple matches the length of the data array\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n // Transform each item in the data array into an return type\n return data.map((item) => transformSingleEncryptedReturnTypeToReturnType(internalType, item));\n}\n\nfunction internalTypeIsEncryptedReturnType(internalType: string): internalType is EncryptedReturnTypeInternalType {\n return ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES.includes(internalType as any);\n}\n\nexport function transformEncryptedReturnTypes<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n data: ContractReturnType<TAbi, TFunctionName>\n): CofheReturnType<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const outputs = abiFunction?.outputs;\n if (abiFunction == null || outputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n const outputsLength = outputs.length;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Is encrypted return type\n if (internalTypeHead != null && internalTypeIsEncryptedReturnType(internalTypeHead)) {\n // Is single encrypted return type\n if (internalTypeSize == null) {\n return transformSingleEncryptedReturnTypeToReturnType(internalTypeHead, value as string);\n }\n\n // Is array of encrypted return types\n if (internalTypeSize != null) {\n return transformArrayOfEncryptedReturnTypesToReturnTypes(internalTypeHead, internalTypeSize, value as string[]);\n }\n }\n\n // Tuple but not an encrypted return type (recursive case)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: transform each element as its own tuple. Treating the\n // array itself as one tuple would look up named components on the array object,\n // find none, and collapse the whole result to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n\n return value;\n }\n\n // Not an encrypted return type, return original value\n return value;\n }\n\n // Process results (array case)\n if (outputsLength > 1) {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n if (outputsLength !== data.length) {\n throw new Error(`Mismatch in outputs length: ${outputsLength} !== ${data.length}`);\n }\n return data.map((item, index) => {\n return processParameter(outputs[index], item);\n }) as CofheReturnType<TAbi, TFunctionName>;\n }\n\n // Process retuls (single item case)\n return processParameter(outputs[0], data) as CofheReturnType<TAbi, TFunctionName>;\n}\n"],"mappings":"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","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../src/encryptedInputs.ts","../src/utils.ts","../src/encryptedReturnTypes.ts"],"sourcesContent":["import {\n Encryptable,\n type AnyExternalHash,\n type EncryptableAddress,\n type EncryptableBool,\n type EncryptableItem,\n type EncryptableUint128,\n type EncryptableUint16,\n type EncryptableUint32,\n type EncryptableUint64,\n type EncryptableUint8,\n type ExternalAddressHash,\n type ExternalBoolHash,\n type ExternalUint128Hash,\n type ExternalUint16Hash,\n type ExternalUint32Hash,\n type ExternalUint64Hash,\n type ExternalUint8Hash,\n type LiteralToPrimitive,\n type Primitive,\n} from '@cofhe/sdk';\nimport type { Abi, AbiFunction, AbiParameter, ExtractAbiFunction } from 'abitype';\nimport type { CofheAbiParametersToPrimitiveTypes } from './fhenixMap';\nimport {\n extractArrayParameterType,\n isAbiFunction,\n type MaybeExtractArrayParameterType,\n type MaybePartialBy,\n type ReadonlyWiden,\n tupleComponentsAreNamed,\n} from './utils';\n\nexport type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<\n abi,\n functionName\n>['args'];\n\ntype ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash\n ? EncryptableBool['data']\n : E extends ExternalUint8Hash\n ? EncryptableUint8['data']\n : E extends ExternalUint16Hash\n ? EncryptableUint16['data']\n : E extends ExternalUint32Hash\n ? EncryptableUint32['data']\n : E extends ExternalUint64Hash\n ? EncryptableUint64['data']\n : E extends ExternalUint128Hash\n ? EncryptableUint128['data']\n : E extends ExternalAddressHash\n ? EncryptableAddress['data']\n : never;\n\n// Note: AnyExternalHash is checked before Primitive - the branded hash types are structurally\n// `0x${string}` (a subtype of `string`, which is itself a Primitive), so Primitive must not be\n// checked first or every hash would be (incorrectly) widened via LiteralToPrimitive instead.\ntype EncryptedInputsToInputs<T> = T extends AnyExternalHash\n ? ExternalHashToInputMap<T>\n : T extends Primitive\n ? LiteralToPrimitive<T>\n : {\n [K in keyof T]: EncryptedInputsToInputs<T[K]>;\n };\n\n/**\n * Drops the batch-signature argument from an args tuple.\n *\n * The signature slot is the first non-`external*` parameter that follows the contiguous run of\n * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the\n * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters\n * and the args tuple in lockstep and elides the arg at that position.\n */\ntype DropSignatureSlotTuple<\n params extends readonly unknown[],\n args extends readonly unknown[],\n afterExternalRun extends boolean = false,\n> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]]\n ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]]\n ? P extends AbiParameter\n ? ParamHasExternalInput<P> extends true\n ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>]\n : afterExternalRun extends true\n ? DropSignatureSlotTuple<PRest, ARest, false>\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>]\n : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>]\n : readonly []\n : args;\n\n/** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */\ntype DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[]\n ? DropSignatureSlotTuple<params, args>\n : args;\n\nconst EXTERNAL_INPUT_INTERNAL_TYPES = [\n 'externalEbool',\n 'externalEuint8',\n 'externalEuint16',\n 'externalEuint32',\n 'externalEuint64',\n 'externalEuint128',\n 'externalEaddress',\n] as const;\ntype ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];\n\n/** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */\ntype ParamHasExternalInput<param extends AbiParameter> =\n MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any]\n ? head extends ExternalInputInternalType\n ? true\n : // A struct array (`tuple[]` / `tuple[N]`) lands here too, with `head` the struct's own\n // internalType. Falling through to the components keeps `Order[]` visible as carrying\n // encrypted inputs, the way the runtime `paramHasExternalInput` already sees it.\n ParamComponentsHaveExternalInput<param>\n : param['internalType'] extends ExternalInputInternalType\n ? true\n : ParamComponentsHaveExternalInput<param>;\n\n/** Recurses into a parameter's `components`, for tuples at any array depth. */\ntype ParamComponentsHaveExternalInput<param extends AbiParameter> = param extends {\n components: infer components extends readonly AbiParameter[];\n}\n ? ParamsHaveExternalInput<components>\n : false;\n\ntype ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [\n infer Head extends AbiParameter,\n ...infer Rest extends readonly AbiParameter[],\n]\n ? ParamHasExternalInput<Head> extends true\n ? true\n : ParamsHaveExternalInput<Rest>\n : false;\n\n/**\n * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.\n *\n * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter\n * immediately following them is the shared batch signature slot - the caller never supplies it\n * directly (the SDK injects it after encryption), so it's dropped from this type entirely.\n */\nexport type CofheInputArgsPreTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n> = EncryptedInputsToInputs<\n ParamsHaveExternalInput<abiFunction['inputs']> extends true\n ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>>\n : CofheInputArgs<abi, functionName>\n>;\n\n/// GetArgs from abitype (not exported from abitype)\ntype GetArgs<\n abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly [],\n ///\n abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction,\n primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>,\n args_ =\n | primitiveTypes // show all values\n | (abi extends Abi\n ? args extends primitiveTypes // infer value (if valid)\n ? primitiveTypes extends args // make sure `args` exactly matches `primitiveTypes` (e.g. avoid `args: readonly [{ foo: string; bar: number; }] | readonly [{ foo: string; }]`)\n ? // make inferred value of `args` match `primitiveTypes` (e.g. avoid union `args: readonly [123n] | readonly [bigint]`)\n ReadonlyWiden<args>\n : never\n : never\n : never)\n | (Abi extends abi ? readonly unknown[] : never), // fallback if `abi` is declared as `Abi`\n> = MaybePartialBy<{ args: args_ }, readonly [] extends primitiveTypes ? 'args' : Abi extends abi ? 'args' : string>;\n\nfunction internalTypeIsExternalInput(internalType: string): internalType is ExternalInputInternalType {\n return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType as any);\n}\n\n/**\n * Resolves `functionName` to a single ABI entry. When the name is overloaded, the\n * overload is chosen by argument count: `args` leaves out the batch signature slot, so\n * an overload with `external*` inputs takes one ABI parameter more than it gets args.\n * Overloads with `external*` inputs win, since these helpers only run for calls that\n * are being encrypted. Solidity tooling sorts overloads by selector, so the first\n * entry by name is often the plaintext one.\n */\nfunction getInputFunction(abi: readonly unknown[], functionName: string, args: readonly unknown[]) {\n const overloads = abi.filter((item): item is AbiFunction => isAbiFunction(item) && item.name === functionName);\n if (overloads.length <= 1) return overloads[0];\n\n const hasExternalInputs = (fn: AbiFunction) => fn.inputs.some((input) => paramHasExternalInput(input));\n const byArity = overloads.filter((fn) => fn.inputs.length - (hasExternalInputs(fn) ? 1 : 0) === args.length);\n const encrypted = byArity.filter(hasExternalInputs);\n const candidates = encrypted.length > 0 ? encrypted : byArity;\n\n if (candidates.length !== 1) {\n throw new Error(\n `Function ${functionName} is overloaded and ${args.length} argument(s) do not select a single overload`\n );\n }\n return candidates[0];\n}\n\nfunction paramHasExternalInput(param: AbiParameter): boolean {\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;\n if ('components' in param && Array.isArray(param.components)) {\n return param.components.some((component) => paramHasExternalInput(component));\n }\n return false;\n}\n\nfunction transformSingleExternalToEncryptable(internalType: ExternalInputInternalType, data: unknown): EncryptableItem {\n switch (internalType) {\n case 'externalEbool':\n return Encryptable.bool(data as boolean);\n case 'externalEuint8':\n return Encryptable.uint8(data as string | bigint);\n case 'externalEuint16':\n return Encryptable.uint16(data as string | bigint);\n case 'externalEuint32':\n return Encryptable.uint32(data as string | bigint);\n case 'externalEuint64':\n return Encryptable.uint64(data as string | bigint);\n case 'externalEuint128':\n return Encryptable.uint128(data as string | bigint);\n case 'externalEaddress':\n return Encryptable.address(data as string | bigint);\n default:\n throw new Error(`Unknown external input type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfExternalsToEncryptables(\n internalType: ExternalInputInternalType,\n size: string | undefined,\n data: unknown\n): EncryptableItem[] {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n return data.map((item) => transformSingleExternalToEncryptable(internalType, item));\n}\n\n/**\n * Extracts encryptable values from function arguments based on the ABI.\n * Transforms raw data values into EncryptableItem objects that can be passed to the encrypt function.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;\n * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)\n * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order\n */\nexport function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>\n): EncryptableItem[] {\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const abiFunction = getInputFunction(abi, functionName, args);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n // Collect encrypted values as EncryptableItem objects in order (flat array)\n const encryptableItems: EncryptableItem[] = [];\n\n function processParameter(param: AbiParameter, value: unknown): void {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Bare external input (e.g. `externalEuint32`, type: 'bytes32')\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n encryptableItems.push(transformSingleExternalToEncryptable(internalTypeHead, value));\n return;\n }\n\n // Array of external inputs (e.g. `externalEuint32[]`/`externalEuint32[2]`, type: 'bytes32[]'/'bytes32[2]')\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const encryptables = transformArrayOfExternalsToEncryptables(internalTypeHead, typeSize, value);\n encryptableItems.push(...encryptables);\n return;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): void => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n components.forEach((component) => {\n processParameter(component, valueObj[component.name]);\n });\n return;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n components.forEach((component, index) => {\n processParameter(component, tupleValue[index]);\n });\n };\n\n // `tuple[]` / `tuple[N]`: walk each element as its own tuple. Treating the array\n // itself as one tuple would look up named components on the array object, find\n // none, and hand `undefined` to the encryptable transform.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n value.forEach(processTuple);\n return;\n }\n\n processTuple(value);\n }\n return;\n }\n\n // Not an external input, and cannot contain one\n return;\n }\n\n // Process all inputs, skipping the batch-signature slot (nothing to extract there). `args` is the\n // pre-transform tuple, which omits that slot, so its indices lag by one past the signature.\n let argIndex = 0;\n inputs.forEach((input, index) => {\n if (index === signatureSlotIndex) return;\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n processParameter(input, arg);\n });\n\n return encryptableItems;\n}\n\n/**\n * Index of the shared batch-signature parameter: the plain `bytes` immediately after the\n * contiguous run of `external*` parameters. Returns -1 when the function has no encrypted inputs.\n *\n * The proof pairs with the hashes it authenticates (`FHE.asEuintXX(hash, proof)`), so it does not\n * have to be the last parameter - anything may follow it.\n */\nfunction findSignatureSlotIndex(\n inputs: readonly AbiParameter[],\n hasExternalInputs: boolean,\n functionName: string\n): number {\n if (!hasExternalInputs) return -1;\n\n const externalIndices = inputs.reduce<number[]>((acc, input, index) => {\n if (paramHasExternalInput(input)) acc.push(index);\n return acc;\n }, []);\n\n const first = externalIndices[0]!;\n const last = externalIndices[externalIndices.length - 1]!;\n if (last - first + 1 !== externalIndices.length) {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs at non-adjacent positions ` +\n `(${externalIndices.join(', ')}). They share one batch signature, so they must be contiguous ` +\n `with the 'bytes' signature parameter immediately after them`\n );\n }\n\n const slotIndex = last + 1;\n const slot = inputs[slotIndex];\n if (slot?.type !== 'bytes') {\n throw new Error(\n `Function ${functionName} has encrypted (external*) inputs, so the parameter immediately after ` +\n `them must be a plain 'bytes' parameter to receive the shared batch signature - found ` +\n `'${slot?.type ?? 'nothing'}' at position ${slotIndex} instead`\n );\n }\n\n return slotIndex;\n}\n\n/**\n * Re-inserts encrypted values back into function arguments based on the ABI.\n * Takes the batch-verified result (per-input hashes, in order, followed by the single shared\n * signature) and the original args structure, and produces the final call args: each `external*`\n * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.\n *\n * This function mirrors the extraction logic in extractEncryptableValues, ensuring values\n * are inserted in the exact same order and locations where they were extracted.\n *\n * @param abi - The ABI containing the function definition\n * @param functionName - Name of the function\n * @param args - Original function arguments in the format of CofheInputArgsPreTransform\n * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`\n * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)\n */\nexport function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n args: CofheInputArgsPreTransform<TAbi, TFunctionName>,\n encryptedResult: readonly `0x${string}`[]\n): CofheInputArgs<TAbi, TFunctionName> {\n if (!Array.isArray(args)) {\n throw new Error('Arguments must be an array');\n }\n\n const abiFunction = getInputFunction(abi, functionName, args);\n const inputs = abiFunction?.inputs;\n if (abiFunction == null || inputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n\n const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));\n const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);\n\n const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];\n const signature = hasExternalInputs ? encryptedResult[encryptedResult.length - 1] : undefined;\n\n // Track position in the hashes array\n let hashIndex = 0;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead] = extractArrayParameterType(param.internalType);\n\n // Bare external input - substitute its hash\n if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n if (hashIndex >= hashes.length) {\n throw new Error(`Not enough encrypted hashes: expected at least ${hashIndex + 1}, got ${hashes.length}`);\n }\n const hash = hashes[hashIndex];\n hashIndex++;\n return hash;\n }\n\n // Array of external inputs - substitute the corresponding slice of hashes\n if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {\n const arrayLength = Array.isArray(value) ? value.length : 0;\n if (arrayLength === 0) {\n return [];\n }\n\n if (hashIndex + arrayLength > hashes.length) {\n throw new Error(\n `Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`\n );\n }\n\n const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);\n hashIndex += arrayLength;\n return hashArray;\n }\n\n // Tuple recursive case (struct that may itself contain external inputs)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: rebuild each element as its own tuple, in the same order\n // extractEncryptableValues walked them, so the hashes line up. Treating the array as\n // one tuple would consume no hashes and collapse the argument to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n return value;\n }\n\n // Not an external input, return original value\n return value;\n }\n\n // Rebuild the full arg list; the signature slot is injected directly. `args` omits that slot, so\n // its indices lag by one past the signature position.\n let argIndex = 0;\n const result = inputs.map((input, index) => {\n if (index === signatureSlotIndex) {\n return signature;\n }\n const arg = args[argIndex];\n if (arg == null) {\n throw new Error(`Argument ${argIndex} is undefined`);\n }\n argIndex++;\n return processParameter(input, arg);\n });\n\n // Verify we used all encrypted hashes\n if (hashIndex !== hashes.length) {\n throw new Error(`Mismatch in encrypted hashes count: used ${hashIndex}, but provided ${hashes.length}`);\n }\n\n return result as CofheInputArgs<TAbi, TFunctionName>;\n}\n","import type {\n Abi,\n AbiConstructor,\n AbiError,\n AbiEvent,\n AbiFallback,\n AbiFunction,\n AbiParameter,\n AbiParametersToPrimitiveTypes,\n AbiReceive,\n AbiType,\n Address,\n ExtractAbiFunction,\n ResolvedRegister,\n SolidityArray,\n SolidityFixedArrayRange,\n SolidityTuple,\n} from 'abitype';\n\nexport type ContractReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends AbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = AbiParametersToPrimitiveTypes<outputs, 'outputs', true>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\nexport type Error<messages extends string | string[]> = messages extends string\n ? [\n // Surrounding with array to prevent `messages` from being widened to `string`\n `Error: ${messages}`,\n ]\n : {\n [key in keyof messages]: messages[key] extends infer message extends string ? `Error: ${message}` : never;\n };\n\ntype PartialBy<TType, TKeys extends keyof TType> = ExactPartial<Pick<TType, TKeys>> & Omit<TType, TKeys>;\ntype ExactPartial<T> = { [K in keyof T]?: T[K] | undefined };\n\nexport type MaybePartialBy<TType, TKeys extends string> = TKeys extends keyof TType ? PartialBy<TType, TKeys> : TType;\n\nexport type ReadonlyWiden<TType> =\n | (TType extends Function ? TType : never)\n | (TType extends ResolvedRegister['bigIntType'] ? bigint : never)\n | (TType extends boolean ? boolean : never)\n | (TType extends ResolvedRegister['intType'] ? number : never)\n | (TType extends string\n ? TType extends Address\n ? Address\n : TType extends ResolvedRegister['bytesType']['inputs']\n ? ResolvedRegister['bytesType']\n : string\n : never)\n | (TType extends readonly [] ? readonly [] : never)\n | (TType extends Record<string, unknown> ? { [K in keyof TType]: ReadonlyWiden<TType[K]> } : never)\n | (TType extends { length: number }\n ? {\n [K in keyof TType]: ReadonlyWiden<TType[K]>;\n } extends infer Val extends unknown[]\n ? readonly [...Val]\n : never\n : never);\n\nexport type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>;\n\n/**\n * First, infer `Head` against a known size type (either fixed-length array value or `\"\"`).\n *\n * | Input | Head |\n * | --------------- | ------------ |\n * | `string[]` | `string` |\n * | `string[][][3]` | `string[][]` |\n */\nexport type MaybeExtractArrayParameterType<type> = type extends `${infer head}[${'' | `${SolidityFixedArrayRange}`}]`\n ? // * Then, infer in the opposite direction, using the known `head` to infer the exact `size` value.\n // *\n // * | Input | Size |\n // * | ------------ | ---- |\n // * | `${head}[]` | `\"\"` |\n // * | `${head}[3]` | `3` |\n // */\n type extends `${head}[${infer size}]`\n ? [head, size]\n : undefined\n : undefined;\n\nexport type IsUnion<T, C = T> = T extends C ? ([C] extends [T] ? false : true) : never;\nexport type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]\n ? []\n : [...UnionToTuple<Exclude<U, Last>>, Last];\ntype LastInUnion<U> =\n UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;\ntype UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;\n\n/**\n * Create tuple of {@link type} type with {@link size} size\n *\n * @param Type - Type of tuple\n * @param Size - Size of tuple\n * @returns Tuple of {@link type} type with {@link size} size\n *\n * @example\n * type Result = Tuple<string, 2>\n * // ^? type Result = [string, string]\n */\n// https://github.com/Microsoft/TypeScript/issues/26223#issuecomment-674500430\nexport type Tuple<type, size extends number> = size extends size\n ? number extends size\n ? type[]\n : _TupleOf<type, size, []>\n : never;\ntype _TupleOf<length, size extends number, acc extends readonly unknown[]> = acc['length'] extends size\n ? acc\n : _TupleOf<length, size, readonly [length, ...acc]>;\n\n/**\n * Merges two object types into new type\n *\n * @param object1 - Object to merge into\n * @param object2 - Object to merge and override keys from {@link object1}\n * @returns New object type with keys from {@link object1} and {@link object2}. If a key exists in both {@link object1} and {@link object2}, the key from {@link object2} will be used.\n *\n * @example\n * type Result = Merge<{ foo: string }, { foo: number; bar: string }>\n * // ^? type Result = { foo: number; bar: string }\n */\nexport type Merge<object1, object2> = Omit<object1, keyof object2> & object2;\n\n// FUNCTIONS\n\n/**\n * Extracts array parameter type information from a type string.\n * Always returns a tuple, with undefined for non-array types.\n *\n * @param type - Type string like \"tuple\", \"tuple[]\", or \"tuple[2]\"\n * @returns [head, size] where:\n * - head is the base type\n * - size is undefined for non-arrays, \"\" for dynamic arrays, or the number as a string for fixed arrays\n *\n * @example\n * extractArrayParameterType(\"tuple\") // [\"tuple\", undefined]\n * extractArrayParameterType(\"tuple[]\") // [\"tuple\", \"\"]\n * extractArrayParameterType(\"tuple[2]\") // [\"tuple\", \"2\"]\n */\nexport function extractArrayParameterType<T extends string | undefined>(type: T): [T, string | undefined] {\n if (type == null) return [type, undefined];\n\n const match = type.match(/^(.+)\\[(\\d*)\\]$/);\n\n if (!match) {\n // Not an array type, return [type, undefined]\n return [type, undefined];\n }\n\n const head = match[1];\n const size = match[2]; // Empty string for dynamic arrays, or digits for fixed arrays\n\n // Return empty string for dynamic arrays, or the size string for fixed arrays\n return [head as T, size === '' ? '' : size];\n}\n\n/**\n * Matches the tuple-shape rule used by `CofheAbiComponentsToPrimitiveType`:\n * tuples are objects only when every component has a name. Otherwise they are\n * represented positionally as arrays.\n */\nexport function tupleComponentsAreNamed(components: readonly AbiParameter[]): boolean {\n return components.length > 0 && components.every((component) => component.name != null && component.name !== '');\n}\n\ntype AbiItem = AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive;\n\nexport function isAbiFunction(item: AbiItem | unknown): item is AbiFunction {\n if (typeof item !== 'object' || item === null) return false;\n return 'type' in item && item.type === 'function' && 'name' in item && 'outputs' in item;\n}\n\nexport function getAbiFunction<TAbi extends Abi | readonly unknown[], TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName\n): AbiFunction | undefined {\n return abi.find((item) => {\n const isFunction = isAbiFunction(item);\n if (!isFunction) return false;\n return item.name === functionName;\n }) as AbiFunction | undefined;\n}\n","import { type Primitive, type LiteralToPrimitive, FheTypes } from '@cofhe/sdk';\nimport type { Abi, AbiFunction, ExtractAbiFunction, AbiParameter } from 'abitype';\nimport type {\n EncryptedReturnType,\n CofheAbiParametersToPrimitiveTypes,\n EBool,\n EAddress,\n EUint128,\n EUint16,\n EUint32,\n EUint64,\n EUint8,\n} from './fhenixMap';\nimport {\n getAbiFunction,\n type IsUnion,\n type UnionToTuple,\n type ContractReturnType,\n extractArrayParameterType,\n tupleComponentsAreNamed,\n} from './utils';\n\ntype FirstCofheReturnValue<T> = [T] extends [void]\n ? never\n : T extends readonly [infer Head, ...(readonly unknown[])]\n ? Head\n : T;\n\ntype FheTypeFromCofheReturnValue<T> = T extends { utype: infer U }\n ? U\n : T extends readonly (infer Element)[]\n ? FheTypeFromCofheReturnValue<Element>\n : never;\n\n/**\n * Extracts the `FheTypes` of the first returned value of a CoFHE call.\n *\n * Examples:\n * - `returns (ebool)` -> `FheTypes.Bool`\n * - `returns (euint8, euint64)` -> `FheTypes.Uint8`\n * - `returns (euint16[])` -> `FheTypes.Uint16`\n */\nexport type CofheFirstReturnFheType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = FheTypeFromCofheReturnValue<FirstCofheReturnValue<CofheReturnType<abi, functionName, args>>>;\n\nexport type CofheReturnType<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n ///\n abiFunction extends AbiFunction = (\n abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction\n ) extends infer abiFunction_ extends AbiFunction\n ? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match\n ? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]\n ? {\n [K in keyof abiFunctions]: (\n readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`\n ? readonly []\n : args\n ) extends CofheAbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>\n ? abiFunctions[K]\n : never;\n }[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)\n : never\n : abiFunction_\n : never,\n outputs extends readonly AbiParameter[] = abiFunction['outputs'],\n primitiveTypes extends readonly unknown[] = CofheAbiParametersToPrimitiveTypes<outputs, 'outputs'>,\n> = [abiFunction] extends [never]\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)\n : readonly unknown[] extends primitiveTypes\n ? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)\n : primitiveTypes extends readonly [] // unwrap `primitiveTypes`\n ? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n void // no outputs\n : primitiveTypes extends readonly [infer primitiveType]\n ? primitiveType // single output\n : primitiveTypes;\n\ntype EncryptedReturnTypeToReturnTypeMap<E extends EncryptedReturnType> = E extends EBool\n ? boolean\n : E extends EUint8\n ? bigint\n : E extends EUint16\n ? bigint\n : E extends EUint32\n ? bigint\n : E extends EUint64\n ? bigint\n : E extends EUint128\n ? bigint\n : E extends EAddress\n ? string\n : never;\n\ntype EncryptedReturnTypesToReturnTypes<T> = T extends Primitive\n ? LiteralToPrimitive<T>\n : T extends EncryptedReturnType\n ? EncryptedReturnTypeToReturnTypeMap<T>\n : {\n [K in keyof T]: EncryptedReturnTypesToReturnTypes<T[K]>;\n };\n\nexport type CofheReturnTypePostTransform<\n abi extends Abi | readonly unknown[] = Abi,\n functionName extends string = string,\n args extends readonly unknown[] | undefined = readonly unknown[] | undefined,\n> = EncryptedReturnTypesToReturnTypes<CofheReturnType<abi, functionName, args>>;\n\nconst ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES = [\n 'ebool',\n 'euint8',\n 'euint16',\n 'euint32',\n 'euint64',\n 'euint128',\n 'eaddress',\n] as const;\ntype EncryptedReturnTypeInternalType = (typeof ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES)[number];\n\ntype EncryptedReturnTypeInternalTypeToReturnTypeMap<T extends EncryptedReturnTypeInternalType> = T extends 'ebool'\n ? EBool\n : T extends 'euint8'\n ? EUint8\n : T extends 'euint16'\n ? EUint16\n : T extends 'euint32'\n ? EUint32\n : T extends 'euint64'\n ? EUint64\n : T extends 'euint128'\n ? EUint128\n : T extends 'eaddress'\n ? EAddress\n : never;\n\nfunction transformSingleEncryptedReturnTypeToReturnType<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n data: string\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T> {\n switch (internalType) {\n case 'ebool':\n return {\n ctHash: data,\n utype: FheTypes.Bool,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint8':\n return {\n ctHash: data,\n utype: FheTypes.Uint8,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint16':\n return {\n ctHash: data,\n utype: FheTypes.Uint16,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint32':\n return {\n ctHash: data,\n utype: FheTypes.Uint32,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint64':\n return {\n ctHash: data,\n utype: FheTypes.Uint64,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'euint128':\n return {\n ctHash: data,\n utype: FheTypes.Uint128,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n case 'eaddress':\n return {\n ctHash: data,\n utype: FheTypes.Uint160,\n } as EncryptedReturnTypeInternalTypeToReturnTypeMap<T>;\n default:\n throw new Error(`Unknown encrypted return type: ${internalType}`);\n }\n}\n\nfunction transformArrayOfEncryptedReturnTypesToReturnTypes<T extends EncryptedReturnTypeInternalType>(\n internalType: T,\n size: string | undefined,\n data: string[]\n): EncryptedReturnTypeInternalTypeToReturnTypeMap<T>[] {\n // Ensure data is an array\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n\n // Ensure length of fixed length tuple matches the length of the data array\n if (size != null && size !== '' && parseInt(size) !== data.length) {\n throw new Error(`Array size mismatch: ${size} !== ${data.length}`);\n }\n\n // Transform each item in the data array into an return type\n return data.map((item) => transformSingleEncryptedReturnTypeToReturnType(internalType, item));\n}\n\nfunction internalTypeIsEncryptedReturnType(internalType: string): internalType is EncryptedReturnTypeInternalType {\n return ENCRYPTED_RETURN_TYPE_INTERNAL_TYPES.includes(internalType as any);\n}\n\nexport function transformEncryptedReturnTypes<TAbi extends Abi, TFunctionName extends string>(\n abi: TAbi,\n functionName: TFunctionName,\n data: ContractReturnType<TAbi, TFunctionName>\n): CofheReturnType<TAbi, TFunctionName> {\n const abiFunction = getAbiFunction(abi, functionName);\n const outputs = abiFunction?.outputs;\n if (abiFunction == null || outputs == null) {\n throw new Error(`Function ${functionName} not found in ABI`);\n }\n const outputsLength = outputs.length;\n\n function processParameter(param: AbiParameter, value: unknown): unknown {\n const [typeHead, typeSize] = extractArrayParameterType(param.type);\n const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);\n\n // Is encrypted return type\n if (internalTypeHead != null && internalTypeIsEncryptedReturnType(internalTypeHead)) {\n // Is single encrypted return type\n if (internalTypeSize == null) {\n return transformSingleEncryptedReturnTypeToReturnType(internalTypeHead, value as string);\n }\n\n // Is array of encrypted return types\n if (internalTypeSize != null) {\n return transformArrayOfEncryptedReturnTypesToReturnTypes(internalTypeHead, internalTypeSize, value as string[]);\n }\n }\n\n // Tuple but not an encrypted return type (recursive case)\n if (typeHead === 'tuple') {\n if ('components' in param && Array.isArray(param.components)) {\n const components = param.components;\n\n const processTuple = (tupleValue: unknown): unknown => {\n if (tupleComponentsAreNamed(components)) {\n const valueObj = tupleValue as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n\n components.forEach((component) => {\n const componentName = component.name;\n if (componentName) {\n const componentValue = valueObj[componentName];\n if (componentValue !== undefined) {\n result[componentName] = processParameter(component, componentValue);\n }\n }\n });\n\n return result;\n }\n\n if (!Array.isArray(tupleValue)) {\n throw new Error('Expected an array value for tuple with unnamed components');\n }\n\n return components.map((component, index) => processParameter(component, tupleValue[index]));\n };\n\n // `tuple[]` / `tuple[N]`: transform each element as its own tuple. Treating the\n // array itself as one tuple would look up named components on the array object,\n // find none, and collapse the whole result to `{}`.\n if (typeSize != null) {\n if (!Array.isArray(value)) {\n throw new Error(`Expected an array value for ${param.type}`);\n }\n if (typeSize !== '' && parseInt(typeSize) !== value.length) {\n throw new Error(`Array size mismatch: ${typeSize} !== ${value.length}`);\n }\n return value.map(processTuple);\n }\n\n return processTuple(value);\n }\n\n return value;\n }\n\n // Not an encrypted return type, return original value\n return value;\n }\n\n // Process results (array case)\n if (outputsLength > 1) {\n if (!Array.isArray(data)) {\n throw new Error('Data must be an array');\n }\n if (outputsLength !== data.length) {\n throw new Error(`Mismatch in outputs length: ${outputsLength} !== ${data.length}`);\n }\n return data.map((item, index) => {\n return processParameter(outputs[index], item);\n }) as CofheReturnType<TAbi, TFunctionName>;\n }\n\n // Process retuls (single item case)\n return processParameter(outputs[0], data) as CofheReturnType<TAbi, TFunctionName>;\n}\n"],"mappings":"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","names":["result"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cofhe/abi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ABI utilities for Fhenix FHE contracts",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"abitype": "1.2.3",
|
|
30
|
-
"@cofhe/sdk": "1.
|
|
30
|
+
"@cofhe/sdk": "1.1.0-alpha.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "20.19.15",
|
package/src/encryptedInputs.ts
CHANGED
|
@@ -23,7 +23,7 @@ import type { Abi, AbiFunction, AbiParameter, ExtractAbiFunction } from 'abitype
|
|
|
23
23
|
import type { CofheAbiParametersToPrimitiveTypes } from './fhenixMap';
|
|
24
24
|
import {
|
|
25
25
|
extractArrayParameterType,
|
|
26
|
-
|
|
26
|
+
isAbiFunction,
|
|
27
27
|
type MaybeExtractArrayParameterType,
|
|
28
28
|
type MaybePartialBy,
|
|
29
29
|
type ReadonlyWiden,
|
|
@@ -173,6 +173,31 @@ function internalTypeIsExternalInput(internalType: string): internalType is Exte
|
|
|
173
173
|
return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType as any);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Resolves `functionName` to a single ABI entry. When the name is overloaded, the
|
|
178
|
+
* overload is chosen by argument count: `args` leaves out the batch signature slot, so
|
|
179
|
+
* an overload with `external*` inputs takes one ABI parameter more than it gets args.
|
|
180
|
+
* Overloads with `external*` inputs win, since these helpers only run for calls that
|
|
181
|
+
* are being encrypted. Solidity tooling sorts overloads by selector, so the first
|
|
182
|
+
* entry by name is often the plaintext one.
|
|
183
|
+
*/
|
|
184
|
+
function getInputFunction(abi: readonly unknown[], functionName: string, args: readonly unknown[]) {
|
|
185
|
+
const overloads = abi.filter((item): item is AbiFunction => isAbiFunction(item) && item.name === functionName);
|
|
186
|
+
if (overloads.length <= 1) return overloads[0];
|
|
187
|
+
|
|
188
|
+
const hasExternalInputs = (fn: AbiFunction) => fn.inputs.some((input) => paramHasExternalInput(input));
|
|
189
|
+
const byArity = overloads.filter((fn) => fn.inputs.length - (hasExternalInputs(fn) ? 1 : 0) === args.length);
|
|
190
|
+
const encrypted = byArity.filter(hasExternalInputs);
|
|
191
|
+
const candidates = encrypted.length > 0 ? encrypted : byArity;
|
|
192
|
+
|
|
193
|
+
if (candidates.length !== 1) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`Function ${functionName} is overloaded and ${args.length} argument(s) do not select a single overload`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
return candidates[0];
|
|
199
|
+
}
|
|
200
|
+
|
|
176
201
|
function paramHasExternalInput(param: AbiParameter): boolean {
|
|
177
202
|
const [internalTypeHead] = extractArrayParameterType(param.internalType);
|
|
178
203
|
if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;
|
|
@@ -234,16 +259,16 @@ export function extractEncryptableValues<TAbi extends Abi, TFunctionName extends
|
|
|
234
259
|
functionName: TFunctionName,
|
|
235
260
|
args: CofheInputArgsPreTransform<TAbi, TFunctionName>
|
|
236
261
|
): EncryptableItem[] {
|
|
237
|
-
|
|
262
|
+
if (!Array.isArray(args)) {
|
|
263
|
+
throw new Error('Arguments must be an array');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
238
267
|
const inputs = abiFunction?.inputs;
|
|
239
268
|
if (abiFunction == null || inputs == null) {
|
|
240
269
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
241
270
|
}
|
|
242
271
|
|
|
243
|
-
if (!Array.isArray(args)) {
|
|
244
|
-
throw new Error('Arguments must be an array');
|
|
245
|
-
}
|
|
246
|
-
|
|
247
272
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
248
273
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
249
274
|
|
|
@@ -392,16 +417,16 @@ export function insertEncryptedValues<TAbi extends Abi, TFunctionName extends st
|
|
|
392
417
|
args: CofheInputArgsPreTransform<TAbi, TFunctionName>,
|
|
393
418
|
encryptedResult: readonly `0x${string}`[]
|
|
394
419
|
): CofheInputArgs<TAbi, TFunctionName> {
|
|
395
|
-
|
|
420
|
+
if (!Array.isArray(args)) {
|
|
421
|
+
throw new Error('Arguments must be an array');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const abiFunction = getInputFunction(abi, functionName, args);
|
|
396
425
|
const inputs = abiFunction?.inputs;
|
|
397
426
|
if (abiFunction == null || inputs == null) {
|
|
398
427
|
throw new Error(`Function ${functionName} not found in ABI`);
|
|
399
428
|
}
|
|
400
429
|
|
|
401
|
-
if (!Array.isArray(args)) {
|
|
402
|
-
throw new Error('Arguments must be an array');
|
|
403
|
-
}
|
|
404
|
-
|
|
405
430
|
const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
|
|
406
431
|
const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
|
|
407
432
|
|