@cofhe/abi 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { EncryptedBoolInput, EncryptedUint8Input, EncryptedUint16Input, EncryptedUint32Input, EncryptedUint64Input, EncryptedUint128Input, EncryptedAddressInput, FheTypes, Primitive, LiteralToPrimitive, EncryptedItemInput, EncryptableBool, EncryptableUint8, EncryptableUint16, EncryptableUint32, EncryptableUint64, EncryptableUint128, EncryptableAddress, EncryptableItem } from '@cofhe/sdk';
1
+ import { ExternalBoolHash, ExternalUint8Hash, ExternalUint16Hash, ExternalUint32Hash, ExternalUint64Hash, ExternalUint128Hash, ExternalAddressHash, FheTypes, AnyExternalHash, EncryptableBool, EncryptableUint8, EncryptableUint16, EncryptableUint32, EncryptableUint64, EncryptableUint128, EncryptableAddress, Primitive, LiteralToPrimitive, EncryptableItem } from '@cofhe/sdk';
2
2
  import { Abi, AbiFunction, ExtractAbiFunction, AbiParametersToPrimitiveTypes, AbiParameter, AbiType, SolidityTuple, SolidityArray, SolidityFixedArrayRange, ResolvedRegister, Address, AbiParameterKind, AbiTypeToPrimitiveType, SolidityFixedArraySizeLookup } from 'abitype';
3
3
  export { Abi } from 'abitype';
4
4
 
@@ -101,13 +101,13 @@ type EncryptedReturnTypeByUtype<U extends FheTypes> = Extract<EncryptedReturnTyp
101
101
  utype: U;
102
102
  }>;
