github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/js/src/codec.ts (about) 1 import { EventFragment, Fragment, FunctionFragment, Interface } from '@ethersproject/abi'; 2 import { postDecodeResult, preEncodeResult, prefixedHexString, toBuffer } from './convert'; 3 4 export type ContractCodec = { 5 encodeDeploy(...args: unknown[]): Buffer; 6 encodeFunctionData(signature: string, ...args: unknown[]): Buffer; 7 decodeFunctionResult(signature: string, data: Uint8Array | undefined): any; 8 decodeEventLog(signature: string, data: Uint8Array | undefined, topics?: Uint8Array[]): any; 9 }; 10 11 export function getContractCodec(iface: Interface): ContractCodec { 12 return { 13 encodeDeploy(...args: unknown[]): Buffer { 14 const frag = iface.deploy; 15 try { 16 return toBuffer(iface.encodeDeploy(preEncodeResult(args, frag.inputs))); 17 } catch (err) { 18 throwErr(err, 'encode deploy', 'constructor', args, frag); 19 } 20 }, 21 22 encodeFunctionData(signature: string, ...args: unknown[]): Buffer { 23 let frag: FunctionFragment | undefined; 24 try { 25 frag = iface.getFunction(formatSignature(signature)); 26 return toBuffer(iface.encodeFunctionData(frag, preEncodeResult(args, frag.inputs))); 27 } catch (err) { 28 throwErr(err, 'encode function data', signature, args, frag); 29 } 30 }, 31 32 decodeFunctionResult(signature: string, data: Uint8Array = new Uint8Array()): any { 33 let frag: FunctionFragment | undefined; 34 try { 35 frag = iface.getFunction(formatSignature(signature)); 36 return postDecodeResult(iface.decodeFunctionResult(frag, data), frag.outputs); 37 } catch (err) { 38 throwErr(err, 'decode function result', signature, { data }, frag); 39 } 40 }, 41 42 decodeEventLog(signature: string, data: Uint8Array = new Uint8Array(), topics?: Uint8Array[]): any { 43 let frag: EventFragment | undefined; 44 try { 45 frag = iface.getEvent(formatSignature(signature)); 46 return postDecodeResult( 47 iface.decodeEventLog( 48 frag, 49 prefixedHexString(data), 50 topics?.map((topic) => prefixedHexString(topic)), 51 ), 52 frag.inputs, 53 ); 54 } catch (err) { 55 throwErr(err, 'decode event log', signature, { data, topics }, frag); 56 } 57 }, 58 }; 59 } 60 61 function formatSignature(signature: string): string { 62 return prefixedHexString(signature); 63 } 64 65 function throwErr( 66 err: unknown, 67 action: string, 68 signature: string, 69 args: Record<string, unknown> | unknown[], 70 frag?: Fragment, 71 ): never { 72 const name = frag ? frag.name : `member with signature '${signature}'`; 73 const inputs = frag?.inputs ? ` (inputs: ${JSON.stringify(frag.inputs)})` : ''; 74 throw new Error(`ContractCodec could not ${action} for ${name} with args ${JSON.stringify(args)}${inputs}: ${err}`); 75 }