ox
Version:
Ethereum Standard Library
60 lines (57 loc) • 2.14 kB
text/typescript
import type { Abi } from 'abitype'
import type { Error, Filter } from './types.js'
import { isStructSignature } from './runtime/signatures.js'
import { parseStructs } from './runtime/structs.js'
import { parseSignature } from './runtime/utils.js'
import type { Signatures } from './types/signatures.js'
import type { ParseStructs } from './types/structs.js'
import type { ParseSignature } from './types/utils.js'
/**
* Parses human-readable ABI into JSON `Abi`.
*
* @param signatures - Human-readable ABI
* @returns Parsed `Abi`.
*/
export type ParseAbi<signatures extends readonly string[]> =
string[] extends signatures
? Abi // If `T` was not able to be inferred (e.g. just `string[]`), return `Abi`
: signatures extends readonly string[]
? signatures extends Signatures<signatures> // Validate signatures
? ParseStructs<signatures> extends infer structs
? {
[key in keyof signatures]: signatures[key] extends string
? ParseSignature<signatures[key], structs>
: never
} extends infer mapped extends readonly unknown[]
? Filter<mapped, never> extends infer result
? result extends readonly []
? never
: result
: never
: never
: never
: never
: never
/**
* Parses human-readable ABI into JSON `Abi`.
*
* @param signatures - Human-Readable ABI
* @returns Parsed `Abi`.
*/
export function parseAbi<const signatures extends readonly string[]>(
signatures: signatures['length'] extends 0
? Error<'At least one signature required'>
: Signatures<signatures> extends signatures
? signatures
: Signatures<signatures>,
): ParseAbi<signatures> {
const structs = parseStructs(signatures as readonly string[])
const abi = []
const length = signatures.length as number
for (let i = 0; i < length; i++) {
const signature = (signatures as readonly string[])[i]!
if (isStructSignature(signature)) continue
abi.push(parseSignature(signature, structs))
}
return abi as unknown as ParseAbi<signatures>
}