103
103
  type FhenixInternalTypeMap = {
104
- 'struct InEbool': EncryptedBoolInput;
105
- 'struct InEuint8': EncryptedUint8Input;
106
- 'struct InEuint16': EncryptedUint16Input;
107
- 'struct InEuint32': EncryptedUint32Input;
108
- 'struct InEuint64': EncryptedUint64Input;
109
- 'struct InEuint128': EncryptedUint128Input;
110
- 'struct InEaddress': EncryptedAddressInput;
104
+ externalEbool: ExternalBoolHash;
105
+ externalEuint8: ExternalUint8Hash;
106
+ externalEuint16: ExternalUint16Hash;
107
+ externalEuint32: ExternalUint32Hash;
108
+ externalEuint64: ExternalUint64Hash;
109
+ externalEuint128: ExternalUint128Hash;
110
+ externalEaddress: ExternalAddressHash;
111
111
  ebool: EBool;
112
112
  euint8: EUint8;
113
113
  euint16: EUint16;
@@ -149,11 +149,40 @@ type CofheAbiArrayToPrimitiveType<abiParameter extends AbiParameter | {
149
149
  }>, abiParameterKind>[];
150
150
 
151
151
  type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<abi, functionName>['args'];
152
- type EncryptedInputToInputMap<E extends EncryptedItemInput> = E extends EncryptedBoolInput ? EncryptableBool['data'] : E extends EncryptedUint8Input ? EncryptableUint8['data'] : E extends EncryptedUint16Input ? EncryptableUint16['data'] : E extends EncryptedUint32Input ? EncryptableUint32['data'] : E extends EncryptedUint64Input ? EncryptableUint64['data'] : E extends EncryptedUint128Input ? EncryptableUint128['data'] : E extends EncryptedAddressInput ? EncryptableAddress['data'] : never;
153
- type EncryptedInputsToInputs<T> = T extends Primitive ? LiteralToPrimitive<T> : T extends EncryptedItemInput ? EncryptedInputToInputMap<T> : {
152
+ type ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash ? EncryptableBool['data'] : E extends ExternalUint8Hash ? EncryptableUint8['data'] : E extends ExternalUint16Hash ? EncryptableUint16['data'] : E extends ExternalUint32Hash ? EncryptableUint32['data'] : E extends ExternalUint64Hash ? EncryptableUint64['data'] : E extends ExternalUint128Hash ? EncryptableUint128['data'] : E extends ExternalAddressHash ? EncryptableAddress['data'] : never;
153
+ type EncryptedInputsToInputs<T> = T extends AnyExternalHash ? ExternalHashToInputMap<T> : T extends Primitive ? LiteralToPrimitive<T> : {
154
154
  [K in keyof T]: EncryptedInputsToInputs<T[K]>;
155
155
  };
156
- type CofheInputArgsPreTransform<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = EncryptedInputsToInputs<CofheInputArgs<abi, functionName>>;
156
+ /**
157
+ * Drops the batch-signature argument from an args tuple.
158
+ *
159
+ * The signature slot is the first non-`external*` parameter that follows the contiguous run of
160
+ * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the
161
+ * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters
162
+ * and the args tuple in lockstep and elides the arg at that position.
163
+ */
164
+ type DropSignatureSlotTuple<params extends readonly unknown[], args extends readonly unknown[], afterExternalRun extends boolean = false> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]] ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]] ? P extends AbiParameter ? ParamHasExternalInput<P> extends true ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>] : afterExternalRun extends true ? DropSignatureSlotTuple<PRest, ARest, false> : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>] : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>] : readonly [] : args;
165
+ /** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */
166
+ type DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[] ? DropSignatureSlotTuple<params, args> : args;
167
+ declare const EXTERNAL_INPUT_INTERNAL_TYPES: readonly ["externalEbool", "externalEuint8", "externalEuint16", "externalEuint32", "externalEuint64", "externalEuint128", "externalEaddress"];
168
+ type ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];
169
+ /** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */
170
+ type ParamHasExternalInput<param extends AbiParameter> = MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any] ? head extends ExternalInputInternalType ? true : false : param['internalType'] extends ExternalInputInternalType ? true : param extends {
171
+ type: 'tuple';
172
+ components: infer components extends readonly AbiParameter[];
173
+ } ? ParamsHaveExternalInput<components> : false;
174
+ type ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [
175
+ infer Head extends AbiParameter,
176
+ ...infer Rest extends readonly AbiParameter[]
177
+ ] ? ParamHasExternalInput<Head> extends true ? true : ParamsHaveExternalInput<Rest> : false;
178
+ /**
179
+ * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.
180
+ *
181
+ * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter
182
+ * immediately following them is the shared batch signature slot - the caller never supplies it
183
+ * directly (the SDK injects it after encryption), so it's dropped from this type entirely.
184
+ */
185
+ type CofheInputArgsPreTransform<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string, abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction> = EncryptedInputsToInputs<ParamsHaveExternalInput<abiFunction['inputs']> extends true ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>> : CofheInputArgs<abi, functionName>>;
157
186
  type GetArgs<abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types
158
187
  functionName extends string = string, args extends readonly unknown[] | undefined = readonly [], abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction, primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>, args_ = primitiveTypes | (abi extends Abi ? args extends primitiveTypes ? primitiveTypes extends args ? ReadonlyWiden<args> : never : never : never) | (Abi extends abi ? readonly unknown[] : never)> = MaybePartialBy<{
159
188
  args: args_;
@@ -164,14 +193,16 @@ functionName extends string = string, args extends readonly unknown[] | undefine
164
193
  *
165
194
  * @param abi - The ABI containing the function definition
166
195
  * @param functionName - Name of the function
167
- * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values)
168
- * @returns Array of EncryptableItem objects ready for encryption
196
+ * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;
197
+ * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)
198
+ * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order
169
199
  */
170
200
  declare function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>): EncryptableItem[];
171
201
  /**
172
202
  * Re-inserts encrypted values back into function arguments based on the ABI.
173
- * Takes the extracted values (now encrypted) and the original args structure, and replaces
174
- * the encryptable values with their encrypted counterparts.
203
+ * Takes the batch-verified result (per-input hashes, in order, followed by the single shared
204
+ * signature) and the original args structure, and produces the final call args: each `external*`
205
+ * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.
175
206
  *
176
207
  * This function mirrors the extraction logic in extractEncryptableValues, ensuring values
177
208
  * are inserted in the exact same order and locations where they were extracted.
@@ -179,10 +210,10 @@ declare function extractEncryptableValues<TAbi extends Abi, TFunctionName extend
179
210
  * @param abi - The ABI containing the function definition
180
211
  * @param functionName - Name of the function
181
212
  * @param args - Original function arguments in the format of CofheInputArgsPreTransform
182
- * @param encryptedValues - Encrypted values in the same order as returned by extractEncryptableValues
213
+ * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`
183
214
  * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)
184
215
  */
