import { utils as ethersUtils } from "ethers";
import { mapAsync } from "../utils";
import { INVALID_ADDRESS } from "./types";
import * as adapters from "./adapters";
import * as adapters_1 from "./adapters";
export { adapters_1 as adapters };
export class AddressAggregator {
    adapters;
    logger;
    constructor(adapters, logger) {
        this.adapters = adapters;
        this.logger = logger;
    }
    static sources() {
        return Object.keys(adapters);
    }
    async update() {
        this.logger?.debug({
            at: "AddressAggregator::update",
            message: "Updating addresses.",
            sources: this.adapters.map((adapter) => adapter.name),
            supportedSources: AddressAggregator.sources(),
        });
        const allAddresses = await mapAsync(this.adapters, async (adapter) => {
            const invalidAddresses = [];
            const addresses = (await adapter.update())
                .map((address) => {
                try {
                    return ethersUtils.getAddress(address.toLowerCase());
                }
                catch {
                    invalidAddresses.push(address);
                    return INVALID_ADDRESS;
                }
            })
                .filter((address) => address !== INVALID_ADDRESS);
            if (invalidAddresses.length > 0) {
                this.logger?.warn({
                    at: "AddressAggregator::update()",
                    message: `Read ${invalidAddresses.length} malformed addresses on ${adapter.name}.`,
                    invalidAddresses,
                });
            }
            this.logger?.debug({
                at: "AddressAggregator::update",
                message: `Loaded ${addresses.length} addresses from ${adapter.name}.`,
            });
            return addresses;
        });
        // Dedup the aggregated, normalised, filtered set of addresses.
        const addresses = new Set(allAddresses.flat());
        this.logger?.debug({
            at: "AddressAggregator::update",
            message: `Loaded ${addresses.size} addresses.`,
            sources: this.adapters.map((adapter) => adapter.name),
        });
        return addresses;
    }
}
async function run() {
    const addressList = new AddressAggregator([new adapters.risklabs.AddressList({ throwOnError: true })]);
    const addresses = await addressList.update();
    console.log(`Retrieved ${addresses.size} addresses: ${JSON.stringify(Array.from(addresses), null, 2)}`);
    return 0;
}
if (require.main === module) {
    run()
        .then((result) => {
        process.exitCode = result;
    })
        .catch((error) => {
        console.error("Process exited with", error);
        process.exitCode = 127;
    });
}
//# sourceMappingURL=index.js.map