@cofhe/abi 0.2.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 +13 -0
- package/README.md +184 -0
- package/package.json +54 -0
- package/src/encryptedInputs.ts +451 -0
- package/src/encryptedReturnTypes.ts +279 -0
- package/src/fhenixMap.ts +162 -0
- package/src/index.ts +6 -0
- package/src/mockEncrypt.ts +86 -0
- package/src/mockEncryptedInput.ts +139 -0
- package/src/utils.ts +205 -0
package/src/utils.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Abi,
|
|
3
|
+
AbiConstructor,
|
|
4
|
+
AbiError,
|
|
5
|
+
AbiEvent,
|
|
6
|
+
AbiFallback,
|
|
7
|
+
AbiFunction,
|
|
8
|
+
AbiParameter,
|
|
9
|
+
AbiParametersToPrimitiveTypes,
|
|
10
|
+
AbiReceive,
|
|
11
|
+
AbiType,
|
|
12
|
+
Address,
|
|
13
|
+
ExtractAbiFunction,
|
|
14
|
+
ResolvedRegister,
|
|
15
|
+
SolidityArray,
|
|
16
|
+
SolidityFixedArrayRange,
|
|
17
|
+
SolidityTuple,
|
|
18
|
+
} from 'abitype';
|
|
19
|
+
|
|
20
|
+
export type ContractReturnType<
|
|
21
|
+
abi extends Abi | readonly unknown[] = Abi,
|
|
22
|
+
functionName extends string = string,
|
|
23
|
+
args extends readonly unknown[] | undefined = readonly unknown[] | undefined,
|
|
24
|
+
///
|
|
25
|
+
abiFunction extends AbiFunction = (
|
|
26
|
+
abi extends Abi ? ExtractAbiFunction<abi, functionName> : AbiFunction
|
|
27
|
+
) extends infer abiFunction_ extends AbiFunction
|
|
28
|
+
? IsUnion<abiFunction_> extends true // narrow overloads by `args` by converting to tuple and filtering out overloads that don't match
|
|
29
|
+
? UnionToTuple<abiFunction_> extends infer abiFunctions extends readonly AbiFunction[]
|
|
30
|
+
? {
|
|
31
|
+
[K in keyof abiFunctions]: (
|
|
32
|
+
readonly unknown[] | undefined extends args // for functions that don't have inputs, `args` can be `undefined` so fallback to `readonly []`
|
|
33
|
+
? readonly []
|
|
34
|
+
: args
|
|
35
|
+
) extends AbiParametersToPrimitiveTypes<abiFunctions[K]['inputs'], 'inputs'>
|
|
36
|
+
? abiFunctions[K]
|
|
37
|
+
: never;
|
|
38
|
+
}[number] // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)
|
|
39
|
+
: never
|
|
40
|
+
: abiFunction_
|
|
41
|
+
: never,
|
|
42
|
+
outputs extends readonly AbiParameter[] = abiFunction['outputs'],
|
|
43
|
+
primitiveTypes extends readonly unknown[] = AbiParametersToPrimitiveTypes<outputs, 'outputs', true>,
|
|
44
|
+
> = [abiFunction] extends [never]
|
|
45
|
+
? unknown // `abiFunction` was not inferrable (e.g. `abi` declared as `Abi`)
|
|
46
|
+
: readonly unknown[] extends primitiveTypes
|
|
47
|
+
? unknown // `abiFunction` was not inferrable (e.g. `abi` not const-asserted)
|
|
48
|
+
: primitiveTypes extends readonly [] // unwrap `primitiveTypes`
|
|
49
|
+
? // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>
|
|
50
|
+
void // no outputs
|
|
51
|
+
: primitiveTypes extends readonly [infer primitiveType]
|
|
52
|
+
? primitiveType // single output
|
|
53
|
+
: primitiveTypes;
|
|
54
|
+
|
|
55
|
+
export type Error<messages extends string | string[]> = messages extends string
|
|
56
|
+
? [
|
|
57
|
+
// Surrounding with array to prevent `messages` from being widened to `string`
|
|
58
|
+
`Error: ${messages}`,
|
|
59
|
+
]
|
|
60
|
+
: {
|
|
61
|
+
[key in keyof messages]: messages[key] extends infer message extends string ? `Error: ${message}` : never;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type PartialBy<TType, TKeys extends keyof TType> = ExactPartial<Pick<TType, TKeys>> & Omit<TType, TKeys>;
|
|
65
|
+
type ExactPartial<T> = { [K in keyof T]?: T[K] | undefined };
|
|
66
|
+
|
|
67
|
+
export type MaybePartialBy<TType, TKeys extends string> = TKeys extends keyof TType ? PartialBy<TType, TKeys> : TType;
|
|
68
|
+
|
|
69
|
+
export type ReadonlyWiden<TType> =
|
|
70
|
+
| (TType extends Function ? TType : never)
|
|
71
|
+
| (TType extends ResolvedRegister['bigIntType'] ? bigint : never)
|
|
72
|
+
| (TType extends boolean ? boolean : never)
|
|
73
|
+
| (TType extends ResolvedRegister['intType'] ? number : never)
|
|
74
|
+
| (TType extends string
|
|
75
|
+
? TType extends Address
|
|
76
|
+
? Address
|
|
77
|
+
: TType extends ResolvedRegister['bytesType']['inputs']
|
|
78
|
+
? ResolvedRegister['bytesType']
|
|
79
|
+
: string
|
|
80
|
+
: never)
|
|
81
|
+
| (TType extends readonly [] ? readonly [] : never)
|
|
82
|
+
| (TType extends Record<string, unknown> ? { [K in keyof TType]: ReadonlyWiden<TType[K]> } : never)
|
|
83
|
+
| (TType extends { length: number }
|
|
84
|
+
? {
|
|
85
|
+
[K in keyof TType]: ReadonlyWiden<TType[K]>;
|
|
86
|
+
} extends infer Val extends unknown[]
|
|
87
|
+
? readonly [...Val]
|
|
88
|
+
: never
|
|
89
|
+
: never);
|
|
90
|
+
|
|
91
|
+
export type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* First, infer `Head` against a known size type (either fixed-length array value or `""`).
|
|
95
|
+
*
|
|
96
|
+
* | Input | Head |
|
|
97
|
+
* | --------------- | ------------ |
|
|
98
|
+
* | `string[]` | `string` |
|
|
99
|
+
* | `string[][][3]` | `string[][]` |
|
|
100
|
+
*/
|
|
101
|
+
export type MaybeExtractArrayParameterType<type> = type extends `${infer head}[${'' | `${SolidityFixedArrayRange}`}]`
|
|
102
|
+
? // * Then, infer in the opposite direction, using the known `head` to infer the exact `size` value.
|
|
103
|
+
// *
|
|
104
|
+
// * | Input | Size |
|
|
105
|
+
// * | ------------ | ---- |
|
|
106
|
+
// * | `${head}[]` | `""` |
|
|
107
|
+
// * | `${head}[3]` | `3` |
|
|
108
|
+
// */
|
|
109
|
+
type extends `${head}[${infer size}]`
|
|
110
|
+
? [head, size]
|
|
111
|
+
: undefined
|
|
112
|
+
: undefined;
|
|
113
|
+
|
|
114
|
+
export type IsUnion<T, C = T> = T extends C ? ([C] extends [T] ? false : true) : never;
|
|
115
|
+
export type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never]
|
|
116
|
+
? []
|
|
117
|
+
: [...UnionToTuple<Exclude<U, Last>>, Last];
|
|
118
|
+
type LastInUnion<U> =
|
|
119
|
+
UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;
|
|
120
|
+
type UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Create tuple of {@link type} type with {@link size} size
|
|
124
|
+
*
|
|
125
|
+
* @param Type - Type of tuple
|
|
126
|
+
* @param Size - Size of tuple
|
|
127
|
+
* @returns Tuple of {@link type} type with {@link size} size
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* type Result = Tuple<string, 2>
|
|
131
|
+
* // ^? type Result = [string, string]
|
|
132
|
+
*/
|
|
133
|
+
// https://github.com/Microsoft/TypeScript/issues/26223#issuecomment-674500430
|
|
134
|
+
export type Tuple<type, size extends number> = size extends size
|
|
135
|
+
? number extends size
|
|
136
|
+
? type[]
|
|
137
|
+
: _TupleOf<type, size, []>
|
|
138
|
+
: never;
|
|
139
|
+
type _TupleOf<length, size extends number, acc extends readonly unknown[]> = acc['length'] extends size
|
|
140
|
+
? acc
|
|
141
|
+
: _TupleOf<length, size, readonly [length, ...acc]>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Merges two object types into new type
|
|
145
|
+
*
|
|
146
|
+
* @param object1 - Object to merge into
|
|
147
|
+
* @param object2 - Object to merge and override keys from {@link object1}
|
|
148
|
+
* @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.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* type Result = Merge<{ foo: string }, { foo: number; bar: string }>
|
|
152
|
+
* // ^? type Result = { foo: number; bar: string }
|
|
153
|
+
*/
|
|
154
|
+
export type Merge<object1, object2> = Omit<object1, keyof object2> & object2;
|
|
155
|
+
|
|
156
|
+
// FUNCTIONS
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Extracts array parameter type information from a type string.
|
|
160
|
+
* Always returns a tuple, with undefined for non-array types.
|
|
161
|
+
*
|
|
162
|
+
* @param type - Type string like "tuple", "tuple[]", or "tuple[2]"
|
|
163
|
+
* @returns [head, size] where:
|
|
164
|
+
* - head is the base type
|
|
165
|
+
* - size is undefined for non-arrays, "" for dynamic arrays, or the number as a string for fixed arrays
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* extractArrayParameterType("tuple") // ["tuple", undefined]
|
|
169
|
+
* extractArrayParameterType("tuple[]") // ["tuple", ""]
|
|
170
|
+
* extractArrayParameterType("tuple[2]") // ["tuple", "2"]
|
|
171
|
+
*/
|
|
172
|
+
export function extractArrayParameterType<T extends string | undefined>(type: T): [T, string | undefined] {
|
|
173
|
+
if (type == null) return [type, undefined];
|
|
174
|
+
|
|
175
|
+
const match = type.match(/^(.+)\[(\d*)\]$/);
|
|
176
|
+
|
|
177
|
+
if (!match) {
|
|
178
|
+
// Not an array type, return [type, undefined]
|
|
179
|
+
return [type, undefined];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const head = match[1];
|
|
183
|
+
const size = match[2]; // Empty string for dynamic arrays, or digits for fixed arrays
|
|
184
|
+
|
|
185
|
+
// Return empty string for dynamic arrays, or the size string for fixed arrays
|
|
186
|
+
return [head as T, size === '' ? '' : size];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
type AbiItem = AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive;
|
|
190
|
+
|
|
191
|
+
export function isAbiFunction(item: AbiItem | unknown): item is AbiFunction {
|
|
192
|
+
if (typeof item !== 'object' || item === null) return false;
|
|
193
|
+
return 'type' in item && item.type === 'function' && 'name' in item && 'outputs' in item;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function getAbiFunction<TAbi extends Abi | readonly unknown[], TFunctionName extends string>(
|
|
197
|
+
abi: TAbi,
|
|
198
|
+
functionName: TFunctionName
|
|
199
|
+
): AbiFunction | undefined {
|
|
200
|
+
return abi.find((item) => {
|
|
201
|
+
const isFunction = isAbiFunction(item);
|
|
202
|
+
if (!isFunction) return false;
|
|
203
|
+
return item.name === functionName;
|
|
204
|
+
}) as AbiFunction | undefined;
|
|
205
|
+
}
|