var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { jsx as _jsx } from "react/jsx-runtime";
import { BNS } from "@leekone/bnsjs";
// eslint-disable-next-line import/no-extraneous-dependencies
import { providers } from "ethers";
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
const opts = {};
if (process.env.REACT_APP_GRAPHURI) {
    opts.graphURI = process.env.REACT_APP_GRAPHURI;
}
const defaultValue = new BNS(opts);
defaultValue.staticNetwork = false;
const BnsContext = createContext(Object.assign(Object.assign({}, defaultValue), { ready: false }));
const chainID = process.env.NODE_ENV === "production" ? 137 : 137;
function EnsProvider({ children }) {
    const [ready, setReady] = useState(false);
    const chainIdRef = useRef(null);
    const chainSetPromise = useRef(null);
    const setChainPromise = () => {
        const provider = new providers.JsonRpcProvider("https://polygon-bor.publicnode.com");
        // eslint-disable-next-line promise/always-return
        return defaultValue.setProvider(provider).then(() => {
            chainIdRef.current = chainID;
            chainSetPromise.current = null;
            setReady(true);
        });
    };
    useEffect(() => {
        if (typeof window !== "undefined" && !chainSetPromise.current) {
            chainSetPromise.current = setChainPromise();
        }
    }, []);
    const value = useMemo(() => new Proxy(Object.assign(Object.assign({}, defaultValue), { ready }), {
        // chain id safety check
        get(target, prop, reciever) {
            var _a;
            const targetFn = target[prop];
            // if on client + target is async function
            if (typeof window !== "undefined" && typeof targetFn === "function" && ((_a = targetFn.constructor) === null || _a === void 0 ? void 0 : _a.name) === "AsyncFunction") {
                const currentChainId = 137;
                // if reference chainId isn't up to date
                if (chainIdRef.current !== currentChainId) {
                    // if there is no ongoing chain set promise
                    if (!chainSetPromise.current) {
                        // set ready to false before making changes
                        setReady(false);
                        // set chain set promise to new promise
                        chainSetPromise.current = setChainPromise();
                    }
                    // eslint-disable-next-line func-names
                    return function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            // wait for existing chain set promise
                            yield chainSetPromise.current;
                            // return result of target function
                            return targetFn(...args);
                        });
                    };
                }
            }
            // pass through all other getters
            return Reflect.get(target, prop, reciever);
        },
    }), [ready]);
    return _jsx(BnsContext.Provider, Object.assign({ value: value }, { children: children }));
}
const BNSContext = () => useContext(BnsContext);
export { BNSContext, EnsProvider };
//# sourceMappingURL=BNSProvider.js.map