| 1005 | */ |
| 1006 | // Create the filter for the event with search criteria (e.g. for eth_filterLog) |
| 1007 | encodeFilterTopics(fragment: EventFragment | string, values: ReadonlyArray<any>): Array<null | string | Array<string>> { |
| 1008 | if (typeof(fragment) === "string") { |
| 1009 | const f = this.getEvent(fragment); |
| 1010 | assertArgument(f, "unknown event", "eventFragment", fragment); |
| 1011 | fragment = f; |
| 1012 | } |
| 1013 | |
| 1014 | assert(values.length <= fragment.inputs.length, `too many arguments for ${ fragment.format() }`, |
| 1015 | "UNEXPECTED_ARGUMENT", { count: values.length, expectedCount: fragment.inputs.length }) |
| 1016 | |
| 1017 | const topics: Array<null | string | Array<string>> = []; |
| 1018 | if (!fragment.anonymous) { topics.push(fragment.topicHash); } |
| 1019 | |
| 1020 | // @TODO: Use the coders for this; to properly support tuples, etc. |
| 1021 | const encodeTopic = (param: ParamType, value: any): string => { |
| 1022 | if (param.type === "string") { |
| 1023 | return id(value); |
| 1024 | } else if (param.type === "bytes") { |
| 1025 | return keccak256(hexlify(value)); |
| 1026 | } |
| 1027 | |
| 1028 | if (param.type === "bool" && typeof(value) === "boolean") { |
| 1029 | value = (value ? "0x01": "0x00"); |
| 1030 | } else if (param.type.match(/^u?int/)) { |
| 1031 | value = toBeHex(value); // @TODO: Should this toTwos?? |
| 1032 | } else if (param.type.match(/^bytes/)) { |
| 1033 | value = zeroPadBytes(value, 32); |
| 1034 | } else if (param.type === "address") { |
| 1035 | // Check addresses are valid |
| 1036 | this.#abiCoder.encode( [ "address" ], [ value ]); |
| 1037 | } |
| 1038 | |
| 1039 | return zeroPadValue(hexlify(value), 32); |
| 1040 | }; |
| 1041 | |
| 1042 | values.forEach((value, index) => { |
| 1043 | |
| 1044 | const param = (<EventFragment>fragment).inputs[index]; |
| 1045 | |
| 1046 | if (!param.indexed) { |
| 1047 | assertArgument(value == null, |
| 1048 | "cannot filter non-indexed parameters; must be null", ("contract." + param.name), value); |
| 1049 | return; |
| 1050 | } |
| 1051 | |
| 1052 | if (value == null) { |
| 1053 | topics.push(null); |
| 1054 | } else if (param.baseType === "array" || param.baseType === "tuple") { |
| 1055 | assertArgument(false, "filtering with tuples or arrays not supported", ("contract." + param.name), value); |
| 1056 | } else if (Array.isArray(value)) { |
| 1057 | topics.push(value.map((value) => encodeTopic(param, value))); |
| 1058 | } else { |
| 1059 | topics.push(encodeTopic(param, value)); |
| 1060 | } |
| 1061 | }); |
| 1062 | |
| 1063 | // Trim off trailing nulls |
| 1064 | while (topics.length && topics[topics.length - 1] === null) { |