import { createLibp2p } from 'libp2p';
import { supportedKeys, generateKeyPair } from '@libp2p/crypto/keys';
import { peerIdFromKeys } from '@libp2p/peer-id';
import { pipe } from 'it-pipe';
import { yamux } from '@chainsafe/libp2p-yamux';
import { mplex } from '@libp2p/mplex';
import { noise } from '@chainsafe/libp2p-noise';
import { Buffer } from 'buffer/index.js';
import { Message } from 'didcomm';
import { toDIDCOMMType, PROTOCOLS, fromDIDCOMMType, ExportableEd25519PublicKey, ExportableEd25519PrivateKey } from '@djack-sdk/interfaces';
import { Apollo, Castor, Domain } from '@atala/prism-wallet-sdk';
import { createX25519PublicKeyFromEd25519PublicKey, createX25519FromEd25519KeyPair } from '@djack-sdk/did-peer';
import { didUrlFromString } from '@djack-sdk/shared';
import { v4 } from 'uuid';

/**
 * @class AnoncredsLoader
 * handle loading and access of anoncreds library
 * Singleton to prevent recompilation of wasm
 */
class AnoncredsLoader {
    constructor() {
        this.loaded = false;
    }
    static async getInstance() {
        if (AnoncredsLoader.instance === undefined) {
            AnoncredsLoader.instance = new AnoncredsLoader();
            await this.instance.load();
        }
        return AnoncredsLoader.instance;
    }
    async load() {
        if (!this.loaded) {
            const pkg = await import('anoncreds-wasm');
            this.pkg = pkg;
            this.loaded = true;
        }
    }
    get wasm() {
        if (this.loaded === false || this.pkg === undefined) {
            throw new Error();
        }
        return this.pkg;
    }
    createLinksecret() {
        return this.wasm.proverCreateLinkSecret();
    }
    createCredentialRequest(credentialOffer, credentialDefinition, linkSecret, linkSecretId) {
        const result = this.wasm.proverCreateCredentialRequest(credentialOffer, credentialDefinition, linkSecret, linkSecretId);
        const credentialRequest = result[0];
        credentialRequest.blinded_ms_correctness_proof.m_caps = this.mapToObj(credentialRequest.blinded_ms_correctness_proof.m_caps);
        return [credentialRequest, result[1]];
    }
    processCredential(credentialDefinition, credential, credentialRequestMeta, linkSecret) {
        const result = this.wasm.proverProcessCredential(credentialDefinition, credential, credentialRequestMeta, linkSecret);
        result.values = this.mapToObj(result.values);
        return result;
    }
    createPresentation(presentationRequest, schemas, credentialDefinitions, credential, linkSecret) {
        const result = this.wasm.proverCreatePresentation(presentationRequest, schemas, credentialDefinitions, credential, linkSecret);
        result.proof.proofs = result.proof.proofs.map((proof) => {
            proof.primary_proof.eq_proof.revealed_attrs = this.mapToObj(proof.primary_proof.eq_proof.revealed_attrs);
            proof.primary_proof.eq_proof.m = this.mapToObj(proof.primary_proof.eq_proof.m);
            proof.primary_proof.ge_proofs = proof.primary_proof.ge_proofs.map((ge) => {
                ge.r = this.mapToObj(ge.r);
                ge.t = this.mapToObj(ge.t);
                ge.u = this.mapToObj(ge.u);
                ge.predicate = this.mapToObj(ge.predicate);
                return ge;
            });
            return proof;
        });
        result.requested_proof.revealed_attrs = this.mapToObj(result.requested_proof.revealed_attrs);
        result.requested_proof.self_attested_attrs = this.mapToObj(result.requested_proof.self_attested_attrs);
        result.requested_proof.unrevealed_attrs = this.mapToObj(result.requested_proof.unrevealed_attrs);
        result.requested_proof.predicates = this.mapToObj(result.requested_proof.predicates);
        return result;
    }
    mapToObj(value) {
        return value instanceof Map ? Object.fromEntries(value) : value;
    }
}

