@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/CHANGELOG.md +29 -0
- package/README.md +36 -25
- package/dist/index.cjs +93 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -17
- package/dist/index.d.ts +48 -17
- package/dist/index.js +93 -54
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/encryptedInputs.ts +234 -234
- package/src/fhenixMap.ts +16 -15
- package/src/mockEncrypt.ts +19 -21
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
153
|
-
type EncryptedInputsToInputs<T> = T extends
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
174
|
-
* the
|
|
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
|
|
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>,
|
|
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 {
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
153
|
-
type EncryptedInputsToInputs<T> = T extends
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
174
|
-
* the
|
|
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
|
|
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>,
|
|
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
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
30
|
+
var EXTERNAL_INPUT_INTERNAL_TYPES = [
|
|
31
|
+
"externalEbool",
|
|
32
|
+
"externalEuint8",
|
|
33
|
+
"externalEuint16",
|
|
34
|
+
"externalEuint32",
|
|
35
|
+
"externalEuint64",
|
|
36
|
+
"externalEuint128",
|
|
37
|
+
"externalEaddress"
|
|
38
38
|
];
|
|
39
|
-
function
|
|
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 "
|
|
52
|
+
case "externalEbool":
|
|
42
53
|
return Encryptable.bool(data);
|
|
43
|
-
case "
|
|
54
|
+
case "externalEuint8":
|
|
44
55
|
return Encryptable.uint8(data);
|
|
45
|
-
case "
|
|
56
|
+
case "externalEuint16":
|
|
46
57
|
return Encryptable.uint16(data);
|
|
47
|
-
case "
|
|
58
|
+
case "externalEuint32":
|
|
48
59
|
return Encryptable.uint32(data);
|
|
49
|
-
case "
|
|
60
|
+
case "externalEuint64":
|
|
50
61
|
return Encryptable.uint64(data);
|
|
51
|
-
case "
|
|
62
|
+
case "externalEuint128":
|
|
52
63
|
return Encryptable.uint128(data);
|
|
53
|
-
case "
|
|
64
|
+
case "externalEaddress":
|
|
54
65
|
return Encryptable.address(data);
|
|
55
66
|
default:
|
|
56
|
-
throw new Error(`Unknown
|
|
67
|
+
throw new Error(`Unknown external input type: ${internalType}`);
|
|
57
68
|
}
|
|
58
69
|
}
|
|
59
|
-
function
|
|
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) =>
|
|
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 (
|
|
85
|
-
|
|
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 (
|
|
90
|
-
const encryptables =
|
|
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"
|
|
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
|
-
|
|
115
|
+
if (index === signatureSlotIndex) return;
|
|
116
|
+
const arg = args[argIndex];
|
|
106
117
|
if (arg == null) {
|
|
107
|
-
throw new Error(`Argument ${
|
|
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
|
|
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
|
-
|
|
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
|
|
126
|
-
if (
|
|
127
|
-
if (
|
|
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
|
|
133
|
-
|
|
134
|
-
return
|
|
168
|
+
const hash = hashes[hashIndex];
|
|
169
|
+
hashIndex++;
|
|
170
|
+
return hash;
|
|
135
171
|
}
|
|
136
|
-
if (
|
|
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 (
|
|
177
|
+
if (hashIndex + arrayLength > hashes.length) {
|
|
142
178
|
throw new Error(
|
|
143
|
-
`Not enough encrypted
|
|
179
|
+
`Not enough encrypted hashes: expected at least ${hashIndex + arrayLength}, got ${hashes.length}`
|
|
144
180
|
);
|
|
145
181
|
}
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
return
|
|
182
|
+
const hashArray = hashes.slice(hashIndex, hashIndex + arrayLength);
|
|
183
|
+
hashIndex += arrayLength;
|
|
184
|
+
return hashArray;
|
|
149
185
|
}
|
|
150
|
-
if (typeHead === "tuple"
|
|
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
|
-
|
|
207
|
+
if (index === signatureSlotIndex) {
|
|
208
|
+
return signature;
|
|
209
|
+
}
|
|
210
|
+
const arg = args[argIndex];
|
|
171
211
|
if (arg == null) {
|
|
172
|
-
throw new Error(`Argument ${
|
|
212
|
+
throw new Error(`Argument ${argIndex} is undefined`);
|
|
173
213
|
}
|
|
214
|
+
argIndex++;
|
|
174
215
|
return processParameter(input, arg);
|
|
175
216
|
});
|
|
176
|
-
if (
|
|
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
|
}
|