github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/js/src/solts/lib/decoder.ts (about) 1 import ts, { factory, VariableStatement } from 'typescript'; 2 import { callDecodeEventLog, callDecodeFunctionResult, Provider } from './provider'; 3 import { ContractMethodsList, inputOuputsToType, InputOutput, Method, Signature } from './solidity'; 4 import { asConst, createParameter, declareConstant, MaybeUint8ArrayType, Uint8ArrayType } from './syntax'; 5 6 export const decodeName = factory.createIdentifier('decode'); 7 const clientName = factory.createIdentifier('client'); 8 const dataName = factory.createIdentifier('data'); 9 const topicsName = factory.createIdentifier('topics'); 10 11 export function generateDecodeObject( 12 methods: ContractMethodsList, 13 provider: Provider, 14 abiName: ts.Identifier, 15 ): ts.VariableStatement { 16 return generateDecoderObject(methods, provider, abiName, (method) => { 17 const decodeFunction = (signature: Signature) => { 18 const isFunction = method.type === 'function'; 19 const inputsOrOutputs = isFunction ? signature.outputs : signature.inputs; 20 return factory.createArrowFunction( 21 undefined, 22 undefined, 23 [], 24 inputOuputsToType(inputsOrOutputs), 25 undefined, 26 body( 27 isFunction 28 ? callDecodeFunctionResult(signature.hash, dataName) 29 : callDecodeEventLog(signature.hash, dataName, topicsName), 30 inputsOrOutputs, 31 ), 32 ); 33 }; 34 if (method.signatures.length === 1) { 35 return decodeFunction(method.signatures[0]); 36 } 37 return asConst(factory.createArrayLiteralExpression(method.signatures.map(decodeFunction))); 38 }); 39 } 40 41 function generateDecoderObject( 42 methods: ContractMethodsList, 43 provider: Provider, 44 abiName: ts.Identifier, 45 functionMaker: (m: Method) => ts.Expression, 46 ): ts.VariableStatement { 47 return declareConstant( 48 decodeName, 49 factory.createArrowFunction( 50 undefined, 51 undefined, 52 [ 53 createParameter(clientName, provider.type()), 54 createParameter(dataName, MaybeUint8ArrayType), 55 createParameter( 56 topicsName, 57 factory.createArrayTypeNode(Uint8ArrayType), 58 factory.createArrayLiteralExpression(), 59 ), 60 ], 61 undefined, 62 undefined, 63 factory.createBlock([ 64 provider.declareContractCodec(clientName, abiName), 65 factory.createReturnStatement( 66 factory.createObjectLiteralExpression( 67 methods.map((method) => { 68 return factory.createPropertyAssignment(method.name, functionMaker(method)); 69 }, true), 70 true, 71 ), 72 ), 73 ]), 74 ), 75 true, 76 ); 77 } 78 79 function body(decodeFn: ts.CallExpression, ios?: InputOutput[]): ts.Block { 80 let named = []; 81 if (ios && ios[0] !== undefined) { 82 named = ios.filter((out) => out.name !== ''); 83 } 84 85 if (ios?.length && ios.length === named.length) { 86 const setter = factory.createVariableStatement( 87 [], 88 factory.createVariableDeclarationList( 89 [ 90 factory.createVariableDeclaration( 91 factory.createArrayBindingPattern( 92 ios.map((out) => factory.createBindingElement(undefined, undefined, out.name)), 93 ), 94 undefined, 95 undefined, 96 decodeFn, 97 ), 98 ], 99 ts.NodeFlags.Const, 100 ), 101 ); 102 103 return factory.createBlock( 104 [ 105 setter, 106 factory.createReturnStatement( 107 factory.createObjectLiteralExpression( 108 ios.map(({ name }) => factory.createPropertyAssignment(name, factory.createIdentifier(name))), 109 ), 110 ), 111 ], 112 true, 113 ); 114 } else { 115 return factory.createBlock([factory.createReturnStatement(ios?.length ? decodeFn : undefined)]); 116 } 117 }