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  }