185
- declare function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>, encryptedValues: readonly EncryptedItemInput[]): CofheInputArgs<TAbi, TFunctionName>;
216
+ declare function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>, encryptedResult: readonly `0x${string}`[]): CofheInputArgs<TAbi, TFunctionName>;
186
217
 
187
218
  type FirstCofheReturnValue<T> = [T] extends [void] ? never : T extends readonly [infer Head, ...(readonly unknown[])] ? Head : T;
188
219
  type FheTypeFromCofheReturnValue<T> = T extends {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EncryptedBoolInput, EncryptedUint8Input, EncryptedUint16Input, EncryptedUint32Input, EncryptedUint64Input, EncryptedUint128Input, EncryptedAddressInput, FheTypes, Primitive, LiteralToPrimitive, EncryptedItemInput, EncryptableBool, EncryptableUint8, EncryptableUint16, EncryptableUint32, EncryptableUint64, EncryptableUint128, EncryptableAddress, EncryptableItem } from '@cofhe/sdk';
1
+ import { ExternalBoolHash, ExternalUint8Hash, ExternalUint16Hash, ExternalUint32Hash, ExternalUint64Hash, ExternalUint128Hash, ExternalAddressHash, FheTypes, AnyExternalHash, EncryptableBool, EncryptableUint8, EncryptableUint16, EncryptableUint32, EncryptableUint64, EncryptableUint128, EncryptableAddress, Primitive, LiteralToPrimitive, EncryptableItem } from '@cofhe/sdk';
2
2
  import { Abi, AbiFunction, ExtractAbiFunction, AbiParametersToPrimitiveTypes, AbiParameter, AbiType, SolidityTuple, SolidityArray, SolidityFixedArrayRange, ResolvedRegister, Address, AbiParameterKind, AbiTypeToPrimitiveType, SolidityFixedArraySizeLookup } from 'abitype';
3
3
  export { Abi } from 'abitype';
4
4
 
@@ -101,13 +101,13 @@ type EncryptedReturnTypeByUtype<U extends FheTypes> = Extract<EncryptedReturnTyp
101
101
  utype: U;
102
102
  }>;
