MCPcopy Create free account
hub / github.com/api3dao/airnode / decode

Function decode

packages/airnode-abi/src/decoding.ts:28–76  ·  view source on GitHub ↗
(encodedData: string)

Source from the content-addressed store, hash-verified

26}
27
28export function decode(encodedData: string): DecodedMap {
29 // Special cases for empty parameters
30 if (encodedData === '0x') {
31 return {};
32 }
33
34 // Alternatively:
35 // const header = encodedData.substring(0, 66);
36 const header = ethers.utils.hexlify(ethers.utils.arrayify(encodedData).slice(0, 32));
37 const parsedHeader = ethers.utils.parseBytes32String(header);
38
39 // Get and validate the first character of the header
40 const encodedEncodingVersion = parsedHeader.substring(0, 1);
41 if (encodedEncodingVersion !== '1') {
42 throw new Error(`Unknown ABI schema version: ${encodedEncodingVersion}`);
43 }
44
45 // The version is specified by the first byte and the parameters are specified by the rest
46 const encodedParameterTypes = parsedHeader.substring(1);
47
48 // Replace encoded types with full type names
49 const fullParameterTypes: ParameterType[] = Array.from(encodedParameterTypes).map(
50 (type) => PARAMETER_SHORT_TYPES[type as ParameterTypeShort]
51 );
52
53 // The first `bytes32` is the type encoding
54 const initialDecodedTypes: ParameterType[] = ['bytes32'];
55
56 const decodingTypes = fullParameterTypes.reduce((acc: string[], type) => {
57 // Each parameter is expected to have a `bytes32` name
58 return [...acc, 'bytes32' as const, TYPE_TRANSFORMATIONS[type] ?? type];
59 }, initialDecodedTypes);
60
61 // It's important to leave the `encodedData` intact here and not try to trim off the first
62 // 32 bytes (i.e. the header) because that results in the decoding failing. So decode
63 // exactly what you got from the contract, including the header.
64 const decodedData = ethers.utils.defaultAbiCoder.decode(decodingTypes, encodedData);
65
66 // Checks if the original encoded data matches the re-encoded data
67 const reEncodedData = ethers.utils.defaultAbiCoder.encode(decodingTypes, decodedData);
68 if (reEncodedData !== encodedData) {
69 throw new Error('Re-encoding mismatch');
70 }
71
72 const [_version, ...decodedParameters] = decodedData;
73 const nameValuePairs = chunk(decodedParameters, 2) as [string, string][];
74
75 return buildDecodedMap(fullParameterTypes, nameValuePairs);
76}

Callers 2

safeDecodeFunction · 0.90

Calls 1

buildDecodedMapFunction · 0.85

Tested by

no test coverage detected