UNPKG

@aeternity/aepp-calldata

Version:
146 lines (112 loc) 3.78 kB
import TypeResolver from './TypeResolver.js' import TypeResolveError from './Errors/TypeResolveError.js' import {FateTypeEvent} from './FateTypes.js' const isObject = (value) => { return value && typeof value === 'object' && value.constructor === Object } const isOption = ({type}) => { let key = type let _ if (isObject(key)) { [[key, _]] = Object.entries(key) } return key === 'option' } class AciTypeResolver extends TypeResolver { constructor(aci) { super() this.aci = aci } getCallTypes(contract, funName) { const funcAci = this.getNamespaceAci(contract).functions.find(e => e.name === funName) if (funcAci) { const types = funcAci.arguments.map(e => this.resolveType(e.type)) const options = funcAci.arguments.filter(isOption) return { types, required: types.length - options.length, } } if (funName === 'init') { return {types: [], required: 0} } throw new TypeResolveError(`Unknown function ${funName}`) } getReturnType(contract, funName) { if (funName === 'init') { return this.resolveType('void') } const funcAci = this.getNamespaceAci(contract).functions.find(e => e.name === funName) if (!funcAci) { throw new TypeResolveError(`Unknown function ${funName}`) } return this.resolveType(funcAci.returns) } getEventType(contract, topics) { const aci = this.getNamespaceAci(contract) if (!aci.hasOwnProperty('event')) { throw new TypeResolveError('Missing event declaration') } return FateTypeEvent(this.resolveType(aci.event), topics) } isCustomType(type) { if (typeof type !== 'string') { return false } if (this.isStdType(type)) { return false } const [namespace, _localType] = type.split('.') const namespaceData = this.getNamespaceAci(namespace) return !!namespaceData } isStdType(type) { if (type === 'Set.set') { return true } return false } getNamespaceAci(name) { for (const e of this.aci) { const [[_type, data]] = Object.entries(e) if (data.name === name) { return data } } return null } resolveTypeDef(type, params = []) { const [namespace, localType] = type.split('.') const namespaceData = this.getNamespaceAci(namespace) // not a custom type if (!namespaceData) { throw new TypeResolveError('Unknown namespace for ' + JSON.stringify(type)) } if (namespaceData.name === type) { return ['contract_pubkey', []] } const def = [ /** * @deprecated use ACIs generated by aesophia@^7.1.0 * TODO remove `type_defs` in next major release */ ...namespaceData.typedefs || namespaceData.type_defs, ...namespaceData.state ? [{ name: 'state', typedef: namespaceData.state, vars: [] }] : [] ].find(e => e.name === localType) if (!def) { throw new TypeResolveError('Unknown type definition: ' + JSON.stringify(type)) } const vars = {} def.vars.forEach((e, i) => { const [[_, k]] = Object.entries(e) vars[k] = params[i] }) const typeDef = vars.hasOwnProperty(def.typedef) ? vars[def.typedef] : def.typedef return [typeDef, vars] } } export default AciTypeResolver