103
103
  type FhenixInternalTypeMap = {
104
- 'struct InEbool': EncryptedBoolInput;
105
- 'struct InEuint8': EncryptedUint8Input;
106
- 'struct InEuint16': EncryptedUint16Input;
107
- 'struct InEuint32': EncryptedUint32Input;
108
- 'struct InEuint64': EncryptedUint64Input;
109
- 'struct InEuint128': EncryptedUint128Input;
110
- 'struct InEaddress': EncryptedAddressInput;
104
+ externalEbool: ExternalBoolHash;
105
+ externalEuint8: ExternalUint8Hash;
106
+ externalEuint16: ExternalUint16Hash;
107
+ externalEuint32: ExternalUint32Hash;
108
+ externalEuint64: ExternalUint64Hash;
109
+ externalEuint128: ExternalUint128Hash;
110
+ externalEaddress: ExternalAddressHash;
111
111
  ebool: EBool;
112
112
  euint8: EUint8;
113
113
  euint16: EUint16;
@@ -149,11 +149,40 @@ type CofheAbiArrayToPrimitiveType<abiParameter extends AbiParameter | {
149
149
  }>, abiParameterKind>[];
150
150
 
151
151
  type CofheInputArgs<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = GetArgs<abi, functionName>['args'];
152
- type EncryptedInputToInputMap<E extends EncryptedItemInput> = E extends EncryptedBoolInput ? EncryptableBool['data'] : E extends EncryptedUint8Input ? EncryptableUint8['data'] : E extends EncryptedUint16Input ? EncryptableUint16['data'] : E extends EncryptedUint32Input ? EncryptableUint32['data'] : E extends EncryptedUint64Input ? EncryptableUint64['data'] : E extends EncryptedUint128Input ? EncryptableUint128['data'] : E extends EncryptedAddressInput ? EncryptableAddress['data'] : never;
153
- type EncryptedInputsToInputs<T> = T extends Primitive ? LiteralToPrimitive<T> : T extends EncryptedItemInput ? EncryptedInputToInputMap<T> : {
152
+ type ExternalHashToInputMap<E extends AnyExternalHash> = E extends ExternalBoolHash ? EncryptableBool['data'] : E extends ExternalUint8Hash ? EncryptableUint8['data'] : E extends ExternalUint16Hash ? EncryptableUint16['data'] : E extends ExternalUint32Hash ? EncryptableUint32['data'] : E extends ExternalUint64Hash ? EncryptableUint64['data'] : E extends ExternalUint128Hash ? EncryptableUint128['data'] : E extends ExternalAddressHash ? EncryptableAddress['data'] : never;
153
+ type EncryptedInputsToInputs<T> = T extends AnyExternalHash ? ExternalHashToInputMap<T> : T extends Primitive ? LiteralToPrimitive<T> : {
154
154
  [K in keyof T]: EncryptedInputsToInputs<T[K]>;
155
155
  };
156
- type CofheInputArgsPreTransform<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string> = EncryptedInputsToInputs<CofheInputArgs<abi, functionName>>;
156
+ /**
157
+ * Drops the batch-signature argument from an args tuple.
158
+ *
159
+ * The signature slot is the first non-`external*` parameter that follows the contiguous run of
160
+ * `external*` parameters - `FHE.asEuintXX(hash, proof)` is a pair, so the proof sits with the
161
+ * hashes it authenticates rather than at the end of the parameter list. Walks the ABI parameters
162
+ * and the args tuple in lockstep and elides the arg at that position.
163
+ */
164
+ type DropSignatureSlotTuple<params extends readonly unknown[], args extends readonly unknown[], afterExternalRun extends boolean = false> = params extends readonly [infer P, ...infer PRest extends readonly unknown[]] ? args extends readonly [infer A, ...infer ARest extends readonly unknown[]] ? P extends AbiParameter ? ParamHasExternalInput<P> extends true ? readonly [A, ...DropSignatureSlotTuple<PRest, ARest, true>] : afterExternalRun extends true ? DropSignatureSlotTuple<PRest, ARest, false> : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, false>] : readonly [A, ...DropSignatureSlotTuple<PRest, ARest, afterExternalRun>] : readonly [] : args;
165
+ /** Non-tuple args (e.g. `undefined`) pass through unchanged, as the previous `DropLast` did. */
166
+ type DropSignatureSlot<params extends readonly unknown[], args> = args extends readonly unknown[] ? DropSignatureSlotTuple<params, args> : args;
167
+ declare const EXTERNAL_INPUT_INTERNAL_TYPES: readonly ["externalEbool", "externalEuint8", "externalEuint16", "externalEuint32", "externalEuint64", "externalEuint128", "externalEaddress"];
168
+ type ExternalInputInternalType = (typeof EXTERNAL_INPUT_INTERNAL_TYPES)[number];
169
+ /** Type-level: does this ABI parameter carry (or, if a tuple, recursively contain) an `external*` input? */
170
+ type ParamHasExternalInput<param extends AbiParameter> = MaybeExtractArrayParameterType<param['internalType']> extends [infer head extends string, any] ? head extends ExternalInputInternalType ? true : false : param['internalType'] extends ExternalInputInternalType ? true : param extends {
171
+ type: 'tuple';
172
+ components: infer components extends readonly AbiParameter[];
173
+ } ? ParamsHaveExternalInput<components> : false;
174
+ type ParamsHaveExternalInput<params extends readonly AbiParameter[]> = params extends readonly [
175
+ infer Head extends AbiParameter,
176
+ ...infer Rest extends readonly AbiParameter[]
177
+ ] ? ParamHasExternalInput<Head> extends true ? true : ParamsHaveExternalInput<Rest> : false;
178
+ /**
179
+ * Pre-transform args for a function ABI: the raw plain values a caller supplies before encryption.
180
+ *
181
+ * If the function has one or more `external*` (encrypted) inputs, the plain `bytes` parameter
182
+ * immediately following them is the shared batch signature slot - the caller never supplies it
183
+ * directly (the SDK injects it after encryption), so it's dropped from this type entirely.
184
+ */
185
+ type CofheInputArgsPreTransform<abi extends Abi | readonly unknown[] = Abi, functionName extends string = string, abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction> = EncryptedInputsToInputs<ParamsHaveExternalInput<abiFunction['inputs']> extends true ? DropSignatureSlot<abiFunction['inputs'], CofheInputArgs<abi, functionName>> : CofheInputArgs<abi, functionName>>;
157
186
  type GetArgs<abi extends Abi | readonly unknown[] = Abi, // `readonly unknown[]` allows for non-const asserted types
158
187
  functionName extends string = string, args extends readonly unknown[] | undefined = readonly [], abiFunction extends AbiFunction = abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction, primitiveTypes = CofheAbiParametersToPrimitiveTypes<abiFunction['inputs']>, args_ = primitiveTypes | (abi extends Abi ? args extends primitiveTypes ? primitiveTypes extends args ? ReadonlyWiden<args> : never : never : never) | (Abi extends abi ? readonly unknown[] : never)> = MaybePartialBy<{
159
188
  args: args_;
@@ -164,14 +193,16 @@ functionName extends string = string, args extends readonly unknown[] | undefine
164
193
  *
165
194
  * @param abi - The ABI containing the function definition
166
195
  * @param functionName - Name of the function
167
- * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values)
168
- * @returns Array of EncryptableItem objects ready for encryption
196
+ * @param args - Function arguments in the format of CofheInputArgsPreTransform (raw data values;
197
+ * if the function has `external*` inputs, the trailing batch-signature slot is NOT included)
198
+ * @returns Array of EncryptableItem objects ready for encryption, in ABI parameter order
169
199
  */
170
200
  declare function extractEncryptableValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>): EncryptableItem[];
