MCPcopy Create free account
hub / github.com/cardstack/cardstack / decode

Function decode

packages/cardpay-subgraph/src/abi.ts:7–87  ·  view source on GitHub ↗
(typesStr: string, hex: string)

Source from the content-addressed store, hash-verified

5const WORD_SIZE = 64;
6
7export function decode(typesStr: string, hex: string): Array<ethereum.Value> {
8 log.debug('decoding abi type: {}, hex {}', [typesStr, hex]);
9 if (hex.startsWith('0x')) {
10 hex = hex.slice(2);
11 }
12
13 if (typesStr.endsWith(')') && !typesStr.startsWith('(')) {
14 // the types looks like "someMethod(address,uint8,...)", we need to remove
15 // the method hash from the hex, as the caller is indicating that we are
16 // decoding a function call
17 hex = hex.slice(8);
18 }
19 assert(hex.length % 64 == 0, 'hex for abi decoding has odd length ' + hex.length.toString() + ', hex: ' + hex);
20
21 if (typesStr.indexOf('(') > -1) {
22 typesStr = typesStr.slice(typesStr.indexOf('(') + 1, -1);
23 }
24
25 let types = typesStr.split(',');
26 let result: Array<ethereum.Value> = [];
27
28 for (let index = 0; index < types.length; index++) {
29 let type = types[index];
30 let pointer = index * WORD_SIZE;
31 let word = wordAt(hex, pointer);
32 let isArray = type.endsWith('[]');
33
34 log.debug('decoding abi - word at {}: {}', [pointer.toString(), word]);
35
36 if (!isArray) {
37 if (type == 'address') {
38 result.push(ethereum.Value.fromAddress(hexToAddress(word)));
39 } else if (type.startsWith('uint')) {
40 result.push(ethereum.Value.fromUnsignedBigInt(bigIntFromHex(word)));
41 } else if (type == 'bool') {
42 result.push(ethereum.Value.fromBoolean(hexToI32(word) == 1));
43 } else if (type == 'bytes') {
44 let offset = hexToI32(word) * 2;
45 let length = hexToI32(hex.slice(offset, offset + WORD_SIZE)) * 2;
46 result.push(ethereum.Value.fromBytes(bytesFromHex(hex.slice(offset + WORD_SIZE, offset + WORD_SIZE + length))));
47 } else if (type == 'string') {
48 let offset = hexToI32(word) * 2;
49 let length = hexToI32(hex.slice(offset, offset + WORD_SIZE)) * 2;
50 let utf8Hex = hex.slice(offset + WORD_SIZE, offset + WORD_SIZE + length);
51 let str = '';
52 for (let i = 0; i < utf8Hex.length; i += 2) {
53 str += String.fromCharCode(hexToI32(utf8Hex.slice(i, i + 2)));
54 }
55 log.info('==========> decoding string - bytes: {} string: {}', [utf8Hex, str]);
56 result.push(ethereum.Value.fromString(str));
57 } else {
58 assert(false, 'decoding ' + type + ' is not yet supported');
59 }
60 } else {
61 let offset = hexToI32(word) * 2;
62 let length = hexToI32(hex.slice(offset, offset + WORD_SIZE)) * 2;
63 if (type.startsWith('uint')) {
64 let array: Array<BigInt> = [];

Callers 1

handleExecutionSuccessFunction · 0.90

Calls 8

wordAtFunction · 0.85
hexToAddressFunction · 0.85
bigIntFromHexFunction · 0.85
hexToI32Function · 0.85
bytesFromHexFunction · 0.85
splitMethod · 0.80
fromAddressMethod · 0.80
indexOfMethod · 0.45

Tested by

no test coverage detected