async function getDidcommLibInstance() {
    const DIDCommLib = await import('./didcomm_js-lloanQTM.js');
    const wasmInit = DIDCommLib.default;
    const { default: wasm } = await import('./didcomm_js_bg-AQ-Bh9MB.js');
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    await wasmInit(await wasm());
    return DIDCommLib;
}

class CancellableTask {
    constructor(task, options) {
        const { abort, repeatEvery } = options;
        this.controller = abort;
        this.cancellationToken = new Promise((resolve, reject) => {
            const onAbort = () => {
                console.log("Aborting task");
                this.controller.signal.removeEventListener("abort", onAbort);
                reject(new Error("Task was cancelled"));
            };
            this.controller.signal.addEventListener("abort", onAbort);
            if (repeatEvery !== undefined) {
                this.period = Math.max(repeatEvery, 10);
                this.loopOnTaskEvery(task, resolve, reject, options.repeatFailureOnly);
            }
            else {
                task().then(resolve).catch(reject);
            }
        });
    }
    clearTimer() {
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = undefined;
        }
    }
    loopOnTaskEvery(task, resolve, reject, repeatFailureOnly = false) {
        if (!this.controller.signal.aborted) {
            if (!repeatFailureOnly) {
                task()
                    .then(() => {
                    this.clearTimer();
                    this.timer = setTimeout(() => {
                        this.loopOnTaskEvery(task, resolve, reject, repeatFailureOnly);
                    }, this.period);
                })
                    .catch(reject);
            }
            else {
                task()
                    .then(resolve)
                    .catch(() => {
                    this.clearTimer();
                    this.timer = setTimeout(() => {
                        this.loopOnTaskEvery(task, resolve, reject, repeatFailureOnly);
                    }, this.period);
                });
            }
        }
    }
    cancel() {
        this.clearTimer();
        this.controller.abort();
    }
    async then() {
        return this.cancellationToken;
    }
    callback(fn) {
        if (this.period) {
            throw new Error("Can't call callback on non periodic cancellable task");
        }
        return this.cancellationToken.then((value) => fn(value));
    }
}

const didcommPKG = typeof window !== "undefined"
    ? await getDidcommLibInstance()
    : await import('didcomm');
class BaseMessage {
    constructor(data) {
        this.id = v4();
        this.typ = "application/didcomm-plain+json";
        this.body = {};
        this.thid = v4();
        this.attachments = [];
        if (!data.from) {
            throw new Error("From is required");
        }
        if (!data.to) {
            throw new Error("To is required");
        }
        this.to = data.to;
        this.from = data.from;
        this.body = data.body || {};
        this.attachments = data.attachments || [];
        this.pthid = data.pthid;
        this.created_time = data.created_time;
        this.expires_time = data.expires_time;
        this.from_prior = data.from_prior;
    }
    get message() {
        return new didcommPKG.Message(this);
    }
    is(type) {
        return !type ? false : type in PROTOCOLS;
    }
}
class ProtocolMessage extends BaseMessage {
    constructor(data) {
        super(data);
        if (this.is(data.type)) {
            this.type = data.type;
        }
    }
}
class ExchangeAuthenticateMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.emailExchangeAuthenticate);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new ExchangeAuthenticateMessage(json);
    }
}
class CredentialOfferRequestMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.credentialOfferRequest);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new CredentialOfferRequestMessage(json);
    }
    respond(message) {
        console.log(`Answering to offer ${this.thid}`);
        return new CredentialOfferMessage({
            ...message,
            thid: this.thid,
        });
    }
}
class CredentialOfferMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.credentialOffer);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new CredentialOfferMessage(json);
    }
}
class ExchangePresentationMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.emailExchangePresentation);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new ExchangePresentationMessage(json);
    }
}
class ExchangeRequestPresentationMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.emailExchangePresentationRequest);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new ExchangeRequestPresentationMessage(json);
    }
}
class CredentialRequestMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.credentialRequest);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new CredentialRequestMessage(json);
    }
}
class CredentialIssueMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.credentialIssue);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new CredentialIssueMessage(json);
    }
}
class ExchangeDeliveryMessage extends ProtocolMessage {
    constructor() {
        super(...arguments);
        this.type = toDIDCOMMType(PROTOCOLS.emailExchangeDelivery);
    }
    static async fromJSON(json) {
        json.type && fromDIDCOMMType(json.type);
        return new ExchangeDeliveryMessage(json);
    }
}

