text: 'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  var common = require('@stacks/common');
  require('cross-fetch/polyfill');
  var jsontokens = require('jsontokens');
  var encryption = require('@stacks/encryption');
  var queryString = require('query-string');
  var profile = require('@stacks/profile');
  var network = require('@stacks/network');
  
  var BLOCKSTACK_HANDLER = 'blockstack';
  var BLOCKSTACK_STORAGE_LABEL = 'blockstack';
  var DEFAULT_BLOCKSTACK_HOST = 'https://browser.blockstack.org/auth';
  var DEFAULT_PROFILE = {
    '@type': 'Person',
    '@context': 'http://schema.org'
  };
  var DEFAULT_SCOPE = ["store_write"];
  var BLOCKSTACK_APP_PRIVATE_KEY_LABEL = 'blockstack-transit-private-key';
  var DEFAULT_CORE_NODE = 'https://core.blockstack.org';
  var NAME_LOOKUP_PATH = '/v1/names';
  var LOCALSTORAGE_SESSION_KEY = 'blockstack-session';
  
  var AppConfig = /*#__PURE__*/function () {
    function AppConfig(scopes, appDomain, redirectPath, manifestPath, coreNode, authenticatorURL) {
      if (scopes === void 0) {
        scopes = DEFAULT_SCOPE.slice();
      }
  
      if (appDomain === void 0) {
        var _getGlobalObject;
  
        appDomain = (_getGlobalObject = common.getGlobalObject('location', {
          returnEmptyObject: true
        })) == null ? void 0 : _getGlobalObject.origin;
      }
  
      if (redirectPath === void 0) {
        redirectPath = '';
      }
  
      if (manifestPath === void 0) {
        manifestPath = '/manifest.json';
      }
  
      if (coreNode === void 0) {
        coreNode = undefined;
      }
  
      if (authenticatorURL === void 0) {
        authenticatorURL = DEFAULT_BLOCKSTACK_HOST;
      }
  
      this.appDomain = appDomain;
      this.scopes = scopes;
      this.redirectPath = redirectPath;
      this.manifestPath = manifestPath;
      this.coreNode = coreNode;
      this.authenticatorURL = authenticatorURL;
    }
  
    var _proto = AppConfig.prototype;
  
    _proto.redirectURI = function redirectURI() {
      return "" + this.appDomain + this.redirectPath;
    };
  
    _proto.manifestURI = function manifestURI() {
      return "" + this.appDomain + this.manifestPath;
    };
  
    return AppConfig;
  }();
  
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
  
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  
  function _asyncToGenerator(fn) {
    return function () {
      var self = this,
          args = arguments;
      return new Promise(function (resolve, reject) {
        var gen = fn.apply(self, args);
  
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
  
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
  
        _next(undefined);
      });
    };
  }
  
  function _extends() {
    _extends = Object.assign || function (target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
  
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
  
      return target;
    };
  
    return _extends.apply(this, arguments);
  }
  
  function _inheritsLoose(subClass, superClass) {
    subClass.prototype = Object.create(superClass.prototype);
    subClass.prototype.constructor = subClass;
    subClass.__proto__ = superClass;
  }
  
  function createCommonjsModule(fn, module) {
  	return module = { exports: {} }, fn(module, module.exports), module.exports;
  }
  
  var runtime_1 = /*#__PURE__*/createCommonjsModule(function (module) {
    /**
     * Copyright (c) 2014-present, Facebook, Inc.
     *
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
     */
    var runtime = function (exports) {
  
      var Op = Object.prototype;
      var hasOwn = Op.hasOwnProperty;
      var undefined$1; // More compressible than void 0.
  
      var $Symbol = typeof Symbol === "function" ? Symbol : {};
      var iteratorSymbol = $Symbol.iterator || "@@iterator";
      var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
      var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  
      function define(obj, key, value) {
        Object.defineProperty(obj, key, {
          value: value,
          enumerable: true,
          configurable: true,
          writable: true
        });
        return obj[key];
      }
  
      try {
        // IE 8 has a broken Object.defineProperty that only works on DOM objects.
        define({}, "");
      } catch (err) {
        define = function define(obj, key, value) {
          return obj[key] = value;
        };
      }
  
      function wrap(innerFn, outerFn, self, tryLocsList) {
        // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
        var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
        var generator = Object.create(protoGenerator.prototype);
        var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
        // .throw, and .return methods.
  
        generator._invoke = makeInvokeMethod(innerFn, self, context);
        return generator;
      }
  
      exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
      // record like context.tryEntries[i].completion. This interface could
      // have been (and was previously) designed to take a closure to be
      // invoked without arguments, but in all the cases we care about we
      // already have an existing method we want to call, so there's no need
      // to create a new function object. We can even get away with assuming
      // the method takes exactly one argument, since that happens to be true
      // in every case, so we don't have to touch the arguments object. The
      // only additional allocation required is the completion record, which
      // has a stable shape and so hopefully should be cheap to allocate.
  
      function tryCatch(fn, obj, arg) {
        try {
          return {
            type: "normal",
            arg: fn.call(obj, arg)
          };
        } catch (err) {
          return {
            type: "throw",
            arg: err
          };
        }
      }
  
      var GenStateSuspendedStart = "suspendedStart";
      var GenStateSuspendedYield = "suspendedYield";
      var GenStateExecuting = "executing";
      var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
      // breaking out of the dispatch switch statement.
  
      var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
      // .constructor.prototype properties for functions that return Generator
      // objects. For full spec compliance, you may wish to configure your
      // minifier not to mangle the names of these two functions.
  
      function Generator() {}
  
      function GeneratorFunction() {}
  
      function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
      // don't natively support it.
  
  
      var IteratorPrototype = {};
  
      IteratorPrototype[iteratorSymbol] = function () {
        return this;
      };
  
      var getProto = Object.getPrototypeOf;
      var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  
      if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
        // This environment has a native %IteratorPrototype%; use it instead
        // of the polyfill.
        IteratorPrototype = NativeIteratorPrototype;
      }
  
      var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
      GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
      GeneratorFunctionPrototype.constructor = GeneratorFunction;
      GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the
      // Iterator interface in terms of a single ._invoke method.
  
      function defineIteratorMethods(prototype) {
        ["next", "throw", "return"].forEach(function (method) {
          define(prototype, method, function (arg) {
            return this._invoke(method, arg);
          });
        });
      }
  
      exports.isGeneratorFunction = function (genFun) {
        var ctor = typeof genFun === "function" && genFun.constructor;
        return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
      };
  
      exports.mark = function (genFun) {
        if (Object.setPrototypeOf) {
          Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
        } else {
          genFun.__proto__ = GeneratorFunctionPrototype;
          define(genFun, toStringTagSymbol, "GeneratorFunction");
        }
  
        genFun.prototype = Object.create(Gp);
        return genFun;
      }; // Within the body of any async function, `await x` is transformed to
      // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
      // `hasOwn.call(value, "__await")` to determine if the yielded value is
      // meant to be awaited.
  
  
      exports.awrap = function (arg) {
        return {
          __await: arg
        };
      };
  
      function AsyncIterator(generator, PromiseImpl) {
        function invoke(method, arg, resolve, reject) {
          var record = tryCatch(generator[method], generator, arg);
  
          if (record.type === "throw") {
            reject(record.arg);
          } else {
            var result = record.arg;
            var value = result.value;
  
            if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
              return PromiseImpl.resolve(value.__await).then(function (value) {
                invoke("next", value, resolve, reject);
              }, function (err) {
                invoke("throw", err, resolve, reject);
              });
            }
  
            return PromiseImpl.resolve(value).then(function (unwrapped) {
              // When a yielded Promise is resolved, its final value becomes
              // the .value of the Promise<{value,done}> result for the
              // current iteration.
              result.value = unwrapped;
              resolve(result);
            }, function (error) {
              // If a rejected Promise was yielded, throw the rejection back
              // into the async generator function so it can be handled there.
              return invoke("throw", error, resolve, reject);
            });
          }
        }
  
        var previousPromise;
  
        function enqueue(method, arg) {
          function callInvokeWithMethodAndArg() {
            return new PromiseImpl(function (resolve, reject) {
              invoke(method, arg, resolve, reject);
            });
          }
  
          return previousPromise = // If enqueue has been called before, then we want to wait until
          // all previous Promises have been resolved before calling invoke,
          // so that results are always delivered in the correct order. If
          // enqueue has not been called before, then it is important to
          // call invoke immediately, without waiting on a callback to fire,
          // so that the async generator function has the opportunity to do
          // any necessary setup in a predictable way. This predictability
          // is why the Promise constructor synchronously invokes its
          // executor callback, and why async functions synchronously
          // execute code before the first await. Since we implement simple
          // async functions in terms of async generators, it is especially
          // important to get this right, even though it requires care.
          previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
        } // Define the unified helper method that is used to implement .next,
        // .throw, and .return (see defineIteratorMethods).
  
  
        this._invoke = enqueue;
      }
  
      defineIteratorMethods(AsyncIterator.prototype);
  
      AsyncIterator.prototype[asyncIteratorSymbol] = function () {
        return this;
      };
  
      exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
      // AsyncIterator objects; they just return a Promise for the value of
      // the final result produced by the iterator.
  
      exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
        if (PromiseImpl === void 0) PromiseImpl = Promise;
        var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
        return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
        : iter.next().then(function (result) {
          return result.done ? result.value : iter.next();
        });
      };
  
      function makeInvokeMethod(innerFn, self, context) {
        var state = GenStateSuspendedStart;
        return function invoke(method, arg) {
          if (state === GenStateExecuting) {
            throw new Error("Generator is already running");
          }
  
          if (state === GenStateCompleted) {
            if (method === "throw") {
              throw arg;
            } // Be forgiving, per 25.3.3.3.3 of the spec:
            // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
  
  
            return doneResult();
          }
  
          context.method = method;
          context.arg = arg;
  
          while (true) {
            var delegate = context.delegate;
  
            if (delegate) {
              var delegateResult = maybeInvokeDelegate(delegate, context);
  
              if (delegateResult) {
                if (delegateResult === ContinueSentinel) continue;
                return delegateResult;
              }
            }
  
            if (context.method === "next") {
              // Setting context._sent for legacy support of Babel's
              // function.sent implementation.
              context.sent = context._sent = context.arg;
            } else if (context.method === "throw") {
              if (state === GenStateSuspendedStart) {
                state = GenStateCompleted;
                throw context.arg;
              }
  
              context.dispatchException(context.arg);
            } else if (context.method === "return") {
              context.abrupt("return", context.arg);
            }
  
            state = GenStateExecuting;
            var record = tryCatch(innerFn, self, context);
  
            if (record.type === "normal") {
              // If an exception is thrown from innerFn, we leave state ===
              // GenStateExecuting and loop back for another invocation.
              state = context.done ? GenStateCompleted : GenStateSuspendedYield;
  
              if (record.arg === ContinueSentinel) {
                continue;
              }
  
              return {
                value: record.arg,
                done: context.done
              };
            } else if (record.type === "throw") {
              state = GenStateCompleted; // Dispatch the exception by looping back around to the
              // context.dispatchException(context.arg) call above.
  
              context.method = "throw";
              context.arg = record.arg;
            }
          }
        };
      } // Call delegate.iterator[context.method](context.arg) and handle the
      // result, either by returning a { value, done } result from the
      // delegate iterator, or by modifying context.method and context.arg,
      // setting context.delegate to null, and returning the ContinueSentinel.
  
  
      function maybeInvokeDelegate(delegate, context) {
        var method = delegate.iterator[context.method];
  
        if (method === undefined$1) {
          // A .throw or .return when the delegate iterator has no .throw
          // method always terminates the yield* loop.
          context.delegate = null;
  
          if (context.method === "throw") {
            // Note: ["return"] must be used for ES3 parsing compatibility.
            if (delegate.iterator["return"]) {
              // If the delegate iterator has a return method, give it a
              // chance to clean up.
              context.method = "return";
              context.arg = undefined$1;
              maybeInvokeDelegate(delegate, context);
  
              if (context.method === "throw") {
                // If maybeInvokeDelegate(context) changed context.method from
                // "return" to "throw", let that override the TypeError below.
                return ContinueSentinel;
              }
            }
  
            context.method = "throw";
            context.arg = new TypeError("The iterator does not provide a 'throw' method");
          }
  
          return ContinueSentinel;
        }
  
        var record = tryCatch(method, delegate.iterator, context.arg);
  
        if (record.type === "throw") {
          context.method = "throw";
          context.arg = record.arg;
          context.delegate = null;
          return ContinueSentinel;
        }
  
        var info = record.arg;
  
        if (!info) {
          context.method = "throw";
          context.arg = new TypeError("iterator result is not an object");
          context.delegate = null;
          return ContinueSentinel;
        }
  
        if (info.done) {
          // Assign the result of the finished delegate to the temporary
          // variable specified by delegate.resultName (see delegateYield).
          context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
  
          context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
          // exception, let the outer generator proceed normally. If
          // context.method was "next", forget context.arg since it has been
          // "consumed" by the delegate iterator. If context.method was
          // "return", allow the original .return call to continue in the
          // outer generator.
  
          if (context.method !== "return") {
            context.method = "next";
            context.arg = undefined$1;
          }
        } else {
          // Re-yield the result returned by the delegate method.
          return info;
        } // The delegate iterator is finished, so forget it and continue with
        // the outer generator.
  
  
        context.delegate = null;
        return ContinueSentinel;
      } // Define Generator.prototype.{next,throw,return} in terms of the
      // unified ._invoke helper method.
  
  
      defineIteratorMethods(Gp);
      define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the
      // @@iterator function is called on it. Some browsers' implementations of the
      // iterator prototype chain incorrectly implement this, causing the Generator
      // object to not be returned from this call. This ensures that doesn't happen.
      // See https://github.com/facebook/regenerator/issues/274 for more details.
  
      Gp[iteratorSymbol] = function () {
        return this;
      };
  
      Gp.toString = function () {
        return "[object Generator]";
      };
  
      function pushTryEntry(locs) {
        var entry = {
          tryLoc: locs[0]
        };
  
        if (1 in locs) {
          entry.catchLoc = locs[1];
        }
  
        if (2 in locs) {
          entry.finallyLoc = locs[2];
          entry.afterLoc = locs[3];
        }
  
        this.tryEntries.push(entry);
      }
  
      function resetTryEntry(entry) {
        var record = entry.completion || {};
        record.type = "normal";
        delete record.arg;
        entry.completion = record;
      }
  
      function Context(tryLocsList) {
        // The root entry object (effectively a try statement without a catch
        // or a finally block) gives us a place to store values thrown from
        // locations where there is no enclosing try statement.
        this.tryEntries = [{
          tryLoc: "root"
        }];
        tryLocsList.forEach(pushTryEntry, this);
        this.reset(true);
      }
  
      exports.keys = function (object) {
        var keys = [];
  
        for (var key in object) {
          keys.push(key);
        }
  
        keys.reverse(); // Rather than returning an object with a next method, we keep
        // things simple and return the next function itself.
  
        return function next() {
          while (keys.length) {
            var key = keys.pop();
  
            if (key in object) {
              next.value = key;
              next.done = false;
              return next;
            }
          } // To avoid creating an additional object, we just hang the .value
          // and .done properties off the next function object itself. This
          // also ensures that the minifier will not anonymize the function.
  
  
          next.done = true;
          return next;
        };
      };
  
      function values(iterable) {
        if (iterable) {
          var iteratorMethod = iterable[iteratorSymbol];
  
          if (iteratorMethod) {
            return iteratorMethod.call(iterable);
          }
  
          if (typeof iterable.next === "function") {
            return iterable;
          }
  
          if (!isNaN(iterable.length)) {
            var i = -1,
                next = function next() {
              while (++i < iterable.length) {
                if (hasOwn.call(iterable, i)) {
                  next.value = iterable[i];
                  next.done = false;
                  return next;
                }
              }
  
              next.value = undefined$1;
              next.done = true;
              return next;
            };
  
            return next.next = next;
          }
        } // Return an iterator with no values.
  
  
        return {
          next: doneResult
        };
      }
  
      exports.values = values;
  
      function doneResult() {
        return {
          value: undefined$1,
          done: true
        };
      }
  
      Context.prototype = {
        constructor: Context,
        reset: function reset(skipTempReset) {
          this.prev = 0;
          this.next = 0; // Resetting context._sent for legacy support of Babel's
          // function.sent implementation.
  
          this.sent = this._sent = undefined$1;
          this.done = false;
          this.delegate = null;
          this.method = "next";
          this.arg = undefined$1;
          this.tryEntries.forEach(resetTryEntry);
  
          if (!skipTempReset) {
            for (var name in this) {
              // Not sure about the optimal order of these conditions:
              if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
                this[name] = undefined$1;
              }
            }
          }
        },
        stop: function stop() {
          this.done = true;
          var rootEntry = this.tryEntries[0];
          var rootRecord = rootEntry.completion;
  
          if (rootRecord.type === "throw") {
            throw rootRecord.arg;
          }
  
          return this.rval;
        },
        dispatchException: function dispatchException(exception) {
          if (this.done) {
            throw exception;
          }
  
          var context = this;
  
          function handle(loc, caught) {
            record.type = "throw";
            record.arg = exception;
            context.next = loc;
  
            if (caught) {
              // If the dispatched exception was caught by a catch block,
              // then let that catch block handle the exception normally.
              context.method = "next";
              context.arg = undefined$1;
            }
  
            return !!caught;
          }
  
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
            var record = entry.completion;
  
            if (entry.tryLoc === "root") {
              // Exception thrown outside of any try block that could handle
              // it, so set the completion value of the entire function to
              // throw the exception.
              return handle("end");
            }
  
            if (entry.tryLoc <= this.prev) {
              var hasCatch = hasOwn.call(entry, "catchLoc");
              var hasFinally = hasOwn.call(entry, "finallyLoc");
  
              if (hasCatch && hasFinally) {
                if (this.prev < entry.catchLoc) {
                  return handle(entry.catchLoc, true);
                } else if (this.prev < entry.finallyLoc) {
                  return handle(entry.finallyLoc);
                }
              } else if (hasCatch) {
                if (this.prev < entry.catchLoc) {
                  return handle(entry.catchLoc, true);
                }
              } else if (hasFinally) {
                if (this.prev < entry.finallyLoc) {
                  return handle(entry.finallyLoc);
                }
              } else {
                throw new Error("try statement without catch or finally");
              }
            }
          }
        },
        abrupt: function abrupt(type, arg) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
  
            if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
              var finallyEntry = entry;
              break;
            }
          }
  
          if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
            // Ignore the finally entry if control is not jumping to a
            // location outside the try/catch block.
            finallyEntry = null;
          }
  
          var record = finallyEntry ? finallyEntry.completion : {};
          record.type = type;
          record.arg = arg;
  
          if (finallyEntry) {
            this.method = "next";
            this.next = finallyEntry.finallyLoc;
            return ContinueSentinel;
          }
  
          return this.complete(record);
        },
        complete: function complete(record, afterLoc) {
          if (record.type === "throw") {
            throw record.arg;
          }
  
          if (record.type === "break" || record.type === "continue") {
            this.next = record.arg;
          } else if (record.type === "return") {
            this.rval = this.arg = record.arg;
            this.method = "return";
            this.next = "end";
          } else if (record.type === "normal" && afterLoc) {
            this.next = afterLoc;
          }
  
          return ContinueSentinel;
        },
        finish: function finish(finallyLoc) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
  
            if (entry.finallyLoc === finallyLoc) {
              this.complete(entry.completion, entry.afterLoc);
              resetTryEntry(entry);
              return ContinueSentinel;
            }
          }
        },
        "catch": function _catch(tryLoc) {
          for (var i = this.tryEntries.length - 1; i >= 0; --i) {
            var entry = this.tryEntries[i];
  
            if (entry.tryLoc === tryLoc) {
              var record = entry.completion;
  
              if (record.type === "throw") {
                var thrown = record.arg;
                resetTryEntry(entry);
              }
  
              return thrown;
            }
          } // The context.catch method must only be called with a location
          // argument that corresponds to a known catch block.
  
  
          throw new Error("illegal catch attempt");
        },
        delegateYield: function delegateYield(iterable, resultName, nextLoc) {
          this.delegate = {
            iterator: values(iterable),
            resultName: resultName,
            nextLoc: nextLoc
          };
  
          if (this.method === "next") {
            // Deliberately forget the last sent value so that we don't
            // accidentally pass it on to the delegate.
            this.arg = undefined$1;
          }
  
          return ContinueSentinel;
        }
      }; // Regardless of whether this script is executing as a CommonJS module
      // or not, return the runtime object so that we can declare the variable
      // regeneratorRuntime in the outer scope, which allows this module to be
      // injected easily by `bin/regenerator --include-runtime script.js`.
  
      return exports;
    }( // If this script is executing as a CommonJS module, use module.exports
    // as the regeneratorRuntime namespace. Otherwise create a new empty
    // object. Either way, the resulting object will be used to initialize
    // the regeneratorRuntime variable at the top of this file.
     module.exports );
  
    try {
      regeneratorRuntime = runtime;
    } catch (accidentalStrictMode) {
      // This module should not be running in strict mode, so the above
      // assignment should always work unless something is misconfigured. Just
      // in case runtime.js accidentally runs in strict mode, we can escape
      // strict mode using a global Function call. This could conceivably fail
      // if a Content Security Policy forbids using Function, but in that case
      // the proper solution is to fix the accidental strict mode problem. If
      // you've misconfigured your bundler to force strict mode and applied a
      // CSP to forbid Function, and you're not willing to fix either of those
      // problems, please detail your unique predicament in a GitHub issue.
      Function("r", "regeneratorRuntime = r")(runtime);
    }
  });
  
  function makeDIDFromAddress(address) {
    return "did:btc-addr:" + address;
  }
  function makeDIDFromPublicKey(publicKey) {
    return "did:ecdsa-pub:" + publicKey;
  }
  function getDIDType(decentralizedID) {
    var didParts = decentralizedID.split(':');
  
    if (didParts.length !== 3) {
      throw new common.InvalidDIDError('Decentralized IDs must have 3 parts');
    }
  
    if (didParts[0].toLowerCase() !== 'did') {
      throw new common.InvalidDIDError('Decentralized IDs must start with "did"');
    }
  
    return didParts[1].toLowerCase();
  }
  function getAddressFromDID(decentralizedID) {
    if (decentralizedID) {
      var didType = getDIDType(decentralizedID);
  
      if (didType === 'btc-addr') {
        return decentralizedID.split(':')[2];
      } else {
        return undefined;
      }
    }
  
    return undefined;
  }
  
  var VERSION = '1.3.1';
  function generateTransitKey() {
    var transitKey = encryption.makeECPrivateKey();
    return transitKey;
  }
  function makeAuthRequest(transitPrivateKey, redirectURI, manifestURI, scopes, appDomain, expiresAt, extraParams) {
    if (scopes === void 0) {
      scopes = DEFAULT_SCOPE.slice();
    }
  
    if (expiresAt === void 0) {
      expiresAt = common.nextMonth().getTime();
    }
  
    if (extraParams === void 0) {
      extraParams = {};
    }
  
    var getWindowOrigin = function getWindowOrigin(paramName) {
      var location = common.getGlobalObject('location', {
        throwIfUnavailable: true,
        usageDesc: "makeAuthRequest([" + paramName + "=undefined])"
      });
      return location == null ? void 0 : location.origin;
    };
  
    if (!redirectURI) {
      redirectURI = getWindowOrigin('redirectURI') + "/";
    }
  
    if (!manifestURI) {
      manifestURI = getWindowOrigin('manifestURI') + "/manifest.json";
    }
  
    if (!appDomain) {
      appDomain = getWindowOrigin('appDomain');
    }
  
    var payload = Object.assign({}, extraParams, {
      jti: common.makeUUID4(),
      iat: Math.floor(new Date().getTime() / 1000),
      exp: Math.floor(expiresAt / 1000),
      iss: null,
      public_keys: [],
      domain_name: appDomain,
      manifest_uri: manifestURI,
      redirect_uri: redirectURI,
      version: VERSION,
      do_not_include_profile: true,
      supports_hub_url: true,
      scopes: scopes
    });
    var publicKey = jsontokens.SECP256K1Client.derivePublicKey(transitPrivateKey);
    payload.public_keys = [publicKey];
    var address = encryption.publicKeyToAddress(publicKey);
    payload.iss = makeDIDFromAddress(address);
    var tokenSigner = new jsontokens.TokenSigner('ES256k', transitPrivateKey);
    var token = tokenSigner.sign(payload);
    return token;
  }
  function encryptPrivateKey(_x, _x2) {
    return _encryptPrivateKey.apply(this, arguments);
  }
  
  function _encryptPrivateKey() {
    _encryptPrivateKey = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(publicKey, privateKey) {
      var encryptedObj, encryptedJSON;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return encryption.encryptECIES(publicKey, Buffer.from(privateKey), true);
  
            case 2:
              encryptedObj = _context.sent;
              encryptedJSON = JSON.stringify(encryptedObj);
              return _context.abrupt("return", Buffer.from(encryptedJSON).toString('hex'));
  
            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return _encryptPrivateKey.apply(this, arguments);
  }
  
  function decryptPrivateKey(_x3, _x4) {
    return _decryptPrivateKey.apply(this, arguments);
  }
  
  function _decryptPrivateKey() {
    _decryptPrivateKey = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(privateKey, hexedEncrypted) {
      var unhexedString, encryptedObj, decrypted;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              unhexedString = Buffer.from(hexedEncrypted, 'hex').toString();
              encryptedObj = JSON.parse(unhexedString);
              _context2.next = 4;
              return encryption.decryptECIES(privateKey, encryptedObj);
  
            case 4:
              decrypted = _context2.sent;
  
              if (!(typeof decrypted !== 'string')) {
                _context2.next = 9;
                break;
              }
  
              throw new Error('Unable to correctly decrypt private key');
  
            case 9:
              return _context2.abrupt("return", decrypted);
  
            case 10:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    }));
    return _decryptPrivateKey.apply(this, arguments);
  }
  
  function makeAuthResponse(_x5, _x6, _x7, _x8, _x9, _x10, _x11, _x12, _x13, _x14, _x15) {
    return _makeAuthResponse.apply(this, arguments);
  }
  
  function _makeAuthResponse() {
    _makeAuthResponse = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(privateKey, profile, username, metadata, coreToken, appPrivateKey, expiresAt, transitPublicKey, hubUrl, blockstackAPIUrl, associationToken) {
      var publicKey, address, privateKeyPayload, coreTokenPayload, additionalProperties, payload, tokenSigner;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (profile === void 0) {
                profile = {};
              }
  
              if (username === void 0) {
                username = null;
              }
  
              if (coreToken === void 0) {
                coreToken = null;
              }
  
              if (appPrivateKey === void 0) {
                appPrivateKey = null;
              }
  
              if (expiresAt === void 0) {
                expiresAt = common.nextMonth().getTime();
              }
  
              if (transitPublicKey === void 0) {
                transitPublicKey = null;
              }
  
              if (hubUrl === void 0) {
                hubUrl = null;
              }
  
              if (blockstackAPIUrl === void 0) {
                blockstackAPIUrl = null;
              }
  
              if (associationToken === void 0) {
                associationToken = null;
              }
  
              publicKey = jsontokens.SECP256K1Client.derivePublicKey(privateKey);
              address = encryption.publicKeyToAddress(publicKey);
              privateKeyPayload = appPrivateKey;
              coreTokenPayload = coreToken;
              additionalProperties = {};
  
              if (!(appPrivateKey !== undefined && appPrivateKey !== null)) {
                _context3.next = 26;
                break;
              }
  
              if (!(transitPublicKey !== undefined && transitPublicKey !== null)) {
                _context3.next = 23;
                break;
              }
  
              _context3.next = 18;
              return encryptPrivateKey(transitPublicKey, appPrivateKey);
  
            case 18:
              privateKeyPayload = _context3.sent;
  
              if (!(coreToken !== undefined && coreToken !== null)) {
                _context3.next = 23;
                break;
              }
  
              _context3.next = 22;
              return encryptPrivateKey(transitPublicKey, coreToken);
  
            case 22:
              coreTokenPayload = _context3.sent;
  
            case 23:
              additionalProperties = {
                email: (metadata == null ? void 0 : metadata.email) ? metadata.email : null,
                profile_url: (metadata == null ? void 0 : metadata.profileUrl) ? metadata.profileUrl : null,
                hubUrl: hubUrl,
                blockstackAPIUrl: blockstackAPIUrl,
                associationToken: associationToken,
                version: VERSION
              };
              _context3.next = 26;
              break;
  
            case 26:
              payload = Object.assign({}, {
                jti: common.makeUUID4(),
                iat: Math.floor(new Date().getTime() / 1000),
                exp: Math.floor(expiresAt / 1000),
                iss: makeDIDFromAddress(address),
                private_key: privateKeyPayload,
                public_keys: [publicKey],
                profile: profile,
                username: username,
                core_token: coreTokenPayload
              }, additionalProperties);
              tokenSigner = new jsontokens.TokenSigner('ES256k', privateKey);
              return _context3.abrupt("return", tokenSigner.sign(payload));
  
            case 29:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3);
    }));
    return _makeAuthResponse.apply(this, arguments);
  }
  
  function getAuthRequestFromURL() {
    var location = common.getGlobalObject('location', {
      throwIfUnavailable: true,
      usageDesc: 'getAuthRequestFromURL'
    });
  
    if (location == null ? void 0 : location.search) {
      var queryDict = queryString.parse(location == null ? void 0 : location.search);
  
      if (queryDict.authRequest) {
        return queryDict.authRequest.split(common.BLOCKSTACK_HANDLER + ":").join('');
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
  function fetchAppManifest(_x) {
    return _fetchAppManifest.apply(this, arguments);
  }
  
  function _fetchAppManifest() {
    _fetchAppManifest = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(authRequest) {
      var payload, manifestURI, response, responseText, responseJSON;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (authRequest) {
                _context.next = 2;
                break;
              }
  
              throw new Error('Invalid auth request');
  
            case 2:
              payload = jsontokens.decodeToken(authRequest).payload;
  
              if (!(typeof payload === 'string')) {
                _context.next = 5;
                break;
              }
  
              throw new Error('Unexpected token payload type of string');
  
            case 5:
              manifestURI = payload.manifest_uri;
              _context.prev = 6;
              _context.next = 9;
              return common.fetchPrivate(manifestURI);
  
            case 9:
              response = _context.sent;
              _context.next = 12;
              return response.text();
  
            case 12:
              responseText = _context.sent;
              responseJSON = JSON.parse(responseText);
              return _context.abrupt("return", _extends({}, responseJSON, {
                manifestURI: manifestURI
              }));
  
            case 17:
              _context.prev = 17;
              _context.t0 = _context["catch"](6);
              console.log(_context.t0);
              throw new Error('Could not fetch manifest.json');
  
            case 21:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, null, [[6, 17]]);
    }));
    return _fetchAppManifest.apply(this, arguments);
  }
  
  function doSignaturesMatchPublicKeys(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    var publicKeys = payload.public_keys;
  
    if (publicKeys.length === 1) {
      var publicKey = publicKeys[0];
  
      try {
        var tokenVerifier = new jsontokens.TokenVerifier('ES256k', publicKey);
        return tokenVerifier.verify(token);
      } catch (e) {
        return false;
      }
    } else {
      throw new Error('Multiple public keys are not supported');
    }
  }
  function doPublicKeysMatchIssuer(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    var publicKeys = payload.public_keys;
    var addressFromIssuer = getAddressFromDID(payload.iss);
  
    if (publicKeys.length === 1) {
      var addressFromPublicKeys = encryption.publicKeyToAddress(publicKeys[0]);
  
      if (addressFromPublicKeys === addressFromIssuer) {
        return true;
      }
    } else {
      throw new Error('Multiple public keys are not supported');
    }
  
    return false;
  }
  function doPublicKeysMatchUsername(_x, _x2) {
    return _doPublicKeysMatchUsername.apply(this, arguments);
  }
  
  function _doPublicKeysMatchUsername() {
    _doPublicKeysMatchUsername = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(token, nameLookupURL) {
      var payload, username, url, response, responseText, responseJSON, nameOwningAddress, addressFromIssuer;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.prev = 0;
              payload = jsontokens.decodeToken(token).payload;
  
              if (!(typeof payload === 'string')) {
                _context.next = 4;
                break;
              }
  
              throw new Error('Unexpected token payload type of string');
  
            case 4:
              if (payload.username) {
                _context.next = 6;
                break;
              }
  
              return _context.abrupt("return", true);
  
            case 6:
              if (!(payload.username === null)) {
                _context.next = 8;
                break;
              }
  
              return _context.abrupt("return", true);
  
            case 8:
              if (!(nameLookupURL === null)) {
                _context.next = 10;
                break;
              }
  
              return _context.abrupt("return", false);
  
            case 10:
              username = payload.username;
              url = nameLookupURL.replace(/\/$/, '') + "/" + username;
              _context.next = 14;
              return common.fetchPrivate(url);
  
            case 14:
              response = _context.sent;
              _context.next = 17;
              return response.text();
  
            case 17:
              responseText = _context.sent;
              responseJSON = JSON.parse(responseText);
  
              if (!responseJSON.hasOwnProperty('address')) {
                _context.next = 29;
                break;
              }
  
              nameOwningAddress = responseJSON.address;
              addressFromIssuer = getAddressFromDID(payload.iss);
  
              if (!(nameOwningAddress === addressFromIssuer)) {
                _context.next = 26;
                break;
              }
  
              return _context.abrupt("return", true);
  
            case 26:
              return _context.abrupt("return", false);
  
            case 27:
              _context.next = 30;
              break;
  
            case 29:
              return _context.abrupt("return", false);
  
            case 30:
              _context.next = 37;
              break;
  
            case 32:
              _context.prev = 32;
              _context.t0 = _context["catch"](0);
              console.log(_context.t0);
              console.log('Error checking `doPublicKeysMatchUsername`');
              return _context.abrupt("return", false);
  
            case 37:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, null, [[0, 32]]);
    }));
    return _doPublicKeysMatchUsername.apply(this, arguments);
  }
  
  function isIssuanceDateValid(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    if (payload.iat) {
      if (typeof payload.iat !== 'number') {
        return false;
      }
  
      var issuedAt = new Date(payload.iat * 1000);
  
      if (new Date().getTime() < issuedAt.getTime()) {
        return false;
      } else {
        return true;
      }
    } else {
      return true;
    }
  }
  function isExpirationDateValid(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    if (payload.exp) {
      if (typeof payload.exp !== 'number') {
        return false;
      }
  
      var expiresAt = new Date(payload.exp * 1000);
  
      if (new Date().getTime() > expiresAt.getTime()) {
        return false;
      } else {
        return true;
      }
    } else {
      return true;
    }
  }
  function isManifestUriValid(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    return common.isSameOriginAbsoluteUrl(payload.domain_name, payload.manifest_uri);
  }
  function isRedirectUriValid(token) {
    var payload = jsontokens.decodeToken(token).payload;
  
    if (typeof payload === 'string') {
      throw new Error('Unexpected token payload type of string');
    }
  
    return common.isSameOriginAbsoluteUrl(payload.domain_name, payload.redirect_uri);
  }
  function verifyAuthRequest(_x3) {
    return _verifyAuthRequest.apply(this, arguments);
  }
  
  function _verifyAuthRequest() {
    _verifyAuthRequest = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(token) {
      var values;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (!(jsontokens.decodeToken(token).header.alg === 'none')) {
                _context2.next = 2;
                break;
              }
  
              throw new Error('Token must be signed in order to be verified');
  
            case 2:
              _context2.next = 4;
              return Promise.all([isExpirationDateValid(token), isIssuanceDateValid(token), doSignaturesMatchPublicKeys(token), doPublicKeysMatchIssuer(token), isManifestUriValid(token), isRedirectUriValid(token)]);
  
            case 4:
              values = _context2.sent;
              return _context2.abrupt("return", values.every(function (val) {
                return val;
              }));
  
            case 6:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    }));
    return _verifyAuthRequest.apply(this, arguments);
  }
  
  function verifyAuthRequestAndLoadManifest(_x4) {
    return _verifyAuthRequestAndLoadManifest.apply(this, arguments);
  }
  
  function _verifyAuthRequestAndLoadManifest() {
    _verifyAuthRequestAndLoadManifest = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(token) {
      var valid;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return verifyAuthRequest(token);
  
            case 2:
              valid = _context3.sent;
  
              if (valid) {
                _context3.next = 5;
                break;
              }
  
              throw new Error('Token is an invalid auth request');
  
            case 5:
              return _context3.abrupt("return", fetchAppManifest(token));
  
            case 6:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3);
    }));
    return _verifyAuthRequestAndLoadManifest.apply(this, arguments);
  }
  
  function verifyAuthResponse(_x5, _x6) {
    return _verifyAuthResponse.apply(this, arguments);
  }
  
  function _verifyAuthResponse() {
    _verifyAuthResponse = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(token, nameLookupURL) {
      var values;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return Promise.all([isExpirationDateValid(token), isIssuanceDateValid(token), doSignaturesMatchPublicKeys(token), doPublicKeysMatchIssuer(token), doPublicKeysMatchUsername(token, nameLookupURL)]);
  
            case 2:
              values = _context4.sent;
              return _context4.abrupt("return", values.every(function (val) {
                return val;
              }));
  
            case 4:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4);
    }));
    return _verifyAuthResponse.apply(this, arguments);
  }
  
  var SESSION_VERSION = '1.0.0';
  var SessionData = /*#__PURE__*/function () {
    function SessionData(options) {
      this.version = SESSION_VERSION;
      this.userData = options.userData;
      this.transitKey = options.transitKey;
      this.etags = options.etags ? options.etags : {};
    }
  
    SessionData.fromJSON = function fromJSON(json) {
      if (json.version !== SESSION_VERSION) {
        throw new common.InvalidStateError("JSON data version " + json.version + " not supported by SessionData");
      }
  
      var options = {
        coreNode: json.coreNode,
        userData: json.userData,
        transitKey: json.transitKey,
        etags: json.etags
      };
      return new SessionData(options);
    };
  
    var _proto = SessionData.prototype;
  
    _proto.toString = function toString() {
      return JSON.stringify(this);
    };
  
    return SessionData;
  }();
  
  var SessionDataStore = /*#__PURE__*/function () {
    function SessionDataStore(sessionOptions) {
      if (sessionOptions) {
        var newSessionData = new SessionData(sessionOptions);
        this.setSessionData(newSessionData);
      }
    }
  
    var _proto = SessionDataStore.prototype;
  
    _proto.getSessionData = function getSessionData() {
      throw new Error('Abstract class');
    };
  
    _proto.setSessionData = function setSessionData(session) {
      throw new Error('Abstract class');
    };
  
    _proto.deleteSessionData = function deleteSessionData() {
      throw new Error('Abstract class');
    };
  
    return SessionDataStore;
  }();
  var InstanceDataStore = /*#__PURE__*/function (_SessionDataStore) {
    _inheritsLoose(InstanceDataStore, _SessionDataStore);
  
    function InstanceDataStore(sessionOptions) {
      var _this;
  
      _this = _SessionDataStore.call(this, sessionOptions) || this;
  
      if (!_this.sessionData) {
        _this.setSessionData(new SessionData({}));
      }
  
      return _this;
    }
  
    var _proto2 = InstanceDataStore.prototype;
  
    _proto2.getSessionData = function getSessionData() {
      if (!this.sessionData) {
        throw new common.NoSessionDataError('No session data was found.');
      }
  
      return this.sessionData;
    };
  
    _proto2.setSessionData = function setSessionData(session) {
      this.sessionData = session;
      return true;
    };
  
    _proto2.deleteSessionData = function deleteSessionData() {
      this.setSessionData(new SessionData({}));
      return true;
    };
  
    return InstanceDataStore;
  }(SessionDataStore);
  var LocalStorageStore = /*#__PURE__*/function (_SessionDataStore2) {
    _inheritsLoose(LocalStorageStore, _SessionDataStore2);
  
    function LocalStorageStore(sessionOptions) {
      var _this2;
  
      _this2 = _SessionDataStore2.call(this, sessionOptions) || this;
  
      if (sessionOptions && sessionOptions.storeOptions && sessionOptions.storeOptions.localStorageKey && typeof sessionOptions.storeOptions.localStorageKey === 'string') {
        _this2.key = sessionOptions.storeOptions.localStorageKey;
      } else {
        _this2.key = LOCALSTORAGE_SESSION_KEY;
      }
  
      var data = localStorage.getItem(_this2.key);
  
      if (!data) {
        var sessionData = new SessionData({});
  
        _this2.setSessionData(sessionData);
      }
  
      return _this2;
    }
  
    var _proto3 = LocalStorageStore.prototype;
  
    _proto3.getSessionData = function getSessionData() {
      var data = localStorage.getItem(this.key);
  
      if (!data) {
        throw new common.NoSessionDataError('No session data was found in localStorage');
      }
  
      var dataJSON = JSON.parse(data);
      return SessionData.fromJSON(dataJSON);
    };
  
    _proto3.setSessionData = function setSessionData(session) {
      localStorage.setItem(this.key, session.toString());
      return true;
    };
  
    _proto3.deleteSessionData = function deleteSessionData() {
      localStorage.removeItem(this.key);
      this.setSessionData(new SessionData({}));
      return true;
    };
  
    return LocalStorageStore;
  }(SessionDataStore);
  
  var GLOBAL_DETECTION_CACHE_KEY = '_blockstackDidCheckEchoReply';
  var ECHO_REPLY_PARAM = 'echoReply';
  var AUTH_CONTINUATION_PARAM = 'authContinuation';
  
  function getQueryStringParams(query) {
    if (!query) {
      return {};
    }
  
    var trimmed = /^[?#]/.test(query) ? query.slice(1) : query;
    return trimmed.split('&').reduce(function (params, param) {
      var _param$split = param.split('='),
          key = _param$split[0],
          value = _param$split[1];
  
      params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
      return params;
    }, {});
  }
  
  function protocolEchoReplyDetection() {
    var globalScope;
  
    if (typeof self !== 'undefined') {
      globalScope = self;
    } else if (typeof window !== 'undefined') {
      globalScope = window;
    } else {
      return false;
    }
  
    if (!globalScope.location || !globalScope.localStorage) {
      return false;
    }
  
    var existingDetection = globalScope[GLOBAL_DETECTION_CACHE_KEY];
  
    if (typeof existingDetection === 'boolean') {
      return existingDetection;
    }
  
    var searchParams = getQueryStringParams(globalScope.location.search);
    var echoReplyParam = searchParams[ECHO_REPLY_PARAM];
  
    if (echoReplyParam) {
      globalScope[GLOBAL_DETECTION_CACHE_KEY] = true;
      var echoReplyKey = "echo-reply-" + echoReplyParam;
      globalScope.localStorage.setItem(echoReplyKey, 'success');
      globalScope.setTimeout(function () {
        var authContinuationParam = searchParams[AUTH_CONTINUATION_PARAM];
        globalScope.location.href = authContinuationParam;
      }, 10);
      return true;
    }
  
    return false;
  }
  
  var UserSession = /*#__PURE__*/function () {
    function UserSession(options) {
      var runningInBrowser = true;
  
      if (typeof window === 'undefined' && typeof self === 'undefined') {
        runningInBrowser = false;
      }
  
      if (options && options.appConfig) {
        this.appConfig = options.appConfig;
      } else if (runningInBrowser) {
        this.appConfig = new AppConfig();
      } else {
        throw new common.MissingParameterError('You need to specify options.appConfig');
      }
  
      if (options && options.sessionStore) {
        this.store = options.sessionStore;
      } else if (runningInBrowser) {
        if (options) {
          this.store = new LocalStorageStore(options.sessionOptions);
        } else {
          this.store = new LocalStorageStore();
        }
      } else if (options) {
        this.store = new InstanceDataStore(options.sessionOptions);
      } else {
        this.store = new InstanceDataStore();
      }
    }
  
    var _proto = UserSession.prototype;
  
    _proto.makeAuthRequest = function makeAuthRequest$1(transitKey, redirectURI, manifestURI, scopes, appDomain, expiresAt, extraParams) {
      if (expiresAt === void 0) {
        expiresAt = common.nextHour().getTime();
      }
  
      if (extraParams === void 0) {
        extraParams = {};
      }
  
      var appConfig = this.appConfig;
  
      if (!appConfig) {
        throw new common.InvalidStateError('Missing AppConfig');
      }
  
      transitKey = transitKey || this.generateAndStoreTransitKey();
      redirectURI = redirectURI || appConfig.redirectURI();
      manifestURI = manifestURI || appConfig.manifestURI();
      scopes = scopes || appConfig.scopes;
      appDomain = appDomain || appConfig.appDomain;
      return makeAuthRequest(transitKey, redirectURI, manifestURI, scopes, appDomain, expiresAt, extraParams);
    };
  
    _proto.generateAndStoreTransitKey = function generateAndStoreTransitKey() {
      var sessionData = this.store.getSessionData();
      var transitKey = generateTransitKey();
      sessionData.transitKey = transitKey;
      this.store.setSessionData(sessionData);
      return transitKey;
    };
  
    _proto.getAuthResponseToken = function getAuthResponseToken() {
      var _getGlobalObject;
  
      var search = (_getGlobalObject = common.getGlobalObject('location', {
        throwIfUnavailable: true,
        usageDesc: 'getAuthResponseToken'
      })) == null ? void 0 : _getGlobalObject.search;
  
      if (search) {
        var queryDict = queryString.parse(search);
        return queryDict.authResponse ? queryDict.authResponse : '';
      }
  
      return '';
    };
  
    _proto.isSignInPending = function isSignInPending() {
      try {
        var isProtocolEcho = protocolEchoReplyDetection();
  
        if (isProtocolEcho) {
          common.Logger.info('protocolEchoReply detected from isSignInPending call, the page is about to redirect.');
          return true;
        }
      } catch (error) {
        common.Logger.error("Error checking for protocol echo reply isSignInPending: " + error);
      }
  
      return !!this.getAuthResponseToken();
    };
  
    _proto.isUserSignedIn = function isUserSignedIn() {
      return !!this.store.getSessionData().userData;
    };
  
    _proto.handlePendingSignIn = /*#__PURE__*/function () {
      var _handlePendingSignIn = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(authResponseToken) {
        var sessionData, transitKey, coreNode, network$1, tokenPayload, nameLookupURL, isValid, appPrivateKey, coreSessionToken, hubUrl, gaiaAssociationToken, userData, profileURL, response, responseText, wrappedProfile;
        return runtime_1.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (authResponseToken === void 0) {
                  authResponseToken = /*#__PURE__*/this.getAuthResponseToken();
                }
  
                sessionData = this.store.getSessionData();
  
                if (!sessionData.userData) {
                  _context.next = 4;
                  break;
                }
  
                throw new common.LoginFailedError('Existing user session found.');
  
              case 4:
                transitKey = this.store.getSessionData().transitKey;
                coreNode = this.appConfig && this.appConfig.coreNode;
  
                if (!coreNode) {
                  network$1 = new network.StacksMainnet();
                  coreNode = network$1.bnsLookupUrl;
                }
  
                tokenPayload = jsontokens.decodeToken(authResponseToken).payload;
  
                if (!(typeof tokenPayload === 'string')) {
                  _context.next = 10;
                  break;
                }
  
                throw new Error('Unexpected token payload type of string');
  
              case 10:
                nameLookupURL = "" + coreNode + NAME_LOOKUP_PATH;
                _context.next = 13;
                return verifyAuthResponse(authResponseToken, nameLookupURL);
  
              case 13:
                isValid = _context.sent;
  
                if (isValid) {
                  _context.next = 16;
                  break;
                }
  
                throw new common.LoginFailedError('Invalid authentication response.');
  
              case 16:
                appPrivateKey = tokenPayload.private_key;
                coreSessionToken = tokenPayload.core_token;
  
                if (!common.isLaterVersion(tokenPayload.version, '1.1.0')) {
                  _context.next = 50;
                  break;
                }
  
                if (!(transitKey !== undefined && transitKey != null)) {
                  _context.next = 49;
                  break;
                }
  
                if (!(tokenPayload.private_key !== undefined && tokenPayload.private_key !== null)) {
                  _context.next = 37;
                  break;
                }
  
                _context.prev = 21;
                _context.next = 24;
                return decryptPrivateKey(transitKey, tokenPayload.private_key);
  
              case 24:
                appPrivateKey = _context.sent;
                _context.next = 37;
                break;
  
              case 27:
                _context.prev = 27;
                _context.t0 = _context["catch"](21);
                common.Logger.warn('Failed decryption of appPrivateKey, will try to use as given');
                _context.prev = 30;
                encryption.hexStringToECPair(tokenPayload.private_key);
                _context.next = 37;
                break;
  
              case 34:
                _context.prev = 34;
                _context.t1 = _context["catch"](30);
                throw new common.LoginFailedError('Failed decrypting appPrivateKey. Usually means' + ' that the transit key has changed during login.');
  
              case 37:
                if (!(coreSessionToken !== undefined && coreSessionToken !== null)) {
                  _context.next = 47;
                  break;
                }
  
                _context.prev = 38;
                _context.next = 41;
                return decryptPrivateKey(transitKey, coreSessionToken);
  
              case 41:
                coreSessionToken = _context.sent;
                _context.next = 47;
                break;
  
              case 44:
                _context.prev = 44;
                _context.t2 = _context["catch"](38);
                common.Logger.info('Failed decryption of coreSessionToken, will try to use as given');
  
              case 47:
                _context.next = 50;
                break;
  
              case 49:
                throw new common.LoginFailedError('Authenticating with protocol > 1.1.0 requires transit' + ' key, and none found.');
  
              case 50:
                hubUrl = common.BLOCKSTACK_DEFAULT_GAIA_HUB_URL;
  
                if (common.isLaterVersion(tokenPayload.version, '1.2.0') && tokenPayload.hubUrl !== null && tokenPayload.hubUrl !== undefined) {
                  hubUrl = tokenPayload.hubUrl;
                }
  
                if (common.isLaterVersion(tokenPayload.version, '1.3.0') && tokenPayload.associationToken !== null && tokenPayload.associationToken !== undefined) {
                  gaiaAssociationToken = tokenPayload.associationToken;
                }
  
                userData = {
                  username: tokenPayload.username,
                  profile: tokenPayload.profile,
                  email: tokenPayload.email,
                  decentralizedID: tokenPayload.iss,
                  identityAddress: getAddressFromDID(tokenPayload.iss),
                  appPrivateKey: appPrivateKey,
                  coreSessionToken: coreSessionToken,
                  authResponseToken: authResponseToken,
                  hubUrl: hubUrl,
                  coreNode: tokenPayload.blockstackAPIUrl,
                  gaiaAssociationToken: gaiaAssociationToken
                };
                profileURL = tokenPayload.profile_url;
  
                if (!(!userData.profile && profileURL)) {
                  _context.next = 70;
                  break;
                }
  
                _context.next = 58;
                return common.fetchPrivate(profileURL);
  
              case 58:
                response = _context.sent;
  
                if (response.ok) {
                  _context.next = 63;
                  break;
                }
  
                userData.profile = Object.assign({}, DEFAULT_PROFILE);
                _context.next = 68;
                break;
  
              case 63:
                _context.next = 65;
                return response.text();
  
              case 65:
                responseText = _context.sent;
                wrappedProfile = JSON.parse(responseText);
                userData.profile = profile.extractProfile(wrappedProfile[0].token);
  
              case 68:
                _context.next = 71;
                break;
  
              case 70:
                userData.profile = tokenPayload.profile;
  
              case 71:
                sessionData.userData = userData;
                this.store.setSessionData(sessionData);
                return _context.abrupt("return", userData);
  
              case 74:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this, [[21, 27], [30, 34], [38, 44]]);
      }));
  
      function handlePendingSignIn(_x) {
        return _handlePendingSignIn.apply(this, arguments);
      }
  
      return handlePendingSignIn;
    }();
  
    _proto.loadUserData = function loadUserData() {
      var userData = this.store.getSessionData().userData;
  
      if (!userData) {
        throw new common.InvalidStateError('No user data found. Did the user sign in?');
      }
  
      return userData;
    };
  
    _proto.encryptContent = function encryptContent(content, options) {
      var opts = Object.assign({}, options);
  
      if (!opts.privateKey) {
        opts.privateKey = this.loadUserData().appPrivateKey;
      }
  
      return encryption.encryptContent(content, opts);
    };
  
    _proto.decryptContent = function decryptContent(content, options) {
      var opts = Object.assign({}, options);
  
      if (!opts.privateKey) {
        opts.privateKey = this.loadUserData().appPrivateKey;
      }
  
      return encryption.decryptContent(content, opts);
    };
  
    _proto.signUserOut = function signUserOut(redirectURL) {
      this.store.deleteSessionData();
  
      if (redirectURL) {
        if (typeof location !== 'undefined' && location.href) {
          location.href = redirectURL;
        }
      }
    };
  
    return UserSession;
  }();
  
  function lookupProfile(options) {
    if (!options.username) {
      return Promise.reject();
    }
  
    var network$1 = options.network ? options.network : new network.StacksMainnet();
    var lookupPromise;
  
    if (options.zoneFileLookupURL) {
      var url = options.zoneFileLookupURL.replace(/\/$/, '') + "/" + options.username;
      lookupPromise = common.fetchPrivate(url).then(function (response) {
        return response.json();
      });
    } else {
      lookupPromise = network$1.getNameInfo(options.username);
    }
  
    return lookupPromise.then(function (responseJSON) {
      if (responseJSON.hasOwnProperty('zonefile') && responseJSON.hasOwnProperty('address')) {
        return profile.resolveZoneFileToProfile(responseJSON.zonefile, responseJSON.address);
      } else {
        throw new Error('Invalid zonefile lookup response: did not contain `address`' + ' or `zonefile` field');
      }
    });
  }
  
  exports.AppConfig = AppConfig;
  exports.BLOCKSTACK_APP_PRIVATE_KEY_LABEL = BLOCKSTACK_APP_PRIVATE_KEY_LABEL;
  exports.BLOCKSTACK_HANDLER = BLOCKSTACK_HANDLER;
  exports.BLOCKSTACK_STORAGE_LABEL = BLOCKSTACK_STORAGE_LABEL;
  exports.DEFAULT_BLOCKSTACK_HOST = DEFAULT_BLOCKSTACK_HOST;
  exports.DEFAULT_CORE_NODE = DEFAULT_CORE_NODE;
  exports.DEFAULT_PROFILE = DEFAULT_PROFILE;
  exports.DEFAULT_SCOPE = DEFAULT_SCOPE;
  exports.LOCALSTORAGE_SESSION_KEY = LOCALSTORAGE_SESSION_KEY;
  exports.NAME_LOOKUP_PATH = NAME_LOOKUP_PATH;
  exports.UserSession = UserSession;
  exports.decryptPrivateKey = decryptPrivateKey;
  exports.doPublicKeysMatchIssuer = doPublicKeysMatchIssuer;
  exports.doPublicKeysMatchUsername = doPublicKeysMatchUsername;
  exports.doSignaturesMatchPublicKeys = doSignaturesMatchPublicKeys;
  exports.fetchAppManifest = fetchAppManifest;
  exports.getAddressFromDID = getAddressFromDID;
  exports.getAuthRequestFromURL = getAuthRequestFromURL;
  exports.getDIDType = getDIDType;
  exports.isExpirationDateValid = isExpirationDateValid;
  exports.isIssuanceDateValid = isIssuanceDateValid;
  exports.isManifestUriValid = isManifestUriValid;
  exports.isRedirectUriValid = isRedirectUriValid;
  exports.lookupProfile = lookupProfile;
  exports.makeAuthRequest = makeAuthRequest;
  exports.makeAuthResponse = makeAuthResponse;
  exports.makeDIDFromAddress = makeDIDFromAddress;
  exports.makeDIDFromPublicKey = makeDIDFromPublicKey;
  exports.verifyAuthRequest = verifyAuthRequest;
  exports.verifyAuthRequestAndLoadManifest = verifyAuthRequestAndLoadManifest;
  exports.verifyAuthResponse = verifyAuthResponse;
  //# sourceMappingURL=auth.cjs.development.js.map
  