| 966 | */ |
| 967 | // Create the filter for the event with search criteria (e.g. for eth_filterLog) |
| 968 | encodeFilterTopics(fragment: EventFragment | string, values: ReadonlyArray<any>): Array<null | string | Array<string>> { |
| 969 | if (typeof(fragment) === "string") { |
| 970 | const f = this.getEvent(fragment); |
| 971 | assertArgument(f, "unknown event", "eventFragment", fragment); |
| 972 | fragment = f; |
| 973 | } |
| 974 | |
| 975 | assert(values.length <= fragment.inputs.length, `too many arguments for ${ fragment.format() }`, |
| 976 | "UNEXPECTED_ARGUMENT", { count: values.length, expectedCount: fragment.inputs.length }) |
| 977 | |
| 978 | const topics: Array<null | string | Array<string>> = []; |
| 979 | if (!fragment.anonymous) { topics.push(fragment.topicHash); } |
| 980 | |
| 981 | // @TODO: Use the coders for this; to properly support tuples, etc. |
| 982 | const encodeTopic = (param: ParamType, value: any): string => { |
| 983 | if (param.type === "string") { |
| 984 | return id(value); |
| 985 | } else if (param.type === "bytes") { |
| 986 | return keccak256(value); |
| 987 | } |
| 988 | |
| 989 | if (param.type === "bool" && typeof(value) === "boolean") { |
| 990 | value = (value ? "0x01": "0x00"); |
| 991 | } else if (param.type.match(/^u?int/)) { |
| 992 | value = toBeHex(value); // @TODO: Should this toTwos?? |
| 993 | } else if (param.type.match(/^bytes/)) { |
| 994 | value = zeroPadBytes(value, 32); |
| 995 | } else if (param.type === "address") { |
| 996 | // Check addresses are valid |
| 997 | this.#abiCoder.encode( [ "address" ], [ value ]); |
| 998 | } |
| 999 | |
| 1000 | return zeroPadValue(hexlify(value), 32); |
| 1001 | }; |
| 1002 | |
| 1003 | values.forEach((value, index) => { |
| 1004 | |
| 1005 | const param = (<EventFragment>fragment).inputs[index]; |
| 1006 | |
| 1007 | if (!param.indexed) { |
| 1008 | assertArgument(value == null, |
| 1009 | "cannot filter non-indexed parameters; must be null", ("contract." + param.name), value); |
| 1010 | return; |
| 1011 | } |
| 1012 | |
| 1013 | if (value == null) { |
| 1014 | topics.push(null); |
| 1015 | } else if (param.baseType === "array" || param.baseType === "tuple") { |
| 1016 | assertArgument(false, "filtering with tuples or arrays not supported", ("contract." + param.name), value); |
| 1017 | } else if (Array.isArray(value)) { |
| 1018 | topics.push(value.map((value) => encodeTopic(param, value))); |
| 1019 | } else { |
| 1020 | topics.push(encodeTopic(param, value)); |
| 1021 | } |
| 1022 | }); |
| 1023 | |
| 1024 | // Trim off trailing nulls |
| 1025 | while (topics.length && topics[topics.length - 1] === null) { |