171
201
  /**
172
202
  * Re-inserts encrypted values back into function arguments based on the ABI.
173
- * Takes the extracted values (now encrypted) and the original args structure, and replaces
174
- * the encryptable values with their encrypted counterparts.
203
+ * Takes the batch-verified result (per-input hashes, in order, followed by the single shared
204
+ * signature) and the original args structure, and produces the final call args: each `external*`
205
+ * position gets its corresponding hash, and the trailing `bytes` parameter gets the signature.
175
206
  *
176
207
  * This function mirrors the extraction logic in extractEncryptableValues, ensuring values
177
208
  * are inserted in the exact same order and locations where they were extracted.
@@ -179,10 +210,10 @@ declare function extractEncryptableValues<TAbi extends Abi, TFunctionName extend
179
210
  * @param abi - The ABI containing the function definition
180
211
  * @param functionName - Name of the function
181
212
  * @param args - Original function arguments in the format of CofheInputArgsPreTransform
182
- * @param encryptedValues - Encrypted values in the same order as returned by extractEncryptableValues
213
+ * @param encryptedResult - `[...hashes, signature]`, as returned by `EncryptInputsBuilder.execute()`
183
214
  * @returns Function arguments with encrypted values inserted (format of CofheInputArgs)
184
215
  */
185
- declare function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>, encryptedValues: readonly EncryptedItemInput[]): CofheInputArgs<TAbi, TFunctionName>;
216
+ declare function insertEncryptedValues<TAbi extends Abi, TFunctionName extends string>(abi: TAbi, functionName: TFunctionName, args: CofheInputArgsPreTransform<TAbi, TFunctionName>, encryptedResult: readonly `0x${string}`[]): CofheInputArgs<TAbi, TFunctionName>;
186
217
 
187
218
  type FirstCofheReturnValue<T> = [T] extends [void] ? never : T extends readonly [infer Head, ...(readonly unknown[])] ? Head : T;
188
219
  type FheTypeFromCofheReturnValue<T> = T extends {
package/dist/index.js CHANGED
@@ -27,46 +27,54 @@ function getAbiFunction(abi, functionName) {
27
27
  }
28
28
 
29
29
  // src/encryptedInputs.ts
30
- var ENCRYPTED_INPUT_INTERNAL_TYPES = [
31
- "struct InEbool",
32
- "struct InEuint8",
33
- "struct InEuint16",
34
- "struct InEuint32",
35
- "struct InEuint64",
36
- "struct InEuint128",
37
- "struct InEaddress"
30
+ var EXTERNAL_INPUT_INTERNAL_TYPES = [
31
+ "externalEbool",
32
+ "externalEuint8",
33
+ "externalEuint16",
34
+ "externalEuint32",
35
+ "externalEuint64",
36
+ "externalEuint128",
37
+ "externalEaddress"
38
38
  ];
39
- function transformSingleEncryptedInputToEncryptable(internalType, data) {
39
+ function internalTypeIsExternalInput(internalType) {
40
+ return EXTERNAL_INPUT_INTERNAL_TYPES.includes(internalType);
41
+ }
42
+ function paramHasExternalInput(param) {
43
+ const [internalTypeHead] = extractArrayParameterType(param.internalType);
44
+ if (internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) return true;
45
+ if ("components" in param && Array.isArray(param.components)) {
46
+ return param.components.some((component) => paramHasExternalInput(component));
47
+ }
48
+ return false;
49
+ }
50
+ function transformSingleExternalToEncryptable(internalType, data) {
40
51
  switch (internalType) {
41
- case "struct InEbool":
52
+ case "externalEbool":
42
53
  return Encryptable.bool(data);
43
- case "struct InEuint8":
54
+ case "externalEuint8":
44
55
  return Encryptable.uint8(data);
45
- case "struct InEuint16":
56
+ case "externalEuint16":
46
57
  return Encryptable.uint16(data);
47
- case "struct InEuint32":
58
+ case "externalEuint32":
48
59
  return Encryptable.uint32(data);
49
- case "struct InEuint64":
60
+ case "externalEuint64":
50
61
  return Encryptable.uint64(data);
51
- case "struct InEuint128":
62
+ case "externalEuint128":
52
63
  return Encryptable.uint128(data);
53
- case "struct InEaddress":
64
+ case "externalEaddress":
54
65
  return Encryptable.address(data);
55
66
  default:
56
- throw new Error(`Unknown encrypted input type: ${internalType}`);
67
+ throw new Error(`Unknown external input type: ${internalType}`);
57
68
  }
58
69
  }
59
- function transformArrayOfEncryptedInputsToEncryptables(internalType, size, data) {
70
+ function transformArrayOfExternalsToEncryptables(internalType, size, data) {
60
71
  if (!Array.isArray(data)) {
61
72
  throw new Error("Data must be an array");
62
73
  }
63
74
  if (size != null && size !== "" && parseInt(size) !== data.length) {
64
75
  throw new Error(`Array size mismatch: ${size} !== ${data.length}`);
65
76
  }
66
- return data.map((item) => transformSingleEncryptedInputToEncryptable(internalType, item));
67
- }
68
- function internalTypeIsEncryptedInput(internalType) {
69
- return ENCRYPTED_INPUT_INTERNAL_TYPES.includes(internalType);
77
+ return data.map((item) => transformSingleExternalToEncryptable(internalType, item));
70
78
  }
71
79
  function extractEncryptableValues(abi, functionName, args) {
72
80
  const abiFunction = getAbiFunction(abi, functionName);
@@ -77,21 +85,22 @@ function extractEncryptableValues(abi, functionName, args) {
77
85
  if (!Array.isArray(args)) {
78
86
  throw new Error("Arguments must be an array");
79
87
  }
88
+ const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
89
+ const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
80
90
  const encryptableItems = [];
81
91
  function processParameter(param, value) {
82
92
  const [typeHead, typeSize] = extractArrayParameterType(param.type);
83
93
  const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);
84
- if (typeHead === "tuple" && typeSize == null && internalTypeHead != null && internalTypeIsEncryptedInput(internalTypeHead)) {
85
- const encryptable = transformSingleEncryptedInputToEncryptable(internalTypeHead, value);
86
- encryptableItems.push(encryptable);
94
+ if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {
95
+ encryptableItems.push(transformSingleExternalToEncryptable(internalTypeHead, value));
87
96
  return;
88
97
  }
89
- if (typeHead === "tuple" && typeSize != null && internalTypeHead != null && internalTypeIsEncryptedInput(internalTypeHead)) {
90
- const encryptables = transformArrayOfEncryptedInputsToEncryptables(internalTypeHead, typeSize, value);
98
+ if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {
99
+ const encryptables = transformArrayOfExternalsToEncryptables(internalTypeHead, typeSize, value);
91
100
  encryptableItems.push(...encryptables);
92
101
  return;
93
102
  }
94
- if (typeHead === "tuple" && (internalTypeHead == null || !internalTypeIsEncryptedInput(internalTypeHead))) {
103
+ if (typeHead === "tuple") {
95
104
  if ("components" in param && Array.isArray(param.components)) {
96
105
  param.components.forEach((component) => {
97
106
  processParameter(component, value[component.name]);
@@ -101,16 +110,41 @@ function extractEncryptableValues(abi, functionName, args) {
101
110
  }
102
111
  return;
103
112
  }
113
+ let argIndex = 0;
104
114
  inputs.forEach((input, index) => {
105
- const arg = args[index];
115
+ if (index === signatureSlotIndex) return;
116
+ const arg = args[argIndex];
106
117
  if (arg == null) {
107
- throw new Error(`Argument ${index} is undefined`);
118
+ throw new Error(`Argument ${argIndex} is undefined`);
108
119
  }
120
+ argIndex++;
109
121
  processParameter(input, arg);
110
122
  });
111
123
  return encryptableItems;
112
124
  }
113
- function insertEncryptedValues(abi, functionName, args, encryptedValues) {
125
+ function findSignatureSlotIndex(inputs, hasExternalInputs, functionName) {
126
+ if (!hasExternalInputs) return -1;
127
+ const externalIndices = inputs.reduce((acc, input, index) => {
128
+ if (paramHasExternalInput(input)) acc.push(index);
129
+ return acc;
130
+ }, []);
131
+ const first = externalIndices[0];
132
+ const last = externalIndices[externalIndices.length - 1];
133
+ if (last - first + 1 !== externalIndices.length) {
134
+ throw new Error(
135
+ `Function ${functionName} has encrypted (external*) inputs at non-adjacent positions (${externalIndices.join(", ")}). They share one batch signature, so they must be contiguous with the 'bytes' signature parameter immediately after them`
136
+ );
137
+ }
138
+ const slotIndex = last + 1;
139
+ const slot = inputs[slotIndex];
140
+ if (slot?.type !== "bytes") {
141
+ throw new Error(
142
+ `Function ${functionName} has encrypted (external*) inputs, so the parameter immediately after them must be a plain 'bytes' parameter to receive the shared batch signature - found '${slot?.type ?? "nothing"}' at position ${slotIndex} instead`
143
+ );
144
+ }
145
+ return slotIndex;
146
+ }
147
+ function insertEncryptedValues(abi, functionName, args, encryptedResult) {
114
148
  const abiFunction = getAbiFunction(abi, functionName);
115
149
  const inputs = abiFunction?.inputs;
116
150
  if (abiFunction == null || inputs == null) {
@@ -119,35 +153,37 @@ function insertEncryptedValues(abi, functionName, args, encryptedValues) {
119
153
  if (!Array.isArray(args)) {
120
154
  throw new Error("Arguments must be an array");
121
155
  }
122
- let encryptedIndex = 0;
156
+ const hasExternalInputs = inputs.some((input) => paramHasExternalInput(input));
157
+ const signatureSlotIndex = findSignatureSlotIndex(inputs, hasExternalInputs, functionName);
158
+ const hashes = hasExternalInputs ? encryptedResult.slice(0, -1) : [];
159
+ const signature = hasExternalInputs ? encryptedResult[encryptedResult.length - 1] : void 0;
160
+ let hashIndex = 0;
123
161
  function processParameter(param, value) {
124
162
  const [typeHead, typeSize] = extractArrayParameterType(param.type);
125
- const [internalTypeHead, internalTypeSize] = extractArrayParameterType(param.internalType);
126
- if (typeHead === "tuple" && typeSize == null && internalTypeHead != null && internalTypeIsEncryptedInput(internalTypeHead)) {
127
- if (encryptedIndex >= encryptedValues.length) {
128
- throw new Error(
129
- `Not enough encrypted values: expected at least ${encryptedIndex + 1}, got ${encryptedValues.length}`
130
- );
163
+ const [internalTypeHead] = extractArrayParameterType(param.internalType);
164
+ if (typeSize == null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {
165
+ if (hashIndex >= hashes.length) {
166
+ throw new Error(`Not enough encrypted hashes: expected at least ${hashIndex + 1}, got ${hashes.length}`);
131
167
  }
132
- const encryptedValue = encryptedValues[encryptedIndex];
133
- encryptedIndex++;
134
- return encryptedValue;
168
+ const hash = hashes[hashIndex];
169
+ hashIndex++;
170
+ return hash;
135
171
  }
136
- if (typeHead === "tuple" && typeSize != null && internalTypeHead != null && internalTypeIsEncryptedInput(internalTypeHead)) {
172
+ if (typeSize != null && internalTypeHead != null && internalTypeIsExternalInput(internalTypeHead)) {
137
173
  const arrayLength = Array.isArray(value) ? value.length : 0;
138
174
  if (arrayLength === 0) {
139
175
  return [];
140
176
  }
141
- if (encryptedIndex + arrayLength > encryptedValues.length) {
177
+ if (hashIndex + arrayLength > hashes.length) {
142
178
  throw new Error(
143
- `Not enough encrypted values: expected at least ${encryptedIndex + arrayLength}, got ${encryptedValues.length}`
179
+ `Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`
144
180
  );
145
181
  }
146
- const encryptedArray = encryptedValues.slice(encryptedIndex, encryptedIndex + arrayLength);
147
- encryptedIndex += arrayLength;
148
- return encryptedArray;
182
+ const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);
183
+ hashIndex += arrayLength;
184
+ return hashArray;
149
185
  }
150
- if (typeHead === "tuple" && (internalTypeHead == null || !internalTypeIsEncryptedInput(internalTypeHead))) {
186
+ if (typeHead === "tuple") {
151
187
  if ("components" in param && Array.isArray(param.components)) {
152
188
  const valueObj = value;
153
189
  const result2 = {};
@@ -166,17 +202,20 @@ function insertEncryptedValues(abi, functionName, args, encryptedValues) {
166
202
  }
167
203
  return value;
168
204
  }
205
+ let argIndex = 0;
169
206
  const result = inputs.map((input, index) => {
170
- const arg = args[index];
207
+ if (index === signatureSlotIndex) {
208
+ return signature;
209
+ }
210
+ const arg = args[argIndex];
171
211
  if (arg == null) {
172
- throw new Error(`Argument ${index} is undefined`);
212
+ throw new Error(`Argument ${argIndex} is undefined`);
173
213
  }
214
+ argIndex++;
174
215
  return processParameter(input, arg);
175
216
  });
176
- if (encryptedIndex !== encryptedValues.length) {
177
- throw new Error(
178
- `Mismatch in encrypted values count: used ${encryptedIndex}, but provided ${encryptedValues.length}`
179
- );
217
+ if (hashIndex !== hashes.length) {
218
+ throw new Error(`Mismatch in encrypted hashes count: used ${hashIndex}, but provided ${hashes.length}`);
180
219
  }
181
220
  return result;
182
221
  }