/* eslint-disable @typescript-eslint/no-non-null-assertion */
const apollo = new Apollo();
const castor = new Castor(apollo);
const DIDCommMessagingKey = "DIDCommMessaging";
const DIDCommMessagingEncodedKey = "dm";
class ProtocolHandlers {
    constructor(protocols = []) {
        this.protocols = protocols;
    }
}
async function getPeerIDDID(peer) {
    const publicKey = peer.publicKey?.slice(4);
    if (!publicKey) {
        throw new Error("No public key in peerId");
    }
    const unmarshalEd25519PublicKey = supportedKeys.ed25519.unmarshalEd25519PublicKey(publicKey);
    const ed25519Pub = new ExportableEd25519PublicKey(unmarshalEd25519PublicKey.marshal());
    const x25519Pub = createX25519PublicKeyFromEd25519PublicKey(ed25519Pub);
    const services = Network.getServicesForPeerDID(peer);
    return castor.createPeerDID([ed25519Pub, x25519Pub], services);
}
class Network {
    get abortController() {
        const abortController = new AbortController();
        this.aborts.push(abortController);
        return {
            signal: abortController.signal,
        };
    }
    constructor(options) {
        this.handlers = [];
        this.aborts = [];
        this.didWebHostname = options.didWebHostname;
        this.did = options.did;
        this.peerdid = options.peerdid;
        this.p2p = options.p2p;
        this.storage = options.storage;
        this.factory = options.factory;
        this.registry = options.registry;
        this.domain = options.domain;
        this.cardanoDID = options.cardanoDID;
    }
    static async getDIDComm() {
        if (!this.didcomm) {
            if (typeof window !== "undefined")
                this.didcomm = await getDidcommLibInstance();
            else
                this.didcomm = await import('didcomm');
        }
        return this.didcomm;
    }
    static async getAnoncreds() {
        if (!Network._anoncreds) {
            Network._anoncreds = await AnoncredsLoader.getInstance();
        }
        return Network._anoncreds;
    }
    get anoncreds() {
        if (Network._anoncreds === undefined) {
            throw new Error("Pollux - Anoncreds not loaded");
        }
        return Network._anoncreds;
    }
    static async generateKeyPair() {
        const prv = await generateKeyPair("Ed25519");
        const ed25519Prv = new ExportableEd25519PrivateKey(prv.marshal());
        const ed25519Pub = new ExportableEd25519PublicKey(prv.public.marshal());
        const ed25519KeyPair = {
            curve: Domain.Curve.ED25519,
            privateKey: ed25519Prv,
            publicKey: ed25519Pub,
        };
        return ed25519KeyPair;
    }
    get addresses() {
        const multiaddrs = this.p2p.getMultiaddrs().map((ma) => ma.toString());
        return multiaddrs;
    }
    static addDefaultListeners(listeners) {
        return Array.from(new Set([...listeners, ...this.DEFAULT_LISTENERS]));
    }
    static async createNode(options) {
        const { keyPair, storage, factory, registry, listen, domain, publicKeys, services, peerDiscovery, } = options;
        const ed25519KeyPair = keyPair ? keyPair : await this.generateKeyPair();
        const x25519KeyPair = createX25519FromEd25519KeyPair(ed25519KeyPair);
        const peerId = await peerIdFromKeys(new supportedKeys.ed25519.Ed25519PublicKey(ed25519KeyPair.publicKey.raw)
            .bytes, new supportedKeys.ed25519.Ed25519PrivateKey(ed25519KeyPair.privateKey.raw, ed25519KeyPair.publicKey.raw).bytes);
        const keyPairs = [ed25519KeyPair, x25519KeyPair];
        const privateKeys = keyPairs.map((keyPair) => keyPair.privateKey);
        const did = new Domain.DID("did", "web", `${options.didWebHostname}:peers:${peerId.toString()}`);
        const peerDID = await castor.createPeerDID(keyPairs.map((keyPair) => keyPair.publicKey), this.getServicesForPeerDID(peerId));
        for (const priv of privateKeys) {
            await storage.store.addDIDKey(did, peerId, priv);
            await storage.store.addDIDKey(peerDID, peerId, priv);
        }
        const node = await createLibp2p({
            start: false,
            peerId: peerId,
            addresses: {
                listen: listen,
            },
            streamMuxers: [yamux(), mplex()],
            transports: options.transports,
            connectionEncryption: [noise()],
            connectionGater: {
                denyDialMultiaddr: () => {
                    return false;
                },
            },
            services: services ? services : {},
            peerDiscovery: peerDiscovery,
        });
        const cardanoDID = publicKeys && publicKeys.length
            ? {
                cardanoDID: await castor.createPeerDID(publicKeys, [
                    new Domain.Service("didcomm", ["DIDCommMessaging"], {
                        uri: (await castor.createPeerDID(publicKeys, [])).toString(),
                        accept: ["didcomm/v2"],
                        routingKeys: []
                    })
                ]),
            }
            : {
                cardanoDID: await castor.createPeerDID([ed25519KeyPair.publicKey, x25519KeyPair.publicKey], [
                    new Domain.Service("didcomm", [
                        "DIDCommMessaging"
                    ], {
                        uri: (await castor.createPeerDID([
                            ed25519KeyPair.publicKey,
                            x25519KeyPair.publicKey,
                        ], [])).toString(),
                        accept: ["didcomm/v2"],
                        routingKeys: []
                    })
                ])
            };
        console.log("Cardnao did ", cardanoDID);
        return new Network({
            didWebHostname: options.didWebHostname,
            did,
            peerdid: peerDID,
            p2p: node,
            storage,
            registry,
            listen,
            factory,
            domain,
            ...cardanoDID,
        });
    }
    static getServicesForPeerDID(peerId) {
        return [
            new Domain.Service("didcomm", ["DIDCommMessaging"], {
                uri: peerId.toString(),
                accept: ["didcomm/v2"],
                routingKeys: []
            })
        ];
    }
    get address() {
        const [multiaddr] = this.p2p.getMultiaddrs();
        return multiaddr;
    }
    get services() {
        if (!this.p2p)
            return [];
        const peerId = this.p2p.peerId;
        return Network.getServicesForPeerDID(peerId);
    }
    get peer() {
        if (!this.p2p)
            return null;
        return this.p2p.peerId;
    }
    get didResolver() {
        return {
            resolve: async (did) => {
                const doc = await castor.resolveDID(did);
                const authentications = [];
                const keyAgreements = [];
                const services = [];
                const verificationMethods = [];
                doc.coreProperties.forEach((coreProperty) => {
                    if ("verificationMethods" in coreProperty) {
                        coreProperty.verificationMethods.forEach((method) => {
                            const curve = Domain.VerificationMethod.getCurveByType(method.publicKeyJwk?.crv || "");
                            switch (curve) {
                                case Domain.Curve.ED25519:
                                    authentications.push(method.id);
                                    break;
                                case Domain.Curve.X25519:
                                    keyAgreements.push(method.id);
                                    break;
                            }
                            const publicKeyBase64 = method.publicKeyJwk?.x;
                            const publicKeyKid = method.publicKeyJwk.kid;
                            if (!method.publicKeyJwk) {
                                throw new Error("Only JWK allowed");
                            }
                            verificationMethods.push({
                                controller: method.controller,
                                id: method.id,
                                type: "JsonWebKey2020",
                                publicKeyJwk: {
                                    crv: method.publicKeyJwk?.crv,
                                    kid: publicKeyKid,
                                    kty: "OKP",
                                    x: publicKeyBase64,
                                },
                            });
                        });
                    }
                    if (coreProperty instanceof Domain.Service &&
                        coreProperty.type.includes(DIDCommMessagingKey)) {
                        services.push({
                            id: coreProperty.id,
                            type: DIDCommMessagingKey,
                            serviceEndpoint: {
                                uri: coreProperty.serviceEndpoint.uri,
                                accept: coreProperty.serviceEndpoint.accept,
                                routing_keys: coreProperty.serviceEndpoint.routingKeys,
                            },
                        });
                    }
                });
                const dcdoc = {
                    id: doc.id.toString(),
                    authentication: authentications,
                    keyAgreement: keyAgreements,
                    service: services,
                    verificationMethod: verificationMethods,
                };
                return dcdoc;
            },
        };
    }
    get secretResolver() {
        return {
            find_secrets: async (secretIds) => {
                const peerDIDs = await this.storage.store.findAllDIDs();
                const found = secretIds.filter((secretId) => {
                    const secretDID = didUrlFromString(secretId);
                    return peerDIDs.find((secretPeerDID) => secretPeerDID.toString() === secretDID.did.toString());
                });
                return found;
            },
            get_secret: async (secretId) => {
                const peerDIDs = await this.storage.store.findAllDIDs();
                const secretDID = didUrlFromString(secretId);
                const found = peerDIDs.find((peerDIDSecret) => {
                    return secretDID.did.toString() === peerDIDSecret.toString();
                });
                if (found) {
                    const did = await castor.resolveDID(found.did.toString());
                    const [publicKeyJWK] = did.coreProperties.reduce((all, property) => {
                        if (property instanceof Domain.VerificationMethods) {
                            const matchingValue = property.values.find((verificationMethod) => verificationMethod.id === secretId);
                            if (matchingValue && matchingValue.publicKeyJwk) {
                                return [...all, matchingValue.publicKeyJwk];
                            }
                        }
                        return all;
                    }, []);
                    if (publicKeyJWK) {
                        const secret = this.mapToSecret(found, publicKeyJWK);
                        return secret;
                    }
                }
                return null;
            },
        };
    }
    mapToSecret(peerDid, publicKeyJWK) {
        const privateKeyBuffer = peerDid.privateKeys.find((key) => key.keyCurve.curve === Domain.Curve.X25519);
        if (!privateKeyBuffer) {
            throw new Error(`Invalid PrivateKey Curve ${Domain.Curve.X25519}`);
        }
        const privateKey = apollo.createPrivateKey({
            type: Domain.KeyTypes.Curve25519,
            curve: Domain.Curve.X25519,
            raw: privateKeyBuffer.value,
        });
        const ecnumbasis = castor.getEcnumbasis(peerDid.did, privateKey.publicKey());
        const id = `${peerDid.did.toString()}#${ecnumbasis}`;
        const secret = {
            id,
            type: "JsonWebKey2020",
            privateKeyJwk: {
                crv: Domain.Curve.X25519,
                kty: "OKP",
                d: Buffer.from(privateKey.getEncoded()).toString(),
                x: publicKeyJWK.x,
            },
        };
        return secret;
    }
    validateProtocol(protocol) {
        const protocolKey = Object.values(PROTOCOLS).findIndex((value) => value === protocol);
        if (protocolKey) {
            return Object.values(PROTOCOLS)[protocolKey];
        }
        throw new Error("Invalid Protocol " + protocol);
    }
    addHandler(name, handler) {
        const serviceHandle = this.getServiceProtocol(this.validateProtocol(name));
        console.log("AddedHandler", serviceHandle);
        this.handlers.push([serviceHandle, handler]);
    }
    _onPeerConnect(evt) {
        const peer = evt.detail;
        console.log("n0 connected to: ", peer.toString());
        if (this.onPeerConnect) {
            this.onPeerConnect(peer);
        }
    }
    async _onPeerDiscovery(evt) {
        const peer = evt.detail;
        console.log(`Peer ${this.p2p.peerId.toString()} discovered: ${peer.id.toString()} with protocols`, JSON.stringify(evt.detail.protocols));
        if (this.onPeerDiscovery) {
            this.onPeerDiscovery(peer);
        }
    }
    async stop() {
        this.coreAbort.abort(new Error("Stopping"));
        this.handlers.forEach(([protocol]) => {
            this.p2p.unhandle(protocol);
        });
        this.coreAbort.signal.removeEventListener("abort", () => {
            this.aborts.forEach((abort) => {
                abort.abort(new Error("aborted"));
            });
        });
        this.p2p.removeEventListener("peer:discovery", this._onPeerDiscovery.bind(this));
        this.p2p.removeEventListener("peer:connect", this._onPeerConnect.bind(this));
        return this.p2p.stop();
    }
    getServiceProtocol(protocol) {
        //TODO, HASH DOMAIN, option 1 with the node pubKey encoded or just sha512 it or something
        return `/service/djack.email${protocol}`;
    }
    isValidServiceProvider(protocols) {
        return protocols.find((protocol) => this.handlers.find(([protocolName]) => protocol === protocolName));
    }
    async start(abortController) {
        this.coreAbort = abortController || new AbortController();
        this.coreAbort.signal.addEventListener("abort", () => {
            this.aborts.forEach((abort) => {
                abort.abort(new Error("aborted"));
            });
        });
        this.handlers.forEach(([protocol, handler]) => {
            this.p2p.handle(protocol, (data) => {
                console.log(`[network][${protocol}] Connection request from ${data.connection.remotePeer.toString()}`);
                return handler(data);
            }, { runOnTransientConnection: true });
        });
        this.p2p.addEventListener("peer:connect", this._onPeerConnect.bind(this));
        this.p2p.addEventListener("peer:disconnect", (peerId) => {
            console.log(`⚡️[server]: Peer ${peerId.detail.toString()} disconnected`);
        });
        console.log(`⚡️[server]: Starting  node`);
        await this.p2p.start();
        console.log(`⚡️[server]: Started  node `, this.p2p.peerId.toString());
        if (this.addresses.length) {
            console.log(`⚡️[server]: Node is available at:  `, this.addresses.join(", "));
        }
    }
    async packMessage(from, to, message) {
        const [encryptedMsg] = await message.pack_encrypted(to, from, null, this.didResolver, this.secretResolver, {
            enc_alg_anon: "Xc20pEcdhEsA256kw",
            enc_alg_auth: "A256cbcHs512Ecdh1puA256kw",
            forward: false,
            protect_sender: false,
        });
        return Buffer.from(encryptedMsg);
    }
    async unpack(message) {
        const [didcommMsg] = await Message.unpack(Buffer.from(message).toString(), this.didResolver, this.secretResolver, {
            expect_decrypt_by_all_keys: false,
            unwrap_re_wrapping_forward: false,
        });
        return didcommMsg;
    }
    async dialProtocol(peer, protocols) {
        const dial = {
            from: this.peer?.toString(),
            to: peer.toString(),
        };
        console.log(`[${JSON.stringify(protocols)}]: Dialing ${dial.from} to ${dial.to}`);
        const connection = await this.dial(peer);
        return connection.newStream(protocols, { runOnTransientConnection: true });
    }
    async dial(peer) {
        return this.p2p.dial(peer, { signal: this.abortController.signal });
    }
    async sendMessage(peer, protocol, message) {
        const stream = await this.dialProtocol(peer, protocol);
        const result = await pipe([message], stream.sink);
        await stream.close({ signal: this.abortController.signal });
        return result;
    }
    async sendAndGetResponse(peer, protocol, message) {
        try {
            const stream = await this.dialProtocol(peer, protocol);
            const results = new Promise((resolve, reject) => {
                return pipe([message], stream, async (source) => {
                    try {
                        for await (const data of source) {
                            const unpacked = await this.unpack(data.subarray());
                            return resolve(unpacked);
                        }
                    }
                    catch (err) {
                        console.log(err);
                        return reject(err);
                    }
                });
            });
            await results;
            await stream.close({ signal: this.abortController.signal });
            return results;
        }
        catch (err) {
            console.log(err);
            throw err;
        }
    }
}
Network.DEFAULT_LISTENERS = [];

export { AnoncredsLoader, CancellableTask, CredentialIssueMessage, CredentialOfferMessage, CredentialOfferRequestMessage, CredentialRequestMessage, DIDCommMessagingEncodedKey, DIDCommMessagingKey, ExchangeAuthenticateMessage, ExchangeDeliveryMessage, ExchangePresentationMessage, ExchangeRequestPresentationMessage, Network, ProtocolHandlers, ProtocolMessage, getPeerIDDID };
//# sourceMappingURL=index.js.map
