import { utils as ethersUtils } from 'ethers' ; import { Abi , AppMethod } from '../types' ; import { ErrorInvalid } from '../errors' ; import App from '../entities/App' ; export const apmAppId = ( appName ) : string => ethersUtils . namehash ( `${ appName }.aragonpm.eth` ) ; function signatureFromAbi ( signature , abi ) { const matches = signature . match ( /(.*)\((.*)\)/m ) ; if ( ! matches ) { throw new ErrorInvalid ( `Abi has no method with signature: ${ signature }` ) ; } const name = matches [ 1 ] ; const params = matches [ 2 ] . split ( ',' ) ; const functionAbis = abi . filter ( ( node ) => node . name === name ) . filter ( ( node ) => node . inputs . length === params . length ) ; if ( functionAbis . length === 1 ) { return `${ functionAbis [ 0 ] . name }(${ functionAbis [ 0 ] . inputs . map ( ( input ) => input . type ) . join ( ',' ) })` ; } return signature ; } function findAppMethod ( app , methodTestFn , { allowDeprecated = true } = { } ) { const { deprecatedFunctions , functions } = app . artifact || { } ; let method ; if ( Array . isArray ( functions ) ) { method = functions . map ( ( f ) => { return { ... f , sig : signatureFromAbi ( f . sig , app . abi ) } ; } ) . find ( methodTestFn ) ; } if ( ! method && allowDeprecated ) { const deprecatedFunctionsFromVersions = Object . values ( deprecatedFunctions || { } ) ; if ( deprecatedFunctionsFromVersions . every ( Array . isArray ) ) { method = deprecatedFunctionsFromVersions . flat ( ) . find ( methodTestFn ) ; } } return method ; } param { Object } app param { Object } data param options param { boolean } options . allowDeprecated return { Object | void } export function findAppMethodFromData ( app , data , { allowDeprecated = true } = { } ) { const methodId = data . substring ( 0 , 10 ) ; return findAppMethod ( app , ( method ) => ethersUtils . id ( method . sig ) . substring ( 0 , 10 ) === methodId , { allowDeprecated } ) ; } param { Object } app param { string } methodSignature param options param { boolean } options . allowDeprecated return { Object | void } export function findAppMethodFromSignature ( app , methodSignature , { allowDeprecated = true } = { } ) { const fullMethodSignature = Boolean ( methodSignature ) && methodSignature . includes ( '(' ) && methodSignature . includes ( ')' ) ; return findAppMethod ( app , ( method ) => { if ( fullMethodSignature ) { return method . sig === methodSignature ; } const methodName = method . sig . split ( '(' ) [ 0 ] ; return methodName === methodSignature ; } , { allowDeprecated } ) ; }