ox
Version:
Ethereum Standard Library
137 lines (132 loc) • 4.34 kB
text/typescript
import type {
Abi,
AbiConstructor,
AbiError,
AbiEvent,
AbiEventParameter,
AbiFallback,
AbiFunction,
AbiParameter,
AbiReceive,
AbiStateMutability,
} from 'abitype'
import {
type FormatAbiParameters as FormatAbiParameters_,
formatAbiParameters,
} from './formatAbiParameters.js'
import type { AssertName } from './types/signatures.js'
/**
* Formats ABI item (e.g. error, event, function) into human-readable ABI item
*
* @param abiItem - ABI item
* @returns Human-readable ABI item
*/
export type FormatAbiItem<abiItem extends Abi[number]> =
Abi[number] extends abiItem
? string
:
| (abiItem extends AbiFunction
? AbiFunction extends abiItem
? string
: `function ${AssertName<abiItem['name']>}(${FormatAbiParameters<
abiItem['inputs']
>})${abiItem['stateMutability'] extends Exclude<
AbiStateMutability,
'nonpayable'
>
? ` ${abiItem['stateMutability']}`
: ''}${abiItem['outputs']['length'] extends 0
? ''
: ` returns (${FormatAbiParameters<abiItem['outputs']>})`}`
: never)
| (abiItem extends AbiEvent
? AbiEvent extends abiItem
? string
: `event ${AssertName<abiItem['name']>}(${FormatAbiParameters<
abiItem['inputs']
>})`
: never)
| (abiItem extends AbiError
? AbiError extends abiItem
? string
: `error ${AssertName<abiItem['name']>}(${FormatAbiParameters<
abiItem['inputs']
>})`
: never)
| (abiItem extends AbiConstructor
? AbiConstructor extends abiItem
? string
: `constructor(${FormatAbiParameters<
abiItem['inputs']
>})${abiItem['stateMutability'] extends 'payable'
? ' payable'
: ''}`
: never)
| (abiItem extends AbiFallback
? AbiFallback extends abiItem
? string
: `fallback() external${abiItem['stateMutability'] extends 'payable'
? ' payable'
: ''}`
: never)
| (abiItem extends AbiReceive
? AbiReceive extends abiItem
? string
: 'receive() external payable'
: never)
type FormatAbiParameters<
abiParameters extends readonly (AbiParameter | AbiEventParameter)[],
> = abiParameters['length'] extends 0
? ''
: FormatAbiParameters_<
abiParameters extends readonly [
AbiParameter | AbiEventParameter,
...(readonly (AbiParameter | AbiEventParameter)[]),
]
? abiParameters
: never
>
/**
* Formats ABI item (e.g. error, event, function) into human-readable ABI item
*
* @param abiItem - ABI item
* @returns Human-readable ABI item
*/
export function formatAbiItem<const abiItem extends Abi[number]>(
abiItem: abiItem,
): FormatAbiItem<abiItem> {
type Result = FormatAbiItem<abiItem>
type Params = readonly [
AbiParameter | AbiEventParameter,
...(readonly (AbiParameter | AbiEventParameter)[]),
]
if (abiItem.type === 'function')
return `function ${abiItem.name}(${formatAbiParameters(
abiItem.inputs as Params,
)})${
abiItem.stateMutability && abiItem.stateMutability !== 'nonpayable'
? ` ${abiItem.stateMutability}`
: ''
}${
abiItem.outputs?.length
? ` returns (${formatAbiParameters(abiItem.outputs as Params)})`
: ''
}`
if (abiItem.type === 'event')
return `event ${abiItem.name}(${formatAbiParameters(
abiItem.inputs as Params,
)})`
if (abiItem.type === 'error')
return `error ${abiItem.name}(${formatAbiParameters(
abiItem.inputs as Params,
)})`
if (abiItem.type === 'constructor')
return `constructor(${formatAbiParameters(abiItem.inputs as Params)})${
abiItem.stateMutability === 'payable' ? ' payable' : ''
}`
if (abiItem.type === 'fallback')
return `fallback() external${
abiItem.stateMutability === 'payable' ? ' payable' : ''
}` as Result
return 'receive() external payable' as Result
}