6340 lines
253 KiB
JavaScript
6340 lines
253 KiB
JavaScript
|
|
"use strict";
|
||
|
|
var __create = Object.create;
|
||
|
|
var __defProp = Object.defineProperty;
|
||
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
|
|
var __getProtoOf = Object.getPrototypeOf;
|
||
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
|
|
var __commonJS = (cb, mod3) => function __require() {
|
||
|
|
return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
|
||
|
|
};
|
||
|
|
var __export = (target, all) => {
|
||
|
|
for (var name in all)
|
||
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||
|
|
};
|
||
|
|
var __copyProps = (to, from3, except, desc) => {
|
||
|
|
if (from3 && typeof from3 === "object" || typeof from3 === "function") {
|
||
|
|
for (let key of __getOwnPropNames(from3))
|
||
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||
|
|
__defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable });
|
||
|
|
}
|
||
|
|
return to;
|
||
|
|
};
|
||
|
|
var __toESM = (mod3, isNodeMode, target) => (target = mod3 != null ? __create(__getProtoOf(mod3)) : {}, __copyProps(
|
||
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
||
|
|
// file that has been converted to a CommonJS file using a Babel-
|
||
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
||
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
||
|
|
isNodeMode || !mod3 || !mod3.__esModule ? __defProp(target, "default", { value: mod3, enumerable: true }) : target,
|
||
|
|
mod3
|
||
|
|
));
|
||
|
|
var __toCommonJS = (mod3) => __copyProps(__defProp({}, "__esModule", { value: true }), mod3);
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/uri-js@4.4.1/node_modules/uri-js/dist/es5/uri.all.js
|
||
|
|
var require_uri_all = __commonJS({
|
||
|
|
"../../node_modules/.pnpm/uri-js@4.4.1/node_modules/uri-js/dist/es5/uri.all.js"(exports, module2) {
|
||
|
|
(function(global, factory) {
|
||
|
|
typeof exports === "object" && typeof module2 !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : factory(global.URI = global.URI || {});
|
||
|
|
})(exports, function(exports2) {
|
||
|
|
"use strict";
|
||
|
|
function merge() {
|
||
|
|
for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) {
|
||
|
|
sets[_key] = arguments[_key];
|
||
|
|
}
|
||
|
|
if (sets.length > 1) {
|
||
|
|
sets[0] = sets[0].slice(0, -1);
|
||
|
|
var xl = sets.length - 1;
|
||
|
|
for (var x = 1; x < xl; ++x) {
|
||
|
|
sets[x] = sets[x].slice(1, -1);
|
||
|
|
}
|
||
|
|
sets[xl] = sets[xl].slice(1);
|
||
|
|
return sets.join("");
|
||
|
|
} else {
|
||
|
|
return sets[0];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function subexp(str3) {
|
||
|
|
return "(?:" + str3 + ")";
|
||
|
|
}
|
||
|
|
function typeOf(o) {
|
||
|
|
return o === void 0 ? "undefined" : o === null ? "null" : Object.prototype.toString.call(o).split(" ").pop().split("]").shift().toLowerCase();
|
||
|
|
}
|
||
|
|
function toUpperCase(str3) {
|
||
|
|
return str3.toUpperCase();
|
||
|
|
}
|
||
|
|
function toArray(obj) {
|
||
|
|
return obj !== void 0 && obj !== null ? obj instanceof Array ? obj : typeof obj.length !== "number" || obj.split || obj.setInterval || obj.call ? [obj] : Array.prototype.slice.call(obj) : [];
|
||
|
|
}
|
||
|
|
function assign(target, source) {
|
||
|
|
var obj = target;
|
||
|
|
if (source) {
|
||
|
|
for (var key in source) {
|
||
|
|
obj[key] = source[key];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return obj;
|
||
|
|
}
|
||
|
|
function buildExps(isIRI2) {
|
||
|
|
var ALPHA$$ = "[A-Za-z]", CR$ = "[\\x0D]", DIGIT$$ = "[0-9]", DQUOTE$$ = "[\\x22]", HEXDIG$$2 = merge(DIGIT$$, "[A-Fa-f]"), LF$$ = "[\\x0A]", SP$$ = "[\\x20]", PCT_ENCODED$2 = subexp(subexp("%[EFef]" + HEXDIG$$2 + "%" + HEXDIG$$2 + HEXDIG$$2 + "%" + HEXDIG$$2 + HEXDIG$$2) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$2 + "%" + HEXDIG$$2 + HEXDIG$$2) + "|" + subexp("%" + HEXDIG$$2 + HEXDIG$$2)), GEN_DELIMS$$ = "[\\:\\/\\?\\#\\[\\]\\@]", SUB_DELIMS$$ = "[\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=]", RESERVED$$ = merge(GEN_DELIMS$$, SUB_DELIMS$$), UCSCHAR$$ = isIRI2 ? "[\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]" : "[]", IPRIVATE$$ = isIRI2 ? "[\\uE000-\\uF8FF]" : "[]", UNRESERVED$$2 = merge(ALPHA$$, DIGIT$$, "[\\-\\.\\_\\~]", UCSCHAR$$), SCHEME$ = subexp(ALPHA$$ + merge(ALPHA$$, DIGIT$$, "[\\+\\-\\.]") + "*"), USERINFO$ = subexp(subexp(PCT_ENCODED$2 + "|" + merge(UNRESERVED$$2, SUB_DELIMS$$, "[\\:]")) + "*"), DEC_OCTET$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("[1-9]" + DIGIT$$) + "|" + DIGIT$$), DEC_OCTET_RELAXED$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("0?[1-9]" + DIGIT$$) + "|0?0?" + DIGIT$$), IPV4ADDRESS$ = subexp(DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$), H16$ = subexp(HEXDIG$$2 + "{1,4}"), LS32$ = subexp(subexp(H16$ + "\\:" + H16$) + "|" + IPV4ADDRESS$), IPV6ADDRESS1$ = subexp(subexp(H16$ + "\\:") + "{6}" + LS32$), IPV6ADDRESS2$ = subexp("\\:\\:" + subexp(H16$ + "\\:") + "{5}" + LS32$), IPV6ADDRESS3$ = subexp(subexp(H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{4}" + LS32$), IPV6ADDRESS4$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,1}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{3}" + LS32$), IPV6ADDRESS5$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,2}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{2}" + LS32$), IPV6ADDRESS6$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,3}" + H16$) + "?\\:\\:" + H16$ + "\\:" + LS32$), IPV6ADDRESS7$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,4}" + H16$) + "?\\:\\:" + LS32$), IPV6ADDRESS8$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,5}" + H16$) + "?\\:\\:" + H16$), IPV6ADDRESS9$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,6}" + H16$) + "?\\:\\:"), IPV6ADDRESS$ = subexp([IPV6ADDRESS1$, IPV6ADDRESS2$, IPV6ADDRESS3$, IPV6ADDRESS4$, IPV6ADDRESS5$, IPV6ADDRESS6$, IPV6ADDRESS7$, IPV6ADDRESS8$, IPV6ADDRESS9$].join("|")), ZONEID$ = subexp(subexp(UNRESERVED$$2 + "|" + PCT_ENCODED$2) + "+"), IPV6ADDRZ$ = subexp(IPV6ADDRESS$ + "\\%25" + ZONEID$), IPV6ADDRZ_RELAXED$ = subexp(IPV6ADDRESS$ + subexp("\\%25|\\%(?!" + HEXDIG$$2 + "{2})") + ZONEID$), IPVFUTURE$ = subexp("[vV]" + HEXDIG$$2 + "+\\." + merge(UNRESERVED$$2, SUB_DELIMS$$, "[\\:]") + "+"), IP_LITERAL$ = subexp("\\[" + subexp(IPV6ADDRZ_RELAXED$ + "|" + IPV6ADDRESS$ + "|" + IPVFUTURE$) + "\\]"), REG_NAME$ = subexp(subexp(PCT_ENCODED$2 + "|" + merge(UNRESERVED$$2, SUB_DELIMS$$)) + "*"), HOST$ = subexp(IP_LITERAL$ + "|" + IPV4ADDRESS$ + "(?!" + REG_NAME$ + ")|" + REG_NAME$), PORT$ = subexp(DIGIT$$ + "*"), AUTHORITY$ = subexp(subexp(USERINFO$ + "@") + "?" + HOST$ + subexp("\\:" + PORT$) + "?"), PCHAR$ = subexp(PCT_ENCODED$2 + "|" + merge(UNRESERVED$$2, SUB_DELIMS$$, "[\\:\\@]")), SEGMENT$ = subexp(PCHAR$ + "*"), SEGMENT_NZ$ = subexp(PCHAR$ + "+"), SEGMENT_NZ_NC$ = subexp(subexp(PCT_ENCODED$2 + "|" + merge(UNRESERVED$$2, SUB_DELIMS$$, "[\\@]")) + "+"), PATH_ABEMPTY$ = subexp(subexp("\\/" + SEGMENT$) + "*"), PATH_ABSOLUTE$ = subexp("\\/" + subexp(SEGMENT_NZ$ + PATH_ABEMPTY$) + "?"), PATH_NOSCHEME$ = subexp(SEGMENT_NZ_NC$ + PATH_ABEMPTY$), PATH_ROOTLESS$ = subexp(SEGMENT_NZ$ + PATH_ABEMPTY$), PATH_EMPTY$ = "(?!" + PCHAR$ + ")", PATH$ = subexp(PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), QUERY$ = subexp(subexp(PCHAR$ + "|" + merge("[\\/\\?]", IPRIVATE$$)) + "*"), FRAGMENT$ = subexp(subexp(PCHAR$ + "|[\\/\\?]") + "*"), HIER_PART$ = subexp(subexp("\\/\\/" + A
|
||
|
|
return {
|
||
|
|
NOT_SCHEME: new RegExp(merge("[^]", ALPHA$$, DIGIT$$, "[\\+\\-\\.]"), "g"),
|
||
|
|
NOT_USERINFO: new RegExp(merge("[^\\%\\:]", UNRESERVED$$2, SUB_DELIMS$$), "g"),
|
||
|
|
NOT_HOST: new RegExp(merge("[^\\%\\[\\]\\:]", UNRESERVED$$2, SUB_DELIMS$$), "g"),
|
||
|
|
NOT_PATH: new RegExp(merge("[^\\%\\/\\:\\@]", UNRESERVED$$2, SUB_DELIMS$$), "g"),
|
||
|
|
NOT_PATH_NOSCHEME: new RegExp(merge("[^\\%\\/\\@]", UNRESERVED$$2, SUB_DELIMS$$), "g"),
|
||
|
|
NOT_QUERY: new RegExp(merge("[^\\%]", UNRESERVED$$2, SUB_DELIMS$$, "[\\:\\@\\/\\?]", IPRIVATE$$), "g"),
|
||
|
|
NOT_FRAGMENT: new RegExp(merge("[^\\%]", UNRESERVED$$2, SUB_DELIMS$$, "[\\:\\@\\/\\?]"), "g"),
|
||
|
|
ESCAPE: new RegExp(merge("[^]", UNRESERVED$$2, SUB_DELIMS$$), "g"),
|
||
|
|
UNRESERVED: new RegExp(UNRESERVED$$2, "g"),
|
||
|
|
OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$2, RESERVED$$), "g"),
|
||
|
|
PCT_ENCODED: new RegExp(PCT_ENCODED$2, "g"),
|
||
|
|
IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"),
|
||
|
|
IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$2 + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$")
|
||
|
|
//RFC 6874, with relaxed parsing rules
|
||
|
|
};
|
||
|
|
}
|
||
|
|
var URI_PROTOCOL = buildExps(false);
|
||
|
|
var IRI_PROTOCOL = buildExps(true);
|
||
|
|
var slicedToArray = /* @__PURE__ */ function() {
|
||
|
|
function sliceIterator(arr, i) {
|
||
|
|
var _arr = [];
|
||
|
|
var _n = true;
|
||
|
|
var _d = false;
|
||
|
|
var _e = void 0;
|
||
|
|
try {
|
||
|
|
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
||
|
|
_arr.push(_s.value);
|
||
|
|
if (i && _arr.length === i)
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
} catch (err3) {
|
||
|
|
_d = true;
|
||
|
|
_e = err3;
|
||
|
|
} finally {
|
||
|
|
try {
|
||
|
|
if (!_n && _i["return"])
|
||
|
|
_i["return"]();
|
||
|
|
} finally {
|
||
|
|
if (_d)
|
||
|
|
throw _e;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return _arr;
|
||
|
|
}
|
||
|
|
return function(arr, i) {
|
||
|
|
if (Array.isArray(arr)) {
|
||
|
|
return arr;
|
||
|
|
} else if (Symbol.iterator in Object(arr)) {
|
||
|
|
return sliceIterator(arr, i);
|
||
|
|
} else {
|
||
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}();
|
||
|
|
var toConsumableArray = function(arr) {
|
||
|
|
if (Array.isArray(arr)) {
|
||
|
|
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++)
|
||
|
|
arr2[i] = arr[i];
|
||
|
|
return arr2;
|
||
|
|
} else {
|
||
|
|
return Array.from(arr);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var maxInt = 2147483647;
|
||
|
|
var base = 36;
|
||
|
|
var tMin = 1;
|
||
|
|
var tMax = 26;
|
||
|
|
var skew = 38;
|
||
|
|
var damp = 700;
|
||
|
|
var initialBias = 72;
|
||
|
|
var initialN = 128;
|
||
|
|
var delimiter = "-";
|
||
|
|
var regexPunycode = /^xn--/;
|
||
|
|
var regexNonASCII = /[^\0-\x7E]/;
|
||
|
|
var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g;
|
||
|
|
var errors = {
|
||
|
|
"overflow": "Overflow: input needs wider integers to process",
|
||
|
|
"not-basic": "Illegal input >= 0x80 (not a basic code point)",
|
||
|
|
"invalid-input": "Invalid input"
|
||
|
|
};
|
||
|
|
var baseMinusTMin = base - tMin;
|
||
|
|
var floor = Math.floor;
|
||
|
|
var stringFromCharCode = String.fromCharCode;
|
||
|
|
function error$1(type) {
|
||
|
|
throw new RangeError(errors[type]);
|
||
|
|
}
|
||
|
|
function map(array, fn) {
|
||
|
|
var result = [];
|
||
|
|
var length2 = array.length;
|
||
|
|
while (length2--) {
|
||
|
|
result[length2] = fn(array[length2]);
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
function mapDomain(string, fn) {
|
||
|
|
var parts = string.split("@");
|
||
|
|
var result = "";
|
||
|
|
if (parts.length > 1) {
|
||
|
|
result = parts[0] + "@";
|
||
|
|
string = parts[1];
|
||
|
|
}
|
||
|
|
string = string.replace(regexSeparators, ".");
|
||
|
|
var labels = string.split(".");
|
||
|
|
var encoded = map(labels, fn).join(".");
|
||
|
|
return result + encoded;
|
||
|
|
}
|
||
|
|
function ucs2decode(string) {
|
||
|
|
var output = [];
|
||
|
|
var counter = 0;
|
||
|
|
var length2 = string.length;
|
||
|
|
while (counter < length2) {
|
||
|
|
var value = string.charCodeAt(counter++);
|
||
|
|
if (value >= 55296 && value <= 56319 && counter < length2) {
|
||
|
|
var extra = string.charCodeAt(counter++);
|
||
|
|
if ((extra & 64512) == 56320) {
|
||
|
|
output.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
||
|
|
} else {
|
||
|
|
output.push(value);
|
||
|
|
counter--;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
output.push(value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return output;
|
||
|
|
}
|
||
|
|
var ucs2encode = function ucs2encode2(array) {
|
||
|
|
return String.fromCodePoint.apply(String, toConsumableArray(array));
|
||
|
|
};
|
||
|
|
var basicToDigit = function basicToDigit2(codePoint) {
|
||
|
|
if (codePoint - 48 < 10) {
|
||
|
|
return codePoint - 22;
|
||
|
|
}
|
||
|
|
if (codePoint - 65 < 26) {
|
||
|
|
return codePoint - 65;
|
||
|
|
}
|
||
|
|
if (codePoint - 97 < 26) {
|
||
|
|
return codePoint - 97;
|
||
|
|
}
|
||
|
|
return base;
|
||
|
|
};
|
||
|
|
var digitToBasic = function digitToBasic2(digit, flag) {
|
||
|
|
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
|
||
|
|
};
|
||
|
|
var adapt = function adapt2(delta, numPoints, firstTime) {
|
||
|
|
var k = 0;
|
||
|
|
delta = firstTime ? floor(delta / damp) : delta >> 1;
|
||
|
|
delta += floor(delta / numPoints);
|
||
|
|
for (
|
||
|
|
;
|
||
|
|
/* no initialization */
|
||
|
|
delta > baseMinusTMin * tMax >> 1;
|
||
|
|
k += base
|
||
|
|
) {
|
||
|
|
delta = floor(delta / baseMinusTMin);
|
||
|
|
}
|
||
|
|
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
|
||
|
|
};
|
||
|
|
var decode6 = function decode7(input) {
|
||
|
|
var output = [];
|
||
|
|
var inputLength = input.length;
|
||
|
|
var i = 0;
|
||
|
|
var n = initialN;
|
||
|
|
var bias = initialBias;
|
||
|
|
var basic = input.lastIndexOf(delimiter);
|
||
|
|
if (basic < 0) {
|
||
|
|
basic = 0;
|
||
|
|
}
|
||
|
|
for (var j = 0; j < basic; ++j) {
|
||
|
|
if (input.charCodeAt(j) >= 128) {
|
||
|
|
error$1("not-basic");
|
||
|
|
}
|
||
|
|
output.push(input.charCodeAt(j));
|
||
|
|
}
|
||
|
|
for (var index = basic > 0 ? basic + 1 : 0; index < inputLength; ) {
|
||
|
|
var oldi = i;
|
||
|
|
for (
|
||
|
|
var w = 1, k = base;
|
||
|
|
;
|
||
|
|
/* no condition */
|
||
|
|
k += base
|
||
|
|
) {
|
||
|
|
if (index >= inputLength) {
|
||
|
|
error$1("invalid-input");
|
||
|
|
}
|
||
|
|
var digit = basicToDigit(input.charCodeAt(index++));
|
||
|
|
if (digit >= base || digit > floor((maxInt - i) / w)) {
|
||
|
|
error$1("overflow");
|
||
|
|
}
|
||
|
|
i += digit * w;
|
||
|
|
var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
|
||
|
|
if (digit < t) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
var baseMinusT = base - t;
|
||
|
|
if (w > floor(maxInt / baseMinusT)) {
|
||
|
|
error$1("overflow");
|
||
|
|
}
|
||
|
|
w *= baseMinusT;
|
||
|
|
}
|
||
|
|
var out = output.length + 1;
|
||
|
|
bias = adapt(i - oldi, out, oldi == 0);
|
||
|
|
if (floor(i / out) > maxInt - n) {
|
||
|
|
error$1("overflow");
|
||
|
|
}
|
||
|
|
n += floor(i / out);
|
||
|
|
i %= out;
|
||
|
|
output.splice(i++, 0, n);
|
||
|
|
}
|
||
|
|
return String.fromCodePoint.apply(String, output);
|
||
|
|
};
|
||
|
|
var encode4 = function encode5(input) {
|
||
|
|
var output = [];
|
||
|
|
input = ucs2decode(input);
|
||
|
|
var inputLength = input.length;
|
||
|
|
var n = initialN;
|
||
|
|
var delta = 0;
|
||
|
|
var bias = initialBias;
|
||
|
|
var _iteratorNormalCompletion = true;
|
||
|
|
var _didIteratorError = false;
|
||
|
|
var _iteratorError = void 0;
|
||
|
|
try {
|
||
|
|
for (var _iterator = input[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||
|
|
var _currentValue2 = _step.value;
|
||
|
|
if (_currentValue2 < 128) {
|
||
|
|
output.push(stringFromCharCode(_currentValue2));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (err3) {
|
||
|
|
_didIteratorError = true;
|
||
|
|
_iteratorError = err3;
|
||
|
|
} finally {
|
||
|
|
try {
|
||
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
||
|
|
_iterator.return();
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
if (_didIteratorError) {
|
||
|
|
throw _iteratorError;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var basicLength = output.length;
|
||
|
|
var handledCPCount = basicLength;
|
||
|
|
if (basicLength) {
|
||
|
|
output.push(delimiter);
|
||
|
|
}
|
||
|
|
while (handledCPCount < inputLength) {
|
||
|
|
var m = maxInt;
|
||
|
|
var _iteratorNormalCompletion2 = true;
|
||
|
|
var _didIteratorError2 = false;
|
||
|
|
var _iteratorError2 = void 0;
|
||
|
|
try {
|
||
|
|
for (var _iterator2 = input[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||
|
|
var currentValue = _step2.value;
|
||
|
|
if (currentValue >= n && currentValue < m) {
|
||
|
|
m = currentValue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (err3) {
|
||
|
|
_didIteratorError2 = true;
|
||
|
|
_iteratorError2 = err3;
|
||
|
|
} finally {
|
||
|
|
try {
|
||
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||
|
|
_iterator2.return();
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
if (_didIteratorError2) {
|
||
|
|
throw _iteratorError2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var handledCPCountPlusOne = handledCPCount + 1;
|
||
|
|
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
|
||
|
|
error$1("overflow");
|
||
|
|
}
|
||
|
|
delta += (m - n) * handledCPCountPlusOne;
|
||
|
|
n = m;
|
||
|
|
var _iteratorNormalCompletion3 = true;
|
||
|
|
var _didIteratorError3 = false;
|
||
|
|
var _iteratorError3 = void 0;
|
||
|
|
try {
|
||
|
|
for (var _iterator3 = input[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||
|
|
var _currentValue = _step3.value;
|
||
|
|
if (_currentValue < n && ++delta > maxInt) {
|
||
|
|
error$1("overflow");
|
||
|
|
}
|
||
|
|
if (_currentValue == n) {
|
||
|
|
var q = delta;
|
||
|
|
for (
|
||
|
|
var k = base;
|
||
|
|
;
|
||
|
|
/* no condition */
|
||
|
|
k += base
|
||
|
|
) {
|
||
|
|
var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
|
||
|
|
if (q < t) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
var qMinusT = q - t;
|
||
|
|
var baseMinusT = base - t;
|
||
|
|
output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)));
|
||
|
|
q = floor(qMinusT / baseMinusT);
|
||
|
|
}
|
||
|
|
output.push(stringFromCharCode(digitToBasic(q, 0)));
|
||
|
|
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
|
||
|
|
delta = 0;
|
||
|
|
++handledCPCount;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (err3) {
|
||
|
|
_didIteratorError3 = true;
|
||
|
|
_iteratorError3 = err3;
|
||
|
|
} finally {
|
||
|
|
try {
|
||
|
|
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||
|
|
_iterator3.return();
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
if (_didIteratorError3) {
|
||
|
|
throw _iteratorError3;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
++delta;
|
||
|
|
++n;
|
||
|
|
}
|
||
|
|
return output.join("");
|
||
|
|
};
|
||
|
|
var toUnicode = function toUnicode2(input) {
|
||
|
|
return mapDomain(input, function(string) {
|
||
|
|
return regexPunycode.test(string) ? decode6(string.slice(4).toLowerCase()) : string;
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var toASCII = function toASCII2(input) {
|
||
|
|
return mapDomain(input, function(string) {
|
||
|
|
return regexNonASCII.test(string) ? "xn--" + encode4(string) : string;
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var punycode = {
|
||
|
|
/**
|
||
|
|
* A string representing the current Punycode.js version number.
|
||
|
|
* @memberOf punycode
|
||
|
|
* @type String
|
||
|
|
*/
|
||
|
|
"version": "2.1.0",
|
||
|
|
/**
|
||
|
|
* An object of methods to convert from JavaScript's internal character
|
||
|
|
* representation (UCS-2) to Unicode code points, and back.
|
||
|
|
* @see <https://mathiasbynens.be/notes/javascript-encoding>
|
||
|
|
* @memberOf punycode
|
||
|
|
* @type Object
|
||
|
|
*/
|
||
|
|
"ucs2": {
|
||
|
|
"decode": ucs2decode,
|
||
|
|
"encode": ucs2encode
|
||
|
|
},
|
||
|
|
"decode": decode6,
|
||
|
|
"encode": encode4,
|
||
|
|
"toASCII": toASCII,
|
||
|
|
"toUnicode": toUnicode
|
||
|
|
};
|
||
|
|
var SCHEMES = {};
|
||
|
|
function pctEncChar(chr) {
|
||
|
|
var c = chr.charCodeAt(0);
|
||
|
|
var e = void 0;
|
||
|
|
if (c < 16)
|
||
|
|
e = "%0" + c.toString(16).toUpperCase();
|
||
|
|
else if (c < 128)
|
||
|
|
e = "%" + c.toString(16).toUpperCase();
|
||
|
|
else if (c < 2048)
|
||
|
|
e = "%" + (c >> 6 | 192).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase();
|
||
|
|
else
|
||
|
|
e = "%" + (c >> 12 | 224).toString(16).toUpperCase() + "%" + (c >> 6 & 63 | 128).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase();
|
||
|
|
return e;
|
||
|
|
}
|
||
|
|
function pctDecChars(str3) {
|
||
|
|
var newStr = "";
|
||
|
|
var i = 0;
|
||
|
|
var il = str3.length;
|
||
|
|
while (i < il) {
|
||
|
|
var c = parseInt(str3.substr(i + 1, 2), 16);
|
||
|
|
if (c < 128) {
|
||
|
|
newStr += String.fromCharCode(c);
|
||
|
|
i += 3;
|
||
|
|
} else if (c >= 194 && c < 224) {
|
||
|
|
if (il - i >= 6) {
|
||
|
|
var c2 = parseInt(str3.substr(i + 4, 2), 16);
|
||
|
|
newStr += String.fromCharCode((c & 31) << 6 | c2 & 63);
|
||
|
|
} else {
|
||
|
|
newStr += str3.substr(i, 6);
|
||
|
|
}
|
||
|
|
i += 6;
|
||
|
|
} else if (c >= 224) {
|
||
|
|
if (il - i >= 9) {
|
||
|
|
var _c = parseInt(str3.substr(i + 4, 2), 16);
|
||
|
|
var c3 = parseInt(str3.substr(i + 7, 2), 16);
|
||
|
|
newStr += String.fromCharCode((c & 15) << 12 | (_c & 63) << 6 | c3 & 63);
|
||
|
|
} else {
|
||
|
|
newStr += str3.substr(i, 9);
|
||
|
|
}
|
||
|
|
i += 9;
|
||
|
|
} else {
|
||
|
|
newStr += str3.substr(i, 3);
|
||
|
|
i += 3;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return newStr;
|
||
|
|
}
|
||
|
|
function _normalizeComponentEncoding(components, protocol) {
|
||
|
|
function decodeUnreserved2(str3) {
|
||
|
|
var decStr = pctDecChars(str3);
|
||
|
|
return !decStr.match(protocol.UNRESERVED) ? str3 : decStr;
|
||
|
|
}
|
||
|
|
if (components.scheme)
|
||
|
|
components.scheme = String(components.scheme).replace(protocol.PCT_ENCODED, decodeUnreserved2).toLowerCase().replace(protocol.NOT_SCHEME, "");
|
||
|
|
if (components.userinfo !== void 0)
|
||
|
|
components.userinfo = String(components.userinfo).replace(protocol.PCT_ENCODED, decodeUnreserved2).replace(protocol.NOT_USERINFO, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase);
|
||
|
|
if (components.host !== void 0)
|
||
|
|
components.host = String(components.host).replace(protocol.PCT_ENCODED, decodeUnreserved2).toLowerCase().replace(protocol.NOT_HOST, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase);
|
||
|
|
if (components.path !== void 0)
|
||
|
|
components.path = String(components.path).replace(protocol.PCT_ENCODED, decodeUnreserved2).replace(components.scheme ? protocol.NOT_PATH : protocol.NOT_PATH_NOSCHEME, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase);
|
||
|
|
if (components.query !== void 0)
|
||
|
|
components.query = String(components.query).replace(protocol.PCT_ENCODED, decodeUnreserved2).replace(protocol.NOT_QUERY, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase);
|
||
|
|
if (components.fragment !== void 0)
|
||
|
|
components.fragment = String(components.fragment).replace(protocol.PCT_ENCODED, decodeUnreserved2).replace(protocol.NOT_FRAGMENT, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase);
|
||
|
|
return components;
|
||
|
|
}
|
||
|
|
function _stripLeadingZeros(str3) {
|
||
|
|
return str3.replace(/^0*(.*)/, "$1") || "0";
|
||
|
|
}
|
||
|
|
function _normalizeIPv4(host, protocol) {
|
||
|
|
var matches = host.match(protocol.IPV4ADDRESS) || [];
|
||
|
|
var _matches = slicedToArray(matches, 2), address = _matches[1];
|
||
|
|
if (address) {
|
||
|
|
return address.split(".").map(_stripLeadingZeros).join(".");
|
||
|
|
} else {
|
||
|
|
return host;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function _normalizeIPv6(host, protocol) {
|
||
|
|
var matches = host.match(protocol.IPV6ADDRESS) || [];
|
||
|
|
var _matches2 = slicedToArray(matches, 3), address = _matches2[1], zone = _matches2[2];
|
||
|
|
if (address) {
|
||
|
|
var _address$toLowerCase$ = address.toLowerCase().split("::").reverse(), _address$toLowerCase$2 = slicedToArray(_address$toLowerCase$, 2), last = _address$toLowerCase$2[0], first = _address$toLowerCase$2[1];
|
||
|
|
var firstFields = first ? first.split(":").map(_stripLeadingZeros) : [];
|
||
|
|
var lastFields = last.split(":").map(_stripLeadingZeros);
|
||
|
|
var isLastFieldIPv4Address = protocol.IPV4ADDRESS.test(lastFields[lastFields.length - 1]);
|
||
|
|
var fieldCount = isLastFieldIPv4Address ? 7 : 8;
|
||
|
|
var lastFieldsStart = lastFields.length - fieldCount;
|
||
|
|
var fields = Array(fieldCount);
|
||
|
|
for (var x = 0; x < fieldCount; ++x) {
|
||
|
|
fields[x] = firstFields[x] || lastFields[lastFieldsStart + x] || "";
|
||
|
|
}
|
||
|
|
if (isLastFieldIPv4Address) {
|
||
|
|
fields[fieldCount - 1] = _normalizeIPv4(fields[fieldCount - 1], protocol);
|
||
|
|
}
|
||
|
|
var allZeroFields = fields.reduce(function(acc, field, index) {
|
||
|
|
if (!field || field === "0") {
|
||
|
|
var lastLongest = acc[acc.length - 1];
|
||
|
|
if (lastLongest && lastLongest.index + lastLongest.length === index) {
|
||
|
|
lastLongest.length++;
|
||
|
|
} else {
|
||
|
|
acc.push({ index, length: 1 });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return acc;
|
||
|
|
}, []);
|
||
|
|
var longestZeroFields = allZeroFields.sort(function(a, b) {
|
||
|
|
return b.length - a.length;
|
||
|
|
})[0];
|
||
|
|
var newHost = void 0;
|
||
|
|
if (longestZeroFields && longestZeroFields.length > 1) {
|
||
|
|
var newFirst = fields.slice(0, longestZeroFields.index);
|
||
|
|
var newLast = fields.slice(longestZeroFields.index + longestZeroFields.length);
|
||
|
|
newHost = newFirst.join(":") + "::" + newLast.join(":");
|
||
|
|
} else {
|
||
|
|
newHost = fields.join(":");
|
||
|
|
}
|
||
|
|
if (zone) {
|
||
|
|
newHost += "%" + zone;
|
||
|
|
}
|
||
|
|
return newHost;
|
||
|
|
} else {
|
||
|
|
return host;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var URI_PARSE = /^(?:([^:\/?#]+):)?(?:\/\/((?:([^\/?#@]*)@)?(\[[^\/?#\]]+\]|[^\/?#:]*)(?:\:(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i;
|
||
|
|
var NO_MATCH_IS_UNDEFINED = "".match(/(){0}/)[1] === void 0;
|
||
|
|
function parse2(uriString) {
|
||
|
|
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
||
|
|
var components = {};
|
||
|
|
var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL;
|
||
|
|
if (options.reference === "suffix")
|
||
|
|
uriString = (options.scheme ? options.scheme + ":" : "") + "//" + uriString;
|
||
|
|
var matches = uriString.match(URI_PARSE);
|
||
|
|
if (matches) {
|
||
|
|
if (NO_MATCH_IS_UNDEFINED) {
|
||
|
|
components.scheme = matches[1];
|
||
|
|
components.userinfo = matches[3];
|
||
|
|
components.host = matches[4];
|
||
|
|
components.port = parseInt(matches[5], 10);
|
||
|
|
components.path = matches[6] || "";
|
||
|
|
components.query = matches[7];
|
||
|
|
components.fragment = matches[8];
|
||
|
|
if (isNaN(components.port)) {
|
||
|
|
components.port = matches[5];
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
components.scheme = matches[1] || void 0;
|
||
|
|
components.userinfo = uriString.indexOf("@") !== -1 ? matches[3] : void 0;
|
||
|
|
components.host = uriString.indexOf("//") !== -1 ? matches[4] : void 0;
|
||
|
|
components.port = parseInt(matches[5], 10);
|
||
|
|
components.path = matches[6] || "";
|
||
|
|
components.query = uriString.indexOf("?") !== -1 ? matches[7] : void 0;
|
||
|
|
components.fragment = uriString.indexOf("#") !== -1 ? matches[8] : void 0;
|
||
|
|
if (isNaN(components.port)) {
|
||
|
|
components.port = uriString.match(/\/\/(?:.|\n)*\:(?:\/|\?|\#|$)/) ? matches[4] : void 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (components.host) {
|
||
|
|
components.host = _normalizeIPv6(_normalizeIPv4(components.host, protocol), protocol);
|
||
|
|
}
|
||
|
|
if (components.scheme === void 0 && components.userinfo === void 0 && components.host === void 0 && components.port === void 0 && !components.path && components.query === void 0) {
|
||
|
|
components.reference = "same-document";
|
||
|
|
} else if (components.scheme === void 0) {
|
||
|
|
components.reference = "relative";
|
||
|
|
} else if (components.fragment === void 0) {
|
||
|
|
components.reference = "absolute";
|
||
|
|
} else {
|
||
|
|
components.reference = "uri";
|
||
|
|
}
|
||
|
|
if (options.reference && options.reference !== "suffix" && options.reference !== components.reference) {
|
||
|
|
components.error = components.error || "URI is not a " + options.reference + " reference.";
|
||
|
|
}
|
||
|
|
var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()];
|
||
|
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
||
|
|
if (components.host && (options.domainHost || schemeHandler && schemeHandler.domainHost)) {
|
||
|
|
try {
|
||
|
|
components.host = punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase());
|
||
|
|
} catch (e) {
|
||
|
|
components.error = components.error || "Host's domain name can not be converted to ASCII via punycode: " + e;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
_normalizeComponentEncoding(components, URI_PROTOCOL);
|
||
|
|
} else {
|
||
|
|
_normalizeComponentEncoding(components, protocol);
|
||
|
|
}
|
||
|
|
if (schemeHandler && schemeHandler.parse) {
|
||
|
|
schemeHandler.parse(components, options);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
components.error = components.error || "URI can not be parsed.";
|
||
|
|
}
|
||
|
|
return components;
|
||
|
|
}
|
||
|
|
function _recomposeAuthority(components, options) {
|
||
|
|
var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL;
|
||
|
|
var uriTokens = [];
|
||
|
|
if (components.userinfo !== void 0) {
|
||
|
|
uriTokens.push(components.userinfo);
|
||
|
|
uriTokens.push("@");
|
||
|
|
}
|
||
|
|
if (components.host !== void 0) {
|
||
|
|
uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function(_, $1, $2) {
|
||
|
|
return "[" + $1 + ($2 ? "%25" + $2 : "") + "]";
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
if (typeof components.port === "number" || typeof components.port === "string") {
|
||
|
|
uriTokens.push(":");
|
||
|
|
uriTokens.push(String(components.port));
|
||
|
|
}
|
||
|
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
||
|
|
}
|
||
|
|
var RDS1 = /^\.\.?\//;
|
||
|
|
var RDS2 = /^\/\.(\/|$)/;
|
||
|
|
var RDS3 = /^\/\.\.(\/|$)/;
|
||
|
|
var RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/;
|
||
|
|
function removeDotSegments(input) {
|
||
|
|
var output = [];
|
||
|
|
while (input.length) {
|
||
|
|
if (input.match(RDS1)) {
|
||
|
|
input = input.replace(RDS1, "");
|
||
|
|
} else if (input.match(RDS2)) {
|
||
|
|
input = input.replace(RDS2, "/");
|
||
|
|
} else if (input.match(RDS3)) {
|
||
|
|
input = input.replace(RDS3, "/");
|
||
|
|
output.pop();
|
||
|
|
} else if (input === "." || input === "..") {
|
||
|
|
input = "";
|
||
|
|
} else {
|
||
|
|
var im = input.match(RDS5);
|
||
|
|
if (im) {
|
||
|
|
var s = im[0];
|
||
|
|
input = input.slice(s.length);
|
||
|
|
output.push(s);
|
||
|
|
} else {
|
||
|
|
throw new Error("Unexpected dot segment condition");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return output.join("");
|
||
|
|
}
|
||
|
|
function serialize(components) {
|
||
|
|
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
||
|
|
var protocol = options.iri ? IRI_PROTOCOL : URI_PROTOCOL;
|
||
|
|
var uriTokens = [];
|
||
|
|
var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()];
|
||
|
|
if (schemeHandler && schemeHandler.serialize)
|
||
|
|
schemeHandler.serialize(components, options);
|
||
|
|
if (components.host) {
|
||
|
|
if (protocol.IPV6ADDRESS.test(components.host)) {
|
||
|
|
} else if (options.domainHost || schemeHandler && schemeHandler.domainHost) {
|
||
|
|
try {
|
||
|
|
components.host = !options.iri ? punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()) : punycode.toUnicode(components.host);
|
||
|
|
} catch (e) {
|
||
|
|
components.error = components.error || "Host's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
_normalizeComponentEncoding(components, protocol);
|
||
|
|
if (options.reference !== "suffix" && components.scheme) {
|
||
|
|
uriTokens.push(components.scheme);
|
||
|
|
uriTokens.push(":");
|
||
|
|
}
|
||
|
|
var authority = _recomposeAuthority(components, options);
|
||
|
|
if (authority !== void 0) {
|
||
|
|
if (options.reference !== "suffix") {
|
||
|
|
uriTokens.push("//");
|
||
|
|
}
|
||
|
|
uriTokens.push(authority);
|
||
|
|
if (components.path && components.path.charAt(0) !== "/") {
|
||
|
|
uriTokens.push("/");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (components.path !== void 0) {
|
||
|
|
var s = components.path;
|
||
|
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
||
|
|
s = removeDotSegments(s);
|
||
|
|
}
|
||
|
|
if (authority === void 0) {
|
||
|
|
s = s.replace(/^\/\//, "/%2F");
|
||
|
|
}
|
||
|
|
uriTokens.push(s);
|
||
|
|
}
|
||
|
|
if (components.query !== void 0) {
|
||
|
|
uriTokens.push("?");
|
||
|
|
uriTokens.push(components.query);
|
||
|
|
}
|
||
|
|
if (components.fragment !== void 0) {
|
||
|
|
uriTokens.push("#");
|
||
|
|
uriTokens.push(components.fragment);
|
||
|
|
}
|
||
|
|
return uriTokens.join("");
|
||
|
|
}
|
||
|
|
function resolveComponents(base2, relative) {
|
||
|
|
var options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
|
||
|
|
var skipNormalization = arguments[3];
|
||
|
|
var target = {};
|
||
|
|
if (!skipNormalization) {
|
||
|
|
base2 = parse2(serialize(base2, options), options);
|
||
|
|
relative = parse2(serialize(relative, options), options);
|
||
|
|
}
|
||
|
|
options = options || {};
|
||
|
|
if (!options.tolerant && relative.scheme) {
|
||
|
|
target.scheme = relative.scheme;
|
||
|
|
target.userinfo = relative.userinfo;
|
||
|
|
target.host = relative.host;
|
||
|
|
target.port = relative.port;
|
||
|
|
target.path = removeDotSegments(relative.path || "");
|
||
|
|
target.query = relative.query;
|
||
|
|
} else {
|
||
|
|
if (relative.userinfo !== void 0 || relative.host !== void 0 || relative.port !== void 0) {
|
||
|
|
target.userinfo = relative.userinfo;
|
||
|
|
target.host = relative.host;
|
||
|
|
target.port = relative.port;
|
||
|
|
target.path = removeDotSegments(relative.path || "");
|
||
|
|
target.query = relative.query;
|
||
|
|
} else {
|
||
|
|
if (!relative.path) {
|
||
|
|
target.path = base2.path;
|
||
|
|
if (relative.query !== void 0) {
|
||
|
|
target.query = relative.query;
|
||
|
|
} else {
|
||
|
|
target.query = base2.query;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (relative.path.charAt(0) === "/") {
|
||
|
|
target.path = removeDotSegments(relative.path);
|
||
|
|
} else {
|
||
|
|
if ((base2.userinfo !== void 0 || base2.host !== void 0 || base2.port !== void 0) && !base2.path) {
|
||
|
|
target.path = "/" + relative.path;
|
||
|
|
} else if (!base2.path) {
|
||
|
|
target.path = relative.path;
|
||
|
|
} else {
|
||
|
|
target.path = base2.path.slice(0, base2.path.lastIndexOf("/") + 1) + relative.path;
|
||
|
|
}
|
||
|
|
target.path = removeDotSegments(target.path);
|
||
|
|
}
|
||
|
|
target.query = relative.query;
|
||
|
|
}
|
||
|
|
target.userinfo = base2.userinfo;
|
||
|
|
target.host = base2.host;
|
||
|
|
target.port = base2.port;
|
||
|
|
}
|
||
|
|
target.scheme = base2.scheme;
|
||
|
|
}
|
||
|
|
target.fragment = relative.fragment;
|
||
|
|
return target;
|
||
|
|
}
|
||
|
|
function resolve(baseURI, relativeURI, options) {
|
||
|
|
var schemelessOptions = assign({ scheme: "null" }, options);
|
||
|
|
return serialize(resolveComponents(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions);
|
||
|
|
}
|
||
|
|
function normalize(uri, options) {
|
||
|
|
if (typeof uri === "string") {
|
||
|
|
uri = serialize(parse2(uri, options), options);
|
||
|
|
} else if (typeOf(uri) === "object") {
|
||
|
|
uri = parse2(serialize(uri, options), options);
|
||
|
|
}
|
||
|
|
return uri;
|
||
|
|
}
|
||
|
|
function equal(uriA, uriB, options) {
|
||
|
|
if (typeof uriA === "string") {
|
||
|
|
uriA = serialize(parse2(uriA, options), options);
|
||
|
|
} else if (typeOf(uriA) === "object") {
|
||
|
|
uriA = serialize(uriA, options);
|
||
|
|
}
|
||
|
|
if (typeof uriB === "string") {
|
||
|
|
uriB = serialize(parse2(uriB, options), options);
|
||
|
|
} else if (typeOf(uriB) === "object") {
|
||
|
|
uriB = serialize(uriB, options);
|
||
|
|
}
|
||
|
|
return uriA === uriB;
|
||
|
|
}
|
||
|
|
function escapeComponent(str3, options) {
|
||
|
|
return str3 && str3.toString().replace(!options || !options.iri ? URI_PROTOCOL.ESCAPE : IRI_PROTOCOL.ESCAPE, pctEncChar);
|
||
|
|
}
|
||
|
|
function unescapeComponent(str3, options) {
|
||
|
|
return str3 && str3.toString().replace(!options || !options.iri ? URI_PROTOCOL.PCT_ENCODED : IRI_PROTOCOL.PCT_ENCODED, pctDecChars);
|
||
|
|
}
|
||
|
|
var handler = {
|
||
|
|
scheme: "http",
|
||
|
|
domainHost: true,
|
||
|
|
parse: function parse3(components, options) {
|
||
|
|
if (!components.host) {
|
||
|
|
components.error = components.error || "HTTP URIs must have a host.";
|
||
|
|
}
|
||
|
|
return components;
|
||
|
|
},
|
||
|
|
serialize: function serialize2(components, options) {
|
||
|
|
var secure = String(components.scheme).toLowerCase() === "https";
|
||
|
|
if (components.port === (secure ? 443 : 80) || components.port === "") {
|
||
|
|
components.port = void 0;
|
||
|
|
}
|
||
|
|
if (!components.path) {
|
||
|
|
components.path = "/";
|
||
|
|
}
|
||
|
|
return components;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var handler$1 = {
|
||
|
|
scheme: "https",
|
||
|
|
domainHost: handler.domainHost,
|
||
|
|
parse: handler.parse,
|
||
|
|
serialize: handler.serialize
|
||
|
|
};
|
||
|
|
function isSecure(wsComponents) {
|
||
|
|
return typeof wsComponents.secure === "boolean" ? wsComponents.secure : String(wsComponents.scheme).toLowerCase() === "wss";
|
||
|
|
}
|
||
|
|
var handler$2 = {
|
||
|
|
scheme: "ws",
|
||
|
|
domainHost: true,
|
||
|
|
parse: function parse3(components, options) {
|
||
|
|
var wsComponents = components;
|
||
|
|
wsComponents.secure = isSecure(wsComponents);
|
||
|
|
wsComponents.resourceName = (wsComponents.path || "/") + (wsComponents.query ? "?" + wsComponents.query : "");
|
||
|
|
wsComponents.path = void 0;
|
||
|
|
wsComponents.query = void 0;
|
||
|
|
return wsComponents;
|
||
|
|
},
|
||
|
|
serialize: function serialize2(wsComponents, options) {
|
||
|
|
if (wsComponents.port === (isSecure(wsComponents) ? 443 : 80) || wsComponents.port === "") {
|
||
|
|
wsComponents.port = void 0;
|
||
|
|
}
|
||
|
|
if (typeof wsComponents.secure === "boolean") {
|
||
|
|
wsComponents.scheme = wsComponents.secure ? "wss" : "ws";
|
||
|
|
wsComponents.secure = void 0;
|
||
|
|
}
|
||
|
|
if (wsComponents.resourceName) {
|
||
|
|
var _wsComponents$resourc = wsComponents.resourceName.split("?"), _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2), path = _wsComponents$resourc2[0], query = _wsComponents$resourc2[1];
|
||
|
|
wsComponents.path = path && path !== "/" ? path : void 0;
|
||
|
|
wsComponents.query = query;
|
||
|
|
wsComponents.resourceName = void 0;
|
||
|
|
}
|
||
|
|
wsComponents.fragment = void 0;
|
||
|
|
return wsComponents;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var handler$3 = {
|
||
|
|
scheme: "wss",
|
||
|
|
domainHost: handler$2.domainHost,
|
||
|
|
parse: handler$2.parse,
|
||
|
|
serialize: handler$2.serialize
|
||
|
|
};
|
||
|
|
var O = {};
|
||
|
|
var isIRI = true;
|
||
|
|
var UNRESERVED$$ = "[A-Za-z0-9\\-\\.\\_\\~" + (isIRI ? "\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF" : "") + "]";
|
||
|
|
var HEXDIG$$ = "[0-9A-Fa-f]";
|
||
|
|
var PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$));
|
||
|
|
var ATEXT$$ = "[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]";
|
||
|
|
var QTEXT$$ = "[\\!\\$\\%\\'\\(\\)\\*\\+\\,\\-\\.0-9\\<\\>A-Z\\x5E-\\x7E]";
|
||
|
|
var VCHAR$$ = merge(QTEXT$$, '[\\"\\\\]');
|
||
|
|
var SOME_DELIMS$$ = "[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]";
|
||
|
|
var UNRESERVED = new RegExp(UNRESERVED$$, "g");
|
||
|
|
var PCT_ENCODED = new RegExp(PCT_ENCODED$, "g");
|
||
|
|
var NOT_LOCAL_PART = new RegExp(merge("[^]", ATEXT$$, "[\\.]", '[\\"]', VCHAR$$), "g");
|
||
|
|
var NOT_HFNAME = new RegExp(merge("[^]", UNRESERVED$$, SOME_DELIMS$$), "g");
|
||
|
|
var NOT_HFVALUE = NOT_HFNAME;
|
||
|
|
function decodeUnreserved(str3) {
|
||
|
|
var decStr = pctDecChars(str3);
|
||
|
|
return !decStr.match(UNRESERVED) ? str3 : decStr;
|
||
|
|
}
|
||
|
|
var handler$4 = {
|
||
|
|
scheme: "mailto",
|
||
|
|
parse: function parse$$1(components, options) {
|
||
|
|
var mailtoComponents = components;
|
||
|
|
var to = mailtoComponents.to = mailtoComponents.path ? mailtoComponents.path.split(",") : [];
|
||
|
|
mailtoComponents.path = void 0;
|
||
|
|
if (mailtoComponents.query) {
|
||
|
|
var unknownHeaders = false;
|
||
|
|
var headers = {};
|
||
|
|
var hfields = mailtoComponents.query.split("&");
|
||
|
|
for (var x = 0, xl = hfields.length; x < xl; ++x) {
|
||
|
|
var hfield = hfields[x].split("=");
|
||
|
|
switch (hfield[0]) {
|
||
|
|
case "to":
|
||
|
|
var toAddrs = hfield[1].split(",");
|
||
|
|
for (var _x = 0, _xl = toAddrs.length; _x < _xl; ++_x) {
|
||
|
|
to.push(toAddrs[_x]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case "subject":
|
||
|
|
mailtoComponents.subject = unescapeComponent(hfield[1], options);
|
||
|
|
break;
|
||
|
|
case "body":
|
||
|
|
mailtoComponents.body = unescapeComponent(hfield[1], options);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
unknownHeaders = true;
|
||
|
|
headers[unescapeComponent(hfield[0], options)] = unescapeComponent(hfield[1], options);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (unknownHeaders)
|
||
|
|
mailtoComponents.headers = headers;
|
||
|
|
}
|
||
|
|
mailtoComponents.query = void 0;
|
||
|
|
for (var _x2 = 0, _xl2 = to.length; _x2 < _xl2; ++_x2) {
|
||
|
|
var addr = to[_x2].split("@");
|
||
|
|
addr[0] = unescapeComponent(addr[0]);
|
||
|
|
if (!options.unicodeSupport) {
|
||
|
|
try {
|
||
|
|
addr[1] = punycode.toASCII(unescapeComponent(addr[1], options).toLowerCase());
|
||
|
|
} catch (e) {
|
||
|
|
mailtoComponents.error = mailtoComponents.error || "Email address's domain name can not be converted to ASCII via punycode: " + e;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
addr[1] = unescapeComponent(addr[1], options).toLowerCase();
|
||
|
|
}
|
||
|
|
to[_x2] = addr.join("@");
|
||
|
|
}
|
||
|
|
return mailtoComponents;
|
||
|
|
},
|
||
|
|
serialize: function serialize$$1(mailtoComponents, options) {
|
||
|
|
var components = mailtoComponents;
|
||
|
|
var to = toArray(mailtoComponents.to);
|
||
|
|
if (to) {
|
||
|
|
for (var x = 0, xl = to.length; x < xl; ++x) {
|
||
|
|
var toAddr = String(to[x]);
|
||
|
|
var atIdx = toAddr.lastIndexOf("@");
|
||
|
|
var localPart = toAddr.slice(0, atIdx).replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_LOCAL_PART, pctEncChar);
|
||
|
|
var domain = toAddr.slice(atIdx + 1);
|
||
|
|
try {
|
||
|
|
domain = !options.iri ? punycode.toASCII(unescapeComponent(domain, options).toLowerCase()) : punycode.toUnicode(domain);
|
||
|
|
} catch (e) {
|
||
|
|
components.error = components.error || "Email address's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e;
|
||
|
|
}
|
||
|
|
to[x] = localPart + "@" + domain;
|
||
|
|
}
|
||
|
|
components.path = to.join(",");
|
||
|
|
}
|
||
|
|
var headers = mailtoComponents.headers = mailtoComponents.headers || {};
|
||
|
|
if (mailtoComponents.subject)
|
||
|
|
headers["subject"] = mailtoComponents.subject;
|
||
|
|
if (mailtoComponents.body)
|
||
|
|
headers["body"] = mailtoComponents.body;
|
||
|
|
var fields = [];
|
||
|
|
for (var name in headers) {
|
||
|
|
if (headers[name] !== O[name]) {
|
||
|
|
fields.push(name.replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFNAME, pctEncChar) + "=" + headers[name].replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFVALUE, pctEncChar));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (fields.length) {
|
||
|
|
components.query = fields.join("&");
|
||
|
|
}
|
||
|
|
return components;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var URN_PARSE = /^([^\:]+)\:(.*)/;
|
||
|
|
var handler$5 = {
|
||
|
|
scheme: "urn",
|
||
|
|
parse: function parse$$1(components, options) {
|
||
|
|
var matches = components.path && components.path.match(URN_PARSE);
|
||
|
|
var urnComponents = components;
|
||
|
|
if (matches) {
|
||
|
|
var scheme = options.scheme || urnComponents.scheme || "urn";
|
||
|
|
var nid = matches[1].toLowerCase();
|
||
|
|
var nss = matches[2];
|
||
|
|
var urnScheme = scheme + ":" + (options.nid || nid);
|
||
|
|
var schemeHandler = SCHEMES[urnScheme];
|
||
|
|
urnComponents.nid = nid;
|
||
|
|
urnComponents.nss = nss;
|
||
|
|
urnComponents.path = void 0;
|
||
|
|
if (schemeHandler) {
|
||
|
|
urnComponents = schemeHandler.parse(urnComponents, options);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
urnComponents.error = urnComponents.error || "URN can not be parsed.";
|
||
|
|
}
|
||
|
|
return urnComponents;
|
||
|
|
},
|
||
|
|
serialize: function serialize$$1(urnComponents, options) {
|
||
|
|
var scheme = options.scheme || urnComponents.scheme || "urn";
|
||
|
|
var nid = urnComponents.nid;
|
||
|
|
var urnScheme = scheme + ":" + (options.nid || nid);
|
||
|
|
var schemeHandler = SCHEMES[urnScheme];
|
||
|
|
if (schemeHandler) {
|
||
|
|
urnComponents = schemeHandler.serialize(urnComponents, options);
|
||
|
|
}
|
||
|
|
var uriComponents = urnComponents;
|
||
|
|
var nss = urnComponents.nss;
|
||
|
|
uriComponents.path = (nid || options.nid) + ":" + nss;
|
||
|
|
return uriComponents;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var UUID = /^[0-9A-Fa-f]{8}(?:\-[0-9A-Fa-f]{4}){3}\-[0-9A-Fa-f]{12}$/;
|
||
|
|
var handler$6 = {
|
||
|
|
scheme: "urn:uuid",
|
||
|
|
parse: function parse3(urnComponents, options) {
|
||
|
|
var uuidComponents = urnComponents;
|
||
|
|
uuidComponents.uuid = uuidComponents.nss;
|
||
|
|
uuidComponents.nss = void 0;
|
||
|
|
if (!options.tolerant && (!uuidComponents.uuid || !uuidComponents.uuid.match(UUID))) {
|
||
|
|
uuidComponents.error = uuidComponents.error || "UUID is not valid.";
|
||
|
|
}
|
||
|
|
return uuidComponents;
|
||
|
|
},
|
||
|
|
serialize: function serialize2(uuidComponents, options) {
|
||
|
|
var urnComponents = uuidComponents;
|
||
|
|
urnComponents.nss = (uuidComponents.uuid || "").toLowerCase();
|
||
|
|
return urnComponents;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
SCHEMES[handler.scheme] = handler;
|
||
|
|
SCHEMES[handler$1.scheme] = handler$1;
|
||
|
|
SCHEMES[handler$2.scheme] = handler$2;
|
||
|
|
SCHEMES[handler$3.scheme] = handler$3;
|
||
|
|
SCHEMES[handler$4.scheme] = handler$4;
|
||
|
|
SCHEMES[handler$5.scheme] = handler$5;
|
||
|
|
SCHEMES[handler$6.scheme] = handler$6;
|
||
|
|
exports2.SCHEMES = SCHEMES;
|
||
|
|
exports2.pctEncChar = pctEncChar;
|
||
|
|
exports2.pctDecChars = pctDecChars;
|
||
|
|
exports2.parse = parse2;
|
||
|
|
exports2.removeDotSegments = removeDotSegments;
|
||
|
|
exports2.serialize = serialize;
|
||
|
|
exports2.resolveComponents = resolveComponents;
|
||
|
|
exports2.resolve = resolve;
|
||
|
|
exports2.normalize = normalize;
|
||
|
|
exports2.equal = equal;
|
||
|
|
exports2.escapeComponent = escapeComponent;
|
||
|
|
exports2.unescapeComponent = unescapeComponent;
|
||
|
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/canonicalize@2.0.0/node_modules/canonicalize/lib/canonicalize.js
|
||
|
|
var require_canonicalize = __commonJS({
|
||
|
|
"../../node_modules/.pnpm/canonicalize@2.0.0/node_modules/canonicalize/lib/canonicalize.js"(exports, module2) {
|
||
|
|
"use strict";
|
||
|
|
module2.exports = function serialize(object) {
|
||
|
|
if (typeof object === "number" && isNaN(object)) {
|
||
|
|
throw new Error("NaN is not allowed");
|
||
|
|
}
|
||
|
|
if (typeof object === "number" && !isFinite(object)) {
|
||
|
|
throw new Error("Infinity is not allowed");
|
||
|
|
}
|
||
|
|
if (object === null || typeof object !== "object") {
|
||
|
|
return JSON.stringify(object);
|
||
|
|
}
|
||
|
|
if (object.toJSON instanceof Function) {
|
||
|
|
return serialize(object.toJSON());
|
||
|
|
}
|
||
|
|
if (Array.isArray(object)) {
|
||
|
|
const values2 = object.reduce((t, cv, ci) => {
|
||
|
|
const comma = ci === 0 ? "" : ",";
|
||
|
|
const value = cv === void 0 || typeof cv === "symbol" ? null : cv;
|
||
|
|
return `${t}${comma}${serialize(value)}`;
|
||
|
|
}, "");
|
||
|
|
return `[${values2}]`;
|
||
|
|
}
|
||
|
|
const values = Object.keys(object).sort().reduce((t, cv) => {
|
||
|
|
if (object[cv] === void 0 || typeof object[cv] === "symbol") {
|
||
|
|
return t;
|
||
|
|
}
|
||
|
|
const comma = t.length === 0 ? "" : ",";
|
||
|
|
return `${t}${comma}${serialize(cv)}:${serialize(object[cv])}`;
|
||
|
|
}, "");
|
||
|
|
return `{${values}}`;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// dist/esm/index.js
|
||
|
|
var esm_exports = {};
|
||
|
|
__export(esm_exports, {
|
||
|
|
BearerDid: () => BearerDid,
|
||
|
|
Did: () => Did,
|
||
|
|
DidDht: () => DidDht,
|
||
|
|
DidDhtDocument: () => DidDhtDocument,
|
||
|
|
DidDhtRegisteredDidType: () => DidDhtRegisteredDidType,
|
||
|
|
DidDhtRegisteredKeyType: () => DidDhtRegisteredKeyType,
|
||
|
|
DidDhtUtils: () => DidDhtUtils,
|
||
|
|
DidDhtVerificationRelationship: () => DidDhtVerificationRelationship,
|
||
|
|
DidError: () => DidError,
|
||
|
|
DidErrorCode: () => DidErrorCode,
|
||
|
|
DidIon: () => DidIon,
|
||
|
|
DidIonRegisteredKeyType: () => DidIonRegisteredKeyType,
|
||
|
|
DidIonUtils: () => DidIonUtils,
|
||
|
|
DidJwk: () => DidJwk,
|
||
|
|
DidKey: () => DidKey,
|
||
|
|
DidKeyRegisteredKeyType: () => DidKeyRegisteredKeyType,
|
||
|
|
DidKeyUtils: () => DidKeyUtils,
|
||
|
|
DidKeyVerificationMethodType: () => DidKeyVerificationMethodType,
|
||
|
|
DidMethod: () => DidMethod,
|
||
|
|
DidResolverCacheLevel: () => DidResolverCacheLevel,
|
||
|
|
DidResolverCacheNoop: () => DidResolverCacheNoop,
|
||
|
|
DidVerificationRelationship: () => DidVerificationRelationship,
|
||
|
|
DidWeb: () => DidWeb,
|
||
|
|
EMPTY_DID_RESOLUTION_RESULT: () => EMPTY_DID_RESOLUTION_RESULT,
|
||
|
|
UniversalResolver: () => UniversalResolver,
|
||
|
|
utils: () => utils_exports
|
||
|
|
});
|
||
|
|
module.exports = __toCommonJS(esm_exports);
|
||
|
|
|
||
|
|
// dist/esm/types/did-core.js
|
||
|
|
var DidVerificationRelationship;
|
||
|
|
(function(DidVerificationRelationship2) {
|
||
|
|
DidVerificationRelationship2["authentication"] = "authentication";
|
||
|
|
DidVerificationRelationship2["assertionMethod"] = "assertionMethod";
|
||
|
|
DidVerificationRelationship2["keyAgreement"] = "keyAgreement";
|
||
|
|
DidVerificationRelationship2["capabilityInvocation"] = "capabilityInvocation";
|
||
|
|
DidVerificationRelationship2["capabilityDelegation"] = "capabilityDelegation";
|
||
|
|
})(DidVerificationRelationship || (DidVerificationRelationship = {}));
|
||
|
|
|
||
|
|
// dist/esm/types/did-resolution.js
|
||
|
|
var EMPTY_DID_RESOLUTION_RESULT = {
|
||
|
|
"@context": "https://w3id.org/did-resolution/v1",
|
||
|
|
didResolutionMetadata: {},
|
||
|
|
didDocument: null,
|
||
|
|
didDocumentMetadata: {}
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/did.js
|
||
|
|
var Did = class _Did {
|
||
|
|
/**
|
||
|
|
* Constructs a new `Did` instance from individual components.
|
||
|
|
*
|
||
|
|
* @param params - An object containing the parameters to be included in the DID URI.
|
||
|
|
* @param params.method - The name of the DID method.
|
||
|
|
* @param params.id - The DID method identifier.
|
||
|
|
* @param params.path - Optional. The path component of the DID URI.
|
||
|
|
* @param params.query - Optional. The query component of the DID URI.
|
||
|
|
* @param params.fragment - Optional. The fragment component of the DID URI.
|
||
|
|
* @param params.params - Optional. The query parameters in the DID URI.
|
||
|
|
*/
|
||
|
|
constructor({ method, id, path, query, fragment, params }) {
|
||
|
|
this.uri = `did:${method}:${id}`;
|
||
|
|
this.method = method;
|
||
|
|
this.id = id;
|
||
|
|
this.path = path;
|
||
|
|
this.query = query;
|
||
|
|
this.fragment = fragment;
|
||
|
|
this.params = params;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Parses a DID URI string into its individual components.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const did = Did.parse('did:example:123?service=agent&relativeRef=/credentials#degree');
|
||
|
|
*
|
||
|
|
* console.log(did.uri) // Output: 'did:example:123'
|
||
|
|
* console.log(did.method) // Output: 'example'
|
||
|
|
* console.log(did.id) // Output: '123'
|
||
|
|
* console.log(did.query) // Output: 'service=agent&relativeRef=/credentials'
|
||
|
|
* console.log(did.fragment) // Output: 'degree'
|
||
|
|
* console.log(did.params) // Output: { service: 'agent', relativeRef: '/credentials' }
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @params didUri - The DID URI string to be parsed.
|
||
|
|
* @returns A `Did` object representing the parsed DID URI, or `null` if the input string is not a valid DID URI.
|
||
|
|
*/
|
||
|
|
static parse(didUri) {
|
||
|
|
if (!didUri)
|
||
|
|
return null;
|
||
|
|
const match = _Did.DID_URI_PATTERN.exec(didUri);
|
||
|
|
if (!match || !match.groups)
|
||
|
|
return null;
|
||
|
|
const { method, id, path, query, fragment } = match.groups;
|
||
|
|
const did = {
|
||
|
|
uri: `did:${method}:${id}`,
|
||
|
|
method,
|
||
|
|
id
|
||
|
|
};
|
||
|
|
if (path)
|
||
|
|
did.path = path;
|
||
|
|
if (query)
|
||
|
|
did.query = query.slice(1);
|
||
|
|
if (fragment)
|
||
|
|
did.fragment = fragment.slice(1);
|
||
|
|
if (query) {
|
||
|
|
const parsedParams = {};
|
||
|
|
const paramPairs = query.slice(1).split("&");
|
||
|
|
for (const pair of paramPairs) {
|
||
|
|
const [key, value] = pair.split("=");
|
||
|
|
parsedParams[key] = value;
|
||
|
|
}
|
||
|
|
did.params = parsedParams;
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Did.METHOD_PATTERN = "([a-z0-9]+)";
|
||
|
|
Did.PCT_ENCODED_PATTERN = "(?:%[0-9a-fA-F]{2})";
|
||
|
|
Did.ID_CHAR_PATTERN = `(?:[a-zA-Z0-9._-]|${Did.PCT_ENCODED_PATTERN})`;
|
||
|
|
Did.METHOD_ID_PATTERN = `((?:${Did.ID_CHAR_PATTERN}*:)*(${Did.ID_CHAR_PATTERN}+))`;
|
||
|
|
Did.PATH_PATTERN = `(/[^#?]*)?`;
|
||
|
|
Did.QUERY_PATTERN = `([?][^#]*)?`;
|
||
|
|
Did.FRAGMENT_PATTERN = `(#.*)?`;
|
||
|
|
Did.DID_URI_PATTERN = new RegExp(`^did:(?<method>${Did.METHOD_PATTERN}):(?<id>${Did.METHOD_ID_PATTERN})(?<path>${Did.PATH_PATTERN})(?<query>${Did.QUERY_PATTERN})(?<fragment>${Did.FRAGMENT_PATTERN})$`);
|
||
|
|
|
||
|
|
// dist/esm/did-error.js
|
||
|
|
var DidError = class _DidError extends Error {
|
||
|
|
/**
|
||
|
|
* Constructs an instance of DidError, a custom error class for handling DID-related errors.
|
||
|
|
*
|
||
|
|
* @param code - A {@link DidErrorCode} representing the specific type of error encountered.
|
||
|
|
* @param message - A human-readable description of the error.
|
||
|
|
*/
|
||
|
|
constructor(code, message) {
|
||
|
|
super(`${code}: ${message}`);
|
||
|
|
this.code = code;
|
||
|
|
this.name = "DidError";
|
||
|
|
Object.setPrototypeOf(this, new.target.prototype);
|
||
|
|
if (Error.captureStackTrace) {
|
||
|
|
Error.captureStackTrace(this, _DidError);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var DidErrorCode;
|
||
|
|
(function(DidErrorCode2) {
|
||
|
|
DidErrorCode2["InvalidDid"] = "invalidDid";
|
||
|
|
DidErrorCode2["MethodNotSupported"] = "methodNotSupported";
|
||
|
|
DidErrorCode2["InternalError"] = "internalError";
|
||
|
|
DidErrorCode2["InvalidDidDocument"] = "invalidDidDocument";
|
||
|
|
DidErrorCode2["InvalidDidDocumentLength"] = "invalidDidDocumentLength";
|
||
|
|
DidErrorCode2["InvalidDidUrl"] = "invalidDidUrl";
|
||
|
|
DidErrorCode2["InvalidPreviousDidProof"] = "invalidPreviousDidProof";
|
||
|
|
DidErrorCode2["InvalidPublicKey"] = "invalidPublicKey";
|
||
|
|
DidErrorCode2["InvalidPublicKeyLength"] = "invalidPublicKeyLength";
|
||
|
|
DidErrorCode2["InvalidPublicKeyType"] = "invalidPublicKeyType";
|
||
|
|
DidErrorCode2["InvalidSignature"] = "invalidSignature";
|
||
|
|
DidErrorCode2["NotFound"] = "notFound";
|
||
|
|
DidErrorCode2["RepresentationNotSupported"] = "representationNotSupported";
|
||
|
|
DidErrorCode2["UnsupportedPublicKeyType"] = "unsupportedPublicKeyType";
|
||
|
|
})(DidErrorCode || (DidErrorCode = {}));
|
||
|
|
|
||
|
|
// dist/esm/bearer-did.js
|
||
|
|
var import_crypto2 = require("@web5/crypto");
|
||
|
|
|
||
|
|
// dist/esm/utils.js
|
||
|
|
var utils_exports = {};
|
||
|
|
__export(utils_exports, {
|
||
|
|
extractDidFragment: () => extractDidFragment,
|
||
|
|
getServices: () => getServices,
|
||
|
|
getVerificationMethodByKey: () => getVerificationMethodByKey,
|
||
|
|
getVerificationMethodTypes: () => getVerificationMethodTypes,
|
||
|
|
getVerificationMethods: () => getVerificationMethods,
|
||
|
|
getVerificationRelationshipsById: () => getVerificationRelationshipsById,
|
||
|
|
isDidService: () => isDidService,
|
||
|
|
isDidVerificationMethod: () => isDidVerificationMethod,
|
||
|
|
isDwnDidService: () => isDwnDidService,
|
||
|
|
keyBytesToMultibaseId: () => keyBytesToMultibaseId,
|
||
|
|
multibaseIdToKeyBytes: () => multibaseIdToKeyBytes
|
||
|
|
});
|
||
|
|
var import_common = require("@web5/common");
|
||
|
|
var import_crypto = require("@web5/crypto");
|
||
|
|
var __awaiter = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
function extractDidFragment(input) {
|
||
|
|
if (typeof input !== "string")
|
||
|
|
return void 0;
|
||
|
|
if (input.length === 0)
|
||
|
|
return void 0;
|
||
|
|
return input.split("#").pop();
|
||
|
|
}
|
||
|
|
function getServices({ didDocument, id, type }) {
|
||
|
|
var _a, _b;
|
||
|
|
return (_b = (_a = didDocument === null || didDocument === void 0 ? void 0 : didDocument.service) === null || _a === void 0 ? void 0 : _a.filter((service) => {
|
||
|
|
if (id && service.id !== id)
|
||
|
|
return false;
|
||
|
|
if (type && service.type !== type)
|
||
|
|
return false;
|
||
|
|
return true;
|
||
|
|
})) !== null && _b !== void 0 ? _b : [];
|
||
|
|
}
|
||
|
|
function getVerificationMethodByKey(_a) {
|
||
|
|
return __awaiter(this, arguments, void 0, function* ({ didDocument, publicKeyJwk, publicKeyMultibase }) {
|
||
|
|
const verificationMethods = getVerificationMethods({ didDocument });
|
||
|
|
for (let method of verificationMethods) {
|
||
|
|
if (publicKeyJwk && method.publicKeyJwk) {
|
||
|
|
const publicKeyThumbprint = yield (0, import_crypto.computeJwkThumbprint)({ jwk: publicKeyJwk });
|
||
|
|
if (publicKeyThumbprint === (yield (0, import_crypto.computeJwkThumbprint)({ jwk: method.publicKeyJwk }))) {
|
||
|
|
return method;
|
||
|
|
}
|
||
|
|
} else if (publicKeyMultibase && method.publicKeyMultibase) {
|
||
|
|
if (publicKeyMultibase === method.publicKeyMultibase) {
|
||
|
|
return method;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
function getVerificationMethods({ didDocument }) {
|
||
|
|
var _a, _b;
|
||
|
|
if (!didDocument)
|
||
|
|
throw new TypeError(`Required parameter missing: 'didDocument'`);
|
||
|
|
const verificationMethods = [];
|
||
|
|
verificationMethods.push(...(_b = (_a = didDocument.verificationMethod) === null || _a === void 0 ? void 0 : _a.filter(isDidVerificationMethod)) !== null && _b !== void 0 ? _b : []);
|
||
|
|
Object.keys(DidVerificationRelationship).forEach((relationship) => {
|
||
|
|
var _a2, _b2;
|
||
|
|
verificationMethods.push(...(_b2 = (_a2 = didDocument[relationship]) === null || _a2 === void 0 ? void 0 : _a2.filter(isDidVerificationMethod)) !== null && _b2 !== void 0 ? _b2 : []);
|
||
|
|
});
|
||
|
|
return verificationMethods;
|
||
|
|
}
|
||
|
|
function getVerificationMethodTypes({ didDocument }) {
|
||
|
|
const verificationMethods = getVerificationMethods({ didDocument });
|
||
|
|
const types = verificationMethods.map((method) => method.type);
|
||
|
|
return [...new Set(types)];
|
||
|
|
}
|
||
|
|
function getVerificationRelationshipsById({ didDocument, methodId }) {
|
||
|
|
const relationships = [];
|
||
|
|
Object.keys(DidVerificationRelationship).forEach((relationship) => {
|
||
|
|
if (Array.isArray(didDocument[relationship])) {
|
||
|
|
const relationshipMethods = didDocument[relationship];
|
||
|
|
const methodIdFragment = extractDidFragment(methodId);
|
||
|
|
const containsMethodId = relationshipMethods.some((method) => {
|
||
|
|
const isByReferenceMatch = extractDidFragment(method) === methodIdFragment;
|
||
|
|
const isEmbeddedMethodMatch = isDidVerificationMethod(method) && extractDidFragment(method.id) === methodIdFragment;
|
||
|
|
return isByReferenceMatch || isEmbeddedMethodMatch;
|
||
|
|
});
|
||
|
|
if (containsMethodId) {
|
||
|
|
relationships.push(relationship);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return relationships;
|
||
|
|
}
|
||
|
|
function isDidService(obj) {
|
||
|
|
if (!obj || typeof obj !== "object" || obj === null)
|
||
|
|
return false;
|
||
|
|
return "id" in obj && "type" in obj && "serviceEndpoint" in obj;
|
||
|
|
}
|
||
|
|
function isDwnDidService(obj) {
|
||
|
|
if (!isDidService(obj))
|
||
|
|
return false;
|
||
|
|
if (obj.type !== "DecentralizedWebNode")
|
||
|
|
return false;
|
||
|
|
if (!("enc" in obj && "sig" in obj))
|
||
|
|
return false;
|
||
|
|
const isStringOrStringArray = (prop) => typeof prop === "string" || Array.isArray(prop) && prop.every((item) => typeof item === "string");
|
||
|
|
return isStringOrStringArray(obj.enc) && isStringOrStringArray(obj.sig);
|
||
|
|
}
|
||
|
|
function isDidVerificationMethod(obj) {
|
||
|
|
if (!obj || typeof obj !== "object" || obj === null)
|
||
|
|
return false;
|
||
|
|
if (!("id" in obj && "type" in obj && "controller" in obj))
|
||
|
|
return false;
|
||
|
|
if (typeof obj.id !== "string")
|
||
|
|
return false;
|
||
|
|
if (typeof obj.type !== "string")
|
||
|
|
return false;
|
||
|
|
if (typeof obj.controller !== "string")
|
||
|
|
return false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
function keyBytesToMultibaseId({ keyBytes, multicodecCode, multicodecName }) {
|
||
|
|
const prefixedKey = import_common.Multicodec.addPrefix({
|
||
|
|
code: multicodecCode,
|
||
|
|
data: keyBytes,
|
||
|
|
name: multicodecName
|
||
|
|
});
|
||
|
|
const prefixedKeyB58 = import_common.Convert.uint8Array(prefixedKey).toBase58Btc();
|
||
|
|
const multibaseKeyId = import_common.Convert.base58Btc(prefixedKeyB58).toMultibase();
|
||
|
|
return multibaseKeyId;
|
||
|
|
}
|
||
|
|
function multibaseIdToKeyBytes({ multibaseKeyId }) {
|
||
|
|
try {
|
||
|
|
const prefixedKeyB58 = import_common.Convert.multibase(multibaseKeyId).toBase58Btc();
|
||
|
|
const prefixedKey = import_common.Convert.base58Btc(prefixedKeyB58).toUint8Array();
|
||
|
|
const { code, data, name } = import_common.Multicodec.removePrefix({ prefixedData: prefixedKey });
|
||
|
|
return { keyBytes: data, multicodecCode: code, multicodecName: name };
|
||
|
|
} catch (error) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDid, `Invalid multibase identifier: ${multibaseKeyId}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// dist/esm/bearer-did.js
|
||
|
|
var __awaiter2 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var BearerDid = class _BearerDid {
|
||
|
|
constructor({ uri, document, metadata, keyManager }) {
|
||
|
|
this.uri = uri;
|
||
|
|
this.document = document;
|
||
|
|
this.metadata = metadata;
|
||
|
|
this.keyManager = keyManager;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a `BearerDid` object to a portable format containing the URI and verification methods
|
||
|
|
* associated with the DID.
|
||
|
|
*
|
||
|
|
* This method is useful when you need to represent the key material and metadata associated with
|
||
|
|
* a DID in format that can be used independently of the specific DID method implementation. It
|
||
|
|
* extracts both public and private keys from the DID's key manager and organizes them into a
|
||
|
|
* `PortableDid` structure.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* If the DID's key manager does not allow private keys to be exported, the `PortableDid` returned
|
||
|
|
* will not contain a `privateKeys` property. This enables the importing and exporting DIDs that
|
||
|
|
* use the same underlying KMS even if the KMS does not support exporting private keys. Examples
|
||
|
|
* include hardware security modules (HSMs) and cloud-based KMS services like AWS KMS.
|
||
|
|
*
|
||
|
|
* If the DID's key manager does support exporting private keys, the resulting `PortableDid` will
|
||
|
|
* include a `privateKeys` property which contains the same number of entries as there are
|
||
|
|
* verification methods as the DID document, each with its associated private key and the
|
||
|
|
* purpose(s) for which the key can be used (e.g., `authentication`, `assertionMethod`, etc.).
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Assuming `did` is an instance of BearerDid
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // portableDid now contains the DID URI, document, metadata, and optionally, private keys.
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @returns A `PortableDid` containing the URI, DID document, metadata, and optionally private
|
||
|
|
* keys associated with the `BearerDid`.
|
||
|
|
* @throws An error if the DID document does not contain any verification methods or the keys for
|
||
|
|
* any verification method are missing in the key manager.
|
||
|
|
*/
|
||
|
|
export() {
|
||
|
|
return __awaiter2(this, void 0, void 0, function* () {
|
||
|
|
if (!(Array.isArray(this.document.verificationMethod) && this.document.verificationMethod.length > 0)) {
|
||
|
|
throw new Error(`DID document for '${this.uri}' is missing verification methods`);
|
||
|
|
}
|
||
|
|
let portableDid = {
|
||
|
|
uri: this.uri,
|
||
|
|
document: this.document,
|
||
|
|
metadata: this.metadata
|
||
|
|
};
|
||
|
|
if ("exportKey" in this.keyManager && typeof this.keyManager.exportKey === "function") {
|
||
|
|
const privateKeys = [];
|
||
|
|
for (let vm of this.document.verificationMethod) {
|
||
|
|
if (!vm.publicKeyJwk) {
|
||
|
|
throw new Error(`Verification method '${vm.id}' does not contain a public key in JWK format`);
|
||
|
|
}
|
||
|
|
const keyUri = yield this.keyManager.getKeyUri({ key: vm.publicKeyJwk });
|
||
|
|
const privateKey = yield this.keyManager.exportKey({ keyUri });
|
||
|
|
privateKeys.push(Object.assign({}, privateKey));
|
||
|
|
}
|
||
|
|
portableDid.privateKeys = privateKeys;
|
||
|
|
}
|
||
|
|
return portableDid;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Return a {@link Signer} that can be used to sign messages, credentials, or arbitrary data.
|
||
|
|
*
|
||
|
|
* If given, the `methodId` parameter is used to select a key from the verification methods
|
||
|
|
* present in the DID Document.
|
||
|
|
*
|
||
|
|
* If `methodID` is not given, the first verification method intended for signing claims is used.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `getSigner` operation.
|
||
|
|
* @param params.methodId - ID of the verification method key that will be used for sign and
|
||
|
|
* verify operations. Optional.
|
||
|
|
* @returns An instantiated {@link Signer} that can be used to sign and verify data.
|
||
|
|
*/
|
||
|
|
getSigner(params) {
|
||
|
|
return __awaiter2(this, void 0, void 0, function* () {
|
||
|
|
var _a;
|
||
|
|
const verificationMethod = (_a = this.document.verificationMethod) === null || _a === void 0 ? void 0 : _a.find((vm) => {
|
||
|
|
var _a2, _b;
|
||
|
|
return extractDidFragment(vm.id) === ((_a2 = extractDidFragment(params === null || params === void 0 ? void 0 : params.methodId)) !== null && _a2 !== void 0 ? _a2 : extractDidFragment((_b = this.document.assertionMethod) === null || _b === void 0 ? void 0 : _b[0]));
|
||
|
|
});
|
||
|
|
if (!(verificationMethod && verificationMethod.publicKeyJwk)) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "A verification method intended for signing could not be determined from the DID Document");
|
||
|
|
}
|
||
|
|
const keyUri = yield this.keyManager.getKeyUri({ key: verificationMethod.publicKeyJwk });
|
||
|
|
const publicKey = yield this.keyManager.getPublicKey({ keyUri });
|
||
|
|
const keyManager = this.keyManager;
|
||
|
|
const algorithm = import_crypto2.utils.getJoseSignatureAlgorithmFromPublicKey(publicKey);
|
||
|
|
return {
|
||
|
|
algorithm,
|
||
|
|
keyId: verificationMethod.id,
|
||
|
|
sign(_a2) {
|
||
|
|
return __awaiter2(this, arguments, void 0, function* ({ data }) {
|
||
|
|
const signature = yield keyManager.sign({ data, keyUri });
|
||
|
|
return signature;
|
||
|
|
});
|
||
|
|
},
|
||
|
|
verify(_a2) {
|
||
|
|
return __awaiter2(this, arguments, void 0, function* ({ data, signature }) {
|
||
|
|
const isValid = yield keyManager.verify({ data, key: publicKey, signature });
|
||
|
|
return isValid;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Instantiates a {@link BearerDid} object from a given {@link PortableDid}.
|
||
|
|
*
|
||
|
|
* This method allows for the creation of a `BearerDid` object using a previously created DID's
|
||
|
|
* key material, DID document, and metadata.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Export an existing BearerDid to PortableDid format.
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // Reconstruct a BearerDid object from the PortableDid.
|
||
|
|
* const did = await BearerDid.import({ portableDid });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the import operation.
|
||
|
|
* @param params.portableDid - The PortableDid object to import.
|
||
|
|
* @param params.keyManager - Optionally specify an external Key Management System (KMS) used to
|
||
|
|
* generate keys and sign data. If not given, a new
|
||
|
|
* {@link LocalKeyManager} instance will be created and
|
||
|
|
* used.
|
||
|
|
* @returns A Promise resolving to a `BearerDid` object representing the DID formed from the
|
||
|
|
* provided PortableDid.
|
||
|
|
* @throws An error if the PortableDid document does not contain any verification methods or the
|
||
|
|
* keys for any verification method are missing in the key manager.
|
||
|
|
*/
|
||
|
|
static import(_a) {
|
||
|
|
return __awaiter2(this, arguments, void 0, function* ({ portableDid, keyManager = new import_crypto2.LocalKeyManager() }) {
|
||
|
|
var _b;
|
||
|
|
const verificationMethods = getVerificationMethods({ didDocument: portableDid.document });
|
||
|
|
if (verificationMethods.length === 0) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocument, `At least one verification method is required but 0 were given`);
|
||
|
|
}
|
||
|
|
for (let key of (_b = portableDid.privateKeys) !== null && _b !== void 0 ? _b : []) {
|
||
|
|
yield keyManager.importKey({ key });
|
||
|
|
}
|
||
|
|
for (let vm of verificationMethods) {
|
||
|
|
if (!vm.publicKeyJwk) {
|
||
|
|
throw new Error(`Verification method '${vm.id}' does not contain a public key in JWK format`);
|
||
|
|
}
|
||
|
|
const keyUri = yield keyManager.getKeyUri({ key: vm.publicKeyJwk });
|
||
|
|
yield keyManager.getPublicKey({ keyUri });
|
||
|
|
}
|
||
|
|
const did = new _BearerDid({
|
||
|
|
uri: portableDid.uri,
|
||
|
|
document: portableDid.document,
|
||
|
|
metadata: portableDid.metadata,
|
||
|
|
keyManager
|
||
|
|
});
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/uint8-util@2.2.4/node_modules/uint8-util/util.js
|
||
|
|
var alphabet = "0123456789abcdef";
|
||
|
|
var encodeLookup = [];
|
||
|
|
var decodeLookup = [];
|
||
|
|
for (let i = 0; i < 256; i++) {
|
||
|
|
encodeLookup[i] = alphabet[i >> 4 & 15] + alphabet[i & 15];
|
||
|
|
if (i < 16) {
|
||
|
|
if (i < 10) {
|
||
|
|
decodeLookup[48 + i] = i;
|
||
|
|
} else {
|
||
|
|
decodeLookup[97 - 10 + i] = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var arr2hex = (data) => {
|
||
|
|
const length2 = data.length;
|
||
|
|
let string = "";
|
||
|
|
let i = 0;
|
||
|
|
while (i < length2) {
|
||
|
|
string += encodeLookup[data[i++]];
|
||
|
|
}
|
||
|
|
return string;
|
||
|
|
};
|
||
|
|
var concat = (chunks, size = 0) => {
|
||
|
|
const length2 = chunks.length || 0;
|
||
|
|
if (!size) {
|
||
|
|
let i2 = length2;
|
||
|
|
while (i2--)
|
||
|
|
size += chunks[i2].length;
|
||
|
|
}
|
||
|
|
const b = new Uint8Array(size);
|
||
|
|
let offset = size;
|
||
|
|
let i = length2;
|
||
|
|
while (i--) {
|
||
|
|
offset -= chunks[i].length;
|
||
|
|
b.set(chunks[i], offset);
|
||
|
|
}
|
||
|
|
return b;
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/uint8-util@2.2.4/node_modules/uint8-util/_node.js
|
||
|
|
var decoder = new TextDecoder();
|
||
|
|
var arr2text = (data, enc) => {
|
||
|
|
if (data.byteLength > 1024) {
|
||
|
|
if (!enc)
|
||
|
|
return decoder.decode(data);
|
||
|
|
const dec = new TextDecoder(enc);
|
||
|
|
return dec.decode(data);
|
||
|
|
}
|
||
|
|
return Buffer.from(data).toString(enc || "utf8");
|
||
|
|
};
|
||
|
|
var text2arr = (str3) => new Uint8Array(Buffer.from(str3, "utf8"));
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/bencode@4.0.0/node_modules/bencode/lib/util.js
|
||
|
|
function digitCount(value) {
|
||
|
|
const sign = value < 0 ? 1 : 0;
|
||
|
|
value = Math.abs(Number(value || 1));
|
||
|
|
return Math.floor(Math.log10(value)) + 1 + sign;
|
||
|
|
}
|
||
|
|
function getType(value) {
|
||
|
|
if (ArrayBuffer.isView(value))
|
||
|
|
return "arraybufferview";
|
||
|
|
if (Array.isArray(value))
|
||
|
|
return "array";
|
||
|
|
if (value instanceof Number)
|
||
|
|
return "number";
|
||
|
|
if (value instanceof Boolean)
|
||
|
|
return "boolean";
|
||
|
|
if (value instanceof Set)
|
||
|
|
return "set";
|
||
|
|
if (value instanceof Map)
|
||
|
|
return "map";
|
||
|
|
if (value instanceof String)
|
||
|
|
return "string";
|
||
|
|
if (value instanceof ArrayBuffer)
|
||
|
|
return "arraybuffer";
|
||
|
|
return typeof value;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/bencode@4.0.0/node_modules/bencode/lib/encode.js
|
||
|
|
function encode(data, buffer, offset) {
|
||
|
|
const buffers = [];
|
||
|
|
let result = null;
|
||
|
|
encode._encode(buffers, data);
|
||
|
|
result = concat(buffers);
|
||
|
|
encode.bytes = result.length;
|
||
|
|
if (ArrayBuffer.isView(buffer)) {
|
||
|
|
buffer.set(result, offset);
|
||
|
|
return buffer;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
encode.bytes = -1;
|
||
|
|
encode._floatConversionDetected = false;
|
||
|
|
encode._encode = function(buffers, data) {
|
||
|
|
if (data == null) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
switch (getType(data)) {
|
||
|
|
case "object":
|
||
|
|
encode.dict(buffers, data);
|
||
|
|
break;
|
||
|
|
case "map":
|
||
|
|
encode.dictMap(buffers, data);
|
||
|
|
break;
|
||
|
|
case "array":
|
||
|
|
encode.list(buffers, data);
|
||
|
|
break;
|
||
|
|
case "set":
|
||
|
|
encode.listSet(buffers, data);
|
||
|
|
break;
|
||
|
|
case "string":
|
||
|
|
encode.string(buffers, data);
|
||
|
|
break;
|
||
|
|
case "number":
|
||
|
|
encode.number(buffers, data);
|
||
|
|
break;
|
||
|
|
case "boolean":
|
||
|
|
encode.number(buffers, data);
|
||
|
|
break;
|
||
|
|
case "arraybufferview":
|
||
|
|
encode.buffer(buffers, new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
|
||
|
|
break;
|
||
|
|
case "arraybuffer":
|
||
|
|
encode.buffer(buffers, new Uint8Array(data));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var buffE = new Uint8Array([101]);
|
||
|
|
var buffD = new Uint8Array([100]);
|
||
|
|
var buffL = new Uint8Array([108]);
|
||
|
|
encode.buffer = function(buffers, data) {
|
||
|
|
buffers.push(text2arr(data.length + ":"), data);
|
||
|
|
};
|
||
|
|
encode.string = function(buffers, data) {
|
||
|
|
buffers.push(text2arr(text2arr(data).byteLength + ":" + data));
|
||
|
|
};
|
||
|
|
encode.number = function(buffers, data) {
|
||
|
|
if (Number.isInteger(data))
|
||
|
|
return buffers.push(text2arr("i" + BigInt(data) + "e"));
|
||
|
|
const maxLo = 2147483648;
|
||
|
|
const hi = data / maxLo << 0;
|
||
|
|
const lo = data % maxLo << 0;
|
||
|
|
const val = hi * maxLo + lo;
|
||
|
|
buffers.push(text2arr("i" + val + "e"));
|
||
|
|
if (val !== data && !encode._floatConversionDetected) {
|
||
|
|
encode._floatConversionDetected = true;
|
||
|
|
console.warn(
|
||
|
|
'WARNING: Possible data corruption detected with value "' + data + '":',
|
||
|
|
'Bencoding only defines support for integers, value was converted to "' + val + '"'
|
||
|
|
);
|
||
|
|
console.trace();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
encode.dict = function(buffers, data) {
|
||
|
|
buffers.push(buffD);
|
||
|
|
let j = 0;
|
||
|
|
let k;
|
||
|
|
const keys = Object.keys(data).sort();
|
||
|
|
const kl = keys.length;
|
||
|
|
for (; j < kl; j++) {
|
||
|
|
k = keys[j];
|
||
|
|
if (data[k] == null)
|
||
|
|
continue;
|
||
|
|
encode.string(buffers, k);
|
||
|
|
encode._encode(buffers, data[k]);
|
||
|
|
}
|
||
|
|
buffers.push(buffE);
|
||
|
|
};
|
||
|
|
encode.dictMap = function(buffers, data) {
|
||
|
|
buffers.push(buffD);
|
||
|
|
const keys = Array.from(data.keys()).sort();
|
||
|
|
for (const key of keys) {
|
||
|
|
if (data.get(key) == null)
|
||
|
|
continue;
|
||
|
|
ArrayBuffer.isView(key) ? encode._encode(buffers, key) : encode.string(buffers, String(key));
|
||
|
|
encode._encode(buffers, data.get(key));
|
||
|
|
}
|
||
|
|
buffers.push(buffE);
|
||
|
|
};
|
||
|
|
encode.list = function(buffers, data) {
|
||
|
|
let i = 0;
|
||
|
|
const c = data.length;
|
||
|
|
buffers.push(buffL);
|
||
|
|
for (; i < c; i++) {
|
||
|
|
if (data[i] == null)
|
||
|
|
continue;
|
||
|
|
encode._encode(buffers, data[i]);
|
||
|
|
}
|
||
|
|
buffers.push(buffE);
|
||
|
|
};
|
||
|
|
encode.listSet = function(buffers, data) {
|
||
|
|
buffers.push(buffL);
|
||
|
|
for (const item of data) {
|
||
|
|
if (item == null)
|
||
|
|
continue;
|
||
|
|
encode._encode(buffers, item);
|
||
|
|
}
|
||
|
|
buffers.push(buffE);
|
||
|
|
};
|
||
|
|
var encode_default = encode;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/bencode@4.0.0/node_modules/bencode/lib/decode.js
|
||
|
|
var INTEGER_START = 105;
|
||
|
|
var STRING_DELIM = 58;
|
||
|
|
var DICTIONARY_START = 100;
|
||
|
|
var LIST_START = 108;
|
||
|
|
var END_OF_TYPE = 101;
|
||
|
|
function getIntFromBuffer(buffer, start, end) {
|
||
|
|
let sum = 0;
|
||
|
|
let sign = 1;
|
||
|
|
for (let i = start; i < end; i++) {
|
||
|
|
const num = buffer[i];
|
||
|
|
if (num < 58 && num >= 48) {
|
||
|
|
sum = sum * 10 + (num - 48);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (i === start && num === 43) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (i === start && num === 45) {
|
||
|
|
sign = -1;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (num === 46) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
throw new Error("not a number: buffer[" + i + "] = " + num);
|
||
|
|
}
|
||
|
|
return sum * sign;
|
||
|
|
}
|
||
|
|
function decode(data, start, end, encoding) {
|
||
|
|
if (data == null || data.length === 0) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (typeof start !== "number" && encoding == null) {
|
||
|
|
encoding = start;
|
||
|
|
start = void 0;
|
||
|
|
}
|
||
|
|
if (typeof end !== "number" && encoding == null) {
|
||
|
|
encoding = end;
|
||
|
|
end = void 0;
|
||
|
|
}
|
||
|
|
decode.position = 0;
|
||
|
|
decode.encoding = encoding || null;
|
||
|
|
decode.data = !ArrayBuffer.isView(data) ? text2arr(data) : new Uint8Array(data.slice(start, end));
|
||
|
|
decode.bytes = decode.data.length;
|
||
|
|
return decode.next();
|
||
|
|
}
|
||
|
|
decode.bytes = 0;
|
||
|
|
decode.position = 0;
|
||
|
|
decode.data = null;
|
||
|
|
decode.encoding = null;
|
||
|
|
decode.next = function() {
|
||
|
|
switch (decode.data[decode.position]) {
|
||
|
|
case DICTIONARY_START:
|
||
|
|
return decode.dictionary();
|
||
|
|
case LIST_START:
|
||
|
|
return decode.list();
|
||
|
|
case INTEGER_START:
|
||
|
|
return decode.integer();
|
||
|
|
default:
|
||
|
|
return decode.buffer();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
decode.find = function(chr) {
|
||
|
|
let i = decode.position;
|
||
|
|
const c = decode.data.length;
|
||
|
|
const d = decode.data;
|
||
|
|
while (i < c) {
|
||
|
|
if (d[i] === chr)
|
||
|
|
return i;
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
throw new Error(
|
||
|
|
'Invalid data: Missing delimiter "' + String.fromCharCode(chr) + '" [0x' + chr.toString(16) + "]"
|
||
|
|
);
|
||
|
|
};
|
||
|
|
decode.dictionary = function() {
|
||
|
|
decode.position++;
|
||
|
|
const dict = {};
|
||
|
|
while (decode.data[decode.position] !== END_OF_TYPE) {
|
||
|
|
const buffer = decode.buffer();
|
||
|
|
let key = arr2text(buffer);
|
||
|
|
if (key.includes("\uFFFD"))
|
||
|
|
key = arr2hex(buffer);
|
||
|
|
dict[key] = decode.next();
|
||
|
|
}
|
||
|
|
decode.position++;
|
||
|
|
return dict;
|
||
|
|
};
|
||
|
|
decode.list = function() {
|
||
|
|
decode.position++;
|
||
|
|
const lst = [];
|
||
|
|
while (decode.data[decode.position] !== END_OF_TYPE) {
|
||
|
|
lst.push(decode.next());
|
||
|
|
}
|
||
|
|
decode.position++;
|
||
|
|
return lst;
|
||
|
|
};
|
||
|
|
decode.integer = function() {
|
||
|
|
const end = decode.find(END_OF_TYPE);
|
||
|
|
const number = getIntFromBuffer(decode.data, decode.position + 1, end);
|
||
|
|
decode.position += end + 1 - decode.position;
|
||
|
|
return number;
|
||
|
|
};
|
||
|
|
decode.buffer = function() {
|
||
|
|
let sep = decode.find(STRING_DELIM);
|
||
|
|
const length2 = getIntFromBuffer(decode.data, decode.position, sep);
|
||
|
|
const end = ++sep + length2;
|
||
|
|
decode.position = end;
|
||
|
|
return decode.encoding ? arr2text(decode.data.slice(sep, end)) : decode.data.slice(sep, end);
|
||
|
|
};
|
||
|
|
var decode_default = decode;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/bencode@4.0.0/node_modules/bencode/lib/encoding-length.js
|
||
|
|
function listLength(list) {
|
||
|
|
let length2 = 1 + 1;
|
||
|
|
for (const value of list) {
|
||
|
|
length2 += encodingLength(value);
|
||
|
|
}
|
||
|
|
return length2;
|
||
|
|
}
|
||
|
|
function mapLength(map) {
|
||
|
|
let length2 = 1 + 1;
|
||
|
|
for (const [key, value] of map) {
|
||
|
|
const keyLength = text2arr(key).byteLength;
|
||
|
|
length2 += digitCount(keyLength) + 1 + keyLength;
|
||
|
|
length2 += encodingLength(value);
|
||
|
|
}
|
||
|
|
return length2;
|
||
|
|
}
|
||
|
|
function objectLength(value) {
|
||
|
|
let length2 = 1 + 1;
|
||
|
|
const keys = Object.keys(value);
|
||
|
|
for (let i = 0; i < keys.length; i++) {
|
||
|
|
const keyLength = text2arr(keys[i]).byteLength;
|
||
|
|
length2 += digitCount(keyLength) + 1 + keyLength;
|
||
|
|
length2 += encodingLength(value[keys[i]]);
|
||
|
|
}
|
||
|
|
return length2;
|
||
|
|
}
|
||
|
|
function stringLength(value) {
|
||
|
|
const length2 = text2arr(value).byteLength;
|
||
|
|
return digitCount(length2) + 1 + length2;
|
||
|
|
}
|
||
|
|
function arrayBufferLength(value) {
|
||
|
|
const length2 = value.byteLength - value.byteOffset;
|
||
|
|
return digitCount(length2) + 1 + length2;
|
||
|
|
}
|
||
|
|
function encodingLength(value) {
|
||
|
|
const length2 = 0;
|
||
|
|
if (value == null)
|
||
|
|
return length2;
|
||
|
|
const type = getType(value);
|
||
|
|
switch (type) {
|
||
|
|
case "arraybufferview":
|
||
|
|
return arrayBufferLength(value);
|
||
|
|
case "string":
|
||
|
|
return stringLength(value);
|
||
|
|
case "array":
|
||
|
|
case "set":
|
||
|
|
return listLength(value);
|
||
|
|
case "number":
|
||
|
|
return 1 + digitCount(Math.floor(value)) + 1;
|
||
|
|
case "bigint":
|
||
|
|
return 1 + value.toString().length + 1;
|
||
|
|
case "object":
|
||
|
|
return objectLength(value);
|
||
|
|
case "map":
|
||
|
|
return mapLength(value);
|
||
|
|
default:
|
||
|
|
throw new TypeError(`Unsupported value of type "${type}"`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var encoding_length_default = encodingLength;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/bencode@4.0.0/node_modules/bencode/index.js
|
||
|
|
var encodingLength2 = encoding_length_default;
|
||
|
|
var bencode_default = { encode: encode_default, decode: decode_default, byteLength: encoding_length_default, encodingLength: encodingLength2 };
|
||
|
|
|
||
|
|
// dist/esm/methods/did-dht.js
|
||
|
|
var import_common2 = require("@web5/common");
|
||
|
|
var import_crypto3 = require("@web5/crypto");
|
||
|
|
var import_dns_packet = require("@dnsquery/dns-packet");
|
||
|
|
|
||
|
|
// dist/esm/methods/did-method.js
|
||
|
|
var __awaiter3 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidMethod = class {
|
||
|
|
/**
|
||
|
|
* MUST be implemented by all DID method implementations that extend {@link DidMethod}.
|
||
|
|
*
|
||
|
|
* Given the W3C DID Document of a DID, return the verification method that will be used for
|
||
|
|
* signing messages and credentials. If given, the `methodId` parameter is used to select the
|
||
|
|
* verification method. If not given, each DID method implementation will select a default
|
||
|
|
* verification method from the DID Document.
|
||
|
|
*
|
||
|
|
* @param _params - The parameters for the `getSigningMethod` operation.
|
||
|
|
* @param _params.didDocument - DID Document to get the verification method from.
|
||
|
|
* @param _params.methodId - ID of the verification method to use for signing.
|
||
|
|
* @returns Verification method to use for signing.
|
||
|
|
*/
|
||
|
|
static getSigningMethod(_params) {
|
||
|
|
return __awaiter3(this, void 0, void 0, function* () {
|
||
|
|
throw new Error(`Not implemented: Classes extending DidMethod must implement getSigningMethod()`);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* MUST be implemented by all DID method implementations that extend {@link DidMethod}.
|
||
|
|
*
|
||
|
|
* Resolves a DID URI to a DID Document.
|
||
|
|
*
|
||
|
|
* @param _didUri - The DID to be resolved.
|
||
|
|
* @param _options - Optional parameters for resolving the DID.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(_didUri, _options) {
|
||
|
|
return __awaiter3(this, void 0, void 0, function* () {
|
||
|
|
throw new Error(`Not implemented: Classes extending DidMethod must implement resolve()`);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/methods/did-dht.js
|
||
|
|
var __awaiter4 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var __rest = function(s, e) {
|
||
|
|
var t = {};
|
||
|
|
for (var p in s)
|
||
|
|
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||
|
|
t[p] = s[p];
|
||
|
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||
|
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||
|
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||
|
|
t[p[i]] = s[p[i]];
|
||
|
|
}
|
||
|
|
return t;
|
||
|
|
};
|
||
|
|
var DEFAULT_GATEWAY_URI = "https://diddht.tbddev.org";
|
||
|
|
var DID_DHT_SPECIFICATION_VERSION = 0;
|
||
|
|
var DNS_RECORD_TTL = 7200;
|
||
|
|
var PROPERTY_SEPARATOR = ";";
|
||
|
|
var VALUE_SEPARATOR = ",";
|
||
|
|
var DidDhtRegisteredDidType;
|
||
|
|
(function(DidDhtRegisteredDidType2) {
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["Discoverable"] = 0] = "Discoverable";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["Organization"] = 1] = "Organization";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["Government"] = 2] = "Government";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["Corporation"] = 3] = "Corporation";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["LocalBusiness"] = 4] = "LocalBusiness";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["SoftwarePackage"] = 5] = "SoftwarePackage";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["WebApp"] = 6] = "WebApp";
|
||
|
|
DidDhtRegisteredDidType2[DidDhtRegisteredDidType2["FinancialInstitution"] = 7] = "FinancialInstitution";
|
||
|
|
})(DidDhtRegisteredDidType || (DidDhtRegisteredDidType = {}));
|
||
|
|
var DidDhtRegisteredKeyType;
|
||
|
|
(function(DidDhtRegisteredKeyType2) {
|
||
|
|
DidDhtRegisteredKeyType2[DidDhtRegisteredKeyType2["Ed25519"] = 0] = "Ed25519";
|
||
|
|
DidDhtRegisteredKeyType2[DidDhtRegisteredKeyType2["secp256k1"] = 1] = "secp256k1";
|
||
|
|
DidDhtRegisteredKeyType2[DidDhtRegisteredKeyType2["secp256r1"] = 2] = "secp256r1";
|
||
|
|
DidDhtRegisteredKeyType2[DidDhtRegisteredKeyType2["X25519"] = 3] = "X25519";
|
||
|
|
})(DidDhtRegisteredKeyType || (DidDhtRegisteredKeyType = {}));
|
||
|
|
var DidDhtVerificationRelationship;
|
||
|
|
(function(DidDhtVerificationRelationship2) {
|
||
|
|
DidDhtVerificationRelationship2["authentication"] = "auth";
|
||
|
|
DidDhtVerificationRelationship2["assertionMethod"] = "asm";
|
||
|
|
DidDhtVerificationRelationship2["capabilityDelegation"] = "del";
|
||
|
|
DidDhtVerificationRelationship2["capabilityInvocation"] = "inv";
|
||
|
|
DidDhtVerificationRelationship2["keyAgreement"] = "agm";
|
||
|
|
})(DidDhtVerificationRelationship || (DidDhtVerificationRelationship = {}));
|
||
|
|
var AlgorithmToKeyTypeMap = {
|
||
|
|
Ed25519: DidDhtRegisteredKeyType.Ed25519,
|
||
|
|
ES256K: DidDhtRegisteredKeyType.secp256k1,
|
||
|
|
ES256: DidDhtRegisteredKeyType.secp256r1,
|
||
|
|
"P-256": DidDhtRegisteredKeyType.secp256r1,
|
||
|
|
secp256k1: DidDhtRegisteredKeyType.secp256k1,
|
||
|
|
secp256r1: DidDhtRegisteredKeyType.secp256r1,
|
||
|
|
X25519: DidDhtRegisteredKeyType.X25519
|
||
|
|
};
|
||
|
|
var KeyTypeToDefaultAlgorithmMap = {
|
||
|
|
[DidDhtRegisteredKeyType.Ed25519]: "Ed25519",
|
||
|
|
[DidDhtRegisteredKeyType.secp256k1]: "ES256K",
|
||
|
|
[DidDhtRegisteredKeyType.secp256r1]: "ES256",
|
||
|
|
[DidDhtRegisteredKeyType.X25519]: "ECDH-ES+A256KW"
|
||
|
|
};
|
||
|
|
var DidDht = class _DidDht extends DidMethod {
|
||
|
|
/**
|
||
|
|
* Creates a new DID using the `did:dht` method formed from a newly generated key.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* The DID URI is formed by z-base-32 encoding the Identity Key public key and prefixing with
|
||
|
|
* `did:dht:`.
|
||
|
|
*
|
||
|
|
* Notes:
|
||
|
|
* - If no `options` are given, by default a new Ed25519 key will be generated which serves as the
|
||
|
|
* Identity Key.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // DID Creation
|
||
|
|
* const did = await DidDht.create();
|
||
|
|
*
|
||
|
|
* // DID Creation with a KMS
|
||
|
|
* const keyManager = new LocalKeyManager();
|
||
|
|
* const did = await DidDht.create({ keyManager });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the create operation.
|
||
|
|
* @param params.keyManager - Optionally specify a Key Management System (KMS) used to generate
|
||
|
|
* keys and sign data.
|
||
|
|
* @param params.options - Optional parameters that can be specified when creating a new DID.
|
||
|
|
* @returns A Promise resolving to a {@link BearerDid} object representing the new DID.
|
||
|
|
*/
|
||
|
|
static create() {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ keyManager = new import_crypto3.LocalKeyManager(), options = {} } = {}) {
|
||
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
||
|
|
if ((_a = options.verificationMethods) === null || _a === void 0 ? void 0 : _a.some((vm) => !(vm.algorithm in AlgorithmToKeyTypeMap))) {
|
||
|
|
throw new Error("One or more verification method algorithms are not supported");
|
||
|
|
}
|
||
|
|
const methodIds = (_b = options.verificationMethods) === null || _b === void 0 ? void 0 : _b.filter((vm) => "id" in vm).map((vm) => vm.id);
|
||
|
|
if (methodIds && methodIds.length !== new Set(methodIds).size) {
|
||
|
|
throw new Error("One or more verification method IDs are not unique");
|
||
|
|
}
|
||
|
|
if ((_c = options.services) === null || _c === void 0 ? void 0 : _c.some((s) => !s.id || !s.type || !s.serviceEndpoint)) {
|
||
|
|
throw new Error("One or more services are missing required properties");
|
||
|
|
}
|
||
|
|
const identityKeyUri = yield keyManager.generateKey({ algorithm: "Ed25519" });
|
||
|
|
const identityKey = yield keyManager.getPublicKey({ keyUri: identityKeyUri });
|
||
|
|
const didUri = yield DidDhtUtils.identityKeyToIdentifier({ identityKey });
|
||
|
|
const document = Object.assign(Object.assign({ id: didUri }, options.alsoKnownAs && { alsoKnownAs: options.alsoKnownAs }), options.controllers && { controller: options.controllers });
|
||
|
|
const verificationMethodsToAdd = [...(_d = options.verificationMethods) !== null && _d !== void 0 ? _d : []];
|
||
|
|
if (!(verificationMethodsToAdd === null || verificationMethodsToAdd === void 0 ? void 0 : verificationMethodsToAdd.some((vm) => {
|
||
|
|
var _a2;
|
||
|
|
return ((_a2 = vm.id) === null || _a2 === void 0 ? void 0 : _a2.split("#").pop()) === "0";
|
||
|
|
}))) {
|
||
|
|
verificationMethodsToAdd.unshift({
|
||
|
|
algorithm: "Ed25519",
|
||
|
|
id: "0",
|
||
|
|
purposes: ["authentication", "assertionMethod", "capabilityDelegation", "capabilityInvocation"]
|
||
|
|
});
|
||
|
|
}
|
||
|
|
for (const verificationMethod of verificationMethodsToAdd) {
|
||
|
|
const keyUri = verificationMethod.id && verificationMethod.id.split("#").pop() === "0" ? identityKeyUri : yield keyManager.generateKey({ algorithm: verificationMethod.algorithm });
|
||
|
|
const publicKey = yield keyManager.getPublicKey({ keyUri });
|
||
|
|
let methodId = (_f = (_e = verificationMethod.id) !== null && _e !== void 0 ? _e : publicKey.kid) !== null && _f !== void 0 ? _f : yield (0, import_crypto3.computeJwkThumbprint)({ jwk: publicKey });
|
||
|
|
methodId = `${didUri}#${extractDidFragment(methodId)}`;
|
||
|
|
(_g = document.verificationMethod) !== null && _g !== void 0 ? _g : document.verificationMethod = [];
|
||
|
|
document.verificationMethod.push({
|
||
|
|
id: methodId,
|
||
|
|
type: "JsonWebKey",
|
||
|
|
controller: (_h = verificationMethod.controller) !== null && _h !== void 0 ? _h : didUri,
|
||
|
|
publicKeyJwk: publicKey
|
||
|
|
});
|
||
|
|
for (const purpose of (_j = verificationMethod.purposes) !== null && _j !== void 0 ? _j : []) {
|
||
|
|
if (!document[purpose])
|
||
|
|
document[purpose] = [];
|
||
|
|
document[purpose].push(methodId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
(_k = options.services) === null || _k === void 0 ? void 0 : _k.forEach((service) => {
|
||
|
|
var _a2;
|
||
|
|
(_a2 = document.service) !== null && _a2 !== void 0 ? _a2 : document.service = [];
|
||
|
|
service.id = `${didUri}#${service.id.split("#").pop()}`;
|
||
|
|
document.service.push(service);
|
||
|
|
});
|
||
|
|
const did = new BearerDid({
|
||
|
|
uri: didUri,
|
||
|
|
document,
|
||
|
|
metadata: Object.assign({ published: false }, options.types && { types: options.types }),
|
||
|
|
keyManager
|
||
|
|
});
|
||
|
|
if ((_l = options.publish) !== null && _l !== void 0 ? _l : true) {
|
||
|
|
const registrationResult = yield _DidDht.publish({ did, gatewayUri: options.gatewayUri });
|
||
|
|
did.metadata = registrationResult.didDocumentMetadata;
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Instantiates a {@link BearerDid} object for the DID DHT method from a given {@link PortableDid}.
|
||
|
|
*
|
||
|
|
* This method allows for the creation of a `BearerDid` object using a previously created DID's
|
||
|
|
* key material, DID document, and metadata.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Export an existing BearerDid to PortableDid format.
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // Reconstruct a BearerDid object from the PortableDid.
|
||
|
|
* const did = await DidDht.import({ portableDid });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the import operation.
|
||
|
|
* @param params.portableDid - The PortableDid object to import.
|
||
|
|
* @param params.keyManager - Optionally specify an external Key Management System (KMS) used to
|
||
|
|
* generate keys and sign data. If not given, a new
|
||
|
|
* {@link LocalKeyManager} instance will be created and
|
||
|
|
* used.
|
||
|
|
* @returns A Promise resolving to a `BearerDid` object representing the DID formed from the
|
||
|
|
* provided PortableDid.
|
||
|
|
* @throws An error if the PortableDid document does not contain any verification methods, lacks
|
||
|
|
* an Identity Key, or the keys for any verification method are missing in the key
|
||
|
|
* manager.
|
||
|
|
*/
|
||
|
|
static import(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ portableDid, keyManager = new import_crypto3.LocalKeyManager() }) {
|
||
|
|
var _b;
|
||
|
|
const parsedDid = Did.parse(portableDid.uri);
|
||
|
|
if ((parsedDid === null || parsedDid === void 0 ? void 0 : parsedDid.method) !== _DidDht.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported`);
|
||
|
|
}
|
||
|
|
const did = yield BearerDid.import({ portableDid, keyManager });
|
||
|
|
if (!((_b = did.document.verificationMethod) === null || _b === void 0 ? void 0 : _b.some((vm) => {
|
||
|
|
var _a2;
|
||
|
|
return ((_a2 = vm.id) === null || _a2 === void 0 ? void 0 : _a2.split("#").pop()) === "0";
|
||
|
|
}))) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocument, `DID document must contain an Identity Key`);
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Given the W3C DID Document of a `did:dht` DID, return the verification method that will be used
|
||
|
|
* for signing messages and credentials. If given, the `methodId` parameter is used to select the
|
||
|
|
* verification method. If not given, the Identity Key's verification method with an ID fragment
|
||
|
|
* of '#0' is used.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `getSigningMethod` operation.
|
||
|
|
* @param params.didDocument - DID Document to get the verification method from.
|
||
|
|
* @param params.methodId - ID of the verification method to use for signing.
|
||
|
|
* @returns Verification method to use for signing.
|
||
|
|
*/
|
||
|
|
static getSigningMethod(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ didDocument, methodId = "#0" }) {
|
||
|
|
var _b;
|
||
|
|
const parsedDid = Did.parse(didDocument.id);
|
||
|
|
if (parsedDid && parsedDid.method !== this.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
const verificationMethod = (_b = didDocument.verificationMethod) === null || _b === void 0 ? void 0 : _b.find((vm) => {
|
||
|
|
var _a2, _b2;
|
||
|
|
return extractDidFragment(vm.id) === ((_a2 = extractDidFragment(methodId)) !== null && _a2 !== void 0 ? _a2 : extractDidFragment((_b2 = didDocument.assertionMethod) === null || _b2 === void 0 ? void 0 : _b2[0]));
|
||
|
|
});
|
||
|
|
if (!(verificationMethod && verificationMethod.publicKeyJwk)) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "A verification method intended for signing could not be determined from the DID Document");
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Publishes a DID to the DHT, making it publicly discoverable and resolvable.
|
||
|
|
*
|
||
|
|
* This method handles the publication of a DID Document associated with a `did:dht` DID to the
|
||
|
|
* Mainline DHT network. The publication process involves storing the DID Document in Mainline DHT
|
||
|
|
* via a Pkarr relay server.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* - This method is typically invoked automatically during the creation of a new DID unless the
|
||
|
|
* `publish` option is set to `false`.
|
||
|
|
* - For existing, unpublished DIDs, it can be used to publish the DID Document to Mainline DHT.
|
||
|
|
* - The method relies on the specified Pkarr relay server to interface with the DHT network.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Generate a new DID and keys but explicitly disable publishing.
|
||
|
|
* const did = await DidDht.create({ options: { publish: false } });
|
||
|
|
* // Publish the DID to the DHT.
|
||
|
|
* const registrationResult = await DidDht.publish({ did });
|
||
|
|
* // `registrationResult.didDocumentMetadata.published` is true if the DID was successfully published.
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `publish` operation.
|
||
|
|
* @param params.did - The `BearerDid` object representing the DID to be published.
|
||
|
|
* @param params.gatewayUri - Optional. The URI of a server involved in executing DID method
|
||
|
|
* operations. In the context of publishing, the endpoint is expected
|
||
|
|
* to be a DID DHT Gateway or Pkarr Relay. If not specified, a default
|
||
|
|
* gateway node is used.
|
||
|
|
* @returns A promise that resolves to a {@link DidRegistrationResult} object that contains
|
||
|
|
* the result of registering the DID with a DID DHT Gateway or Pkarr relay.
|
||
|
|
*/
|
||
|
|
static publish(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ did, gatewayUri = DEFAULT_GATEWAY_URI }) {
|
||
|
|
const registrationResult = yield DidDhtDocument.put({ did, gatewayUri });
|
||
|
|
return registrationResult;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Resolves a `did:dht` identifier to its corresponding DID document.
|
||
|
|
*
|
||
|
|
* This method performs the resolution of a `did:dht` DID, retrieving its DID Document from the
|
||
|
|
* Mainline DHT network. The process involves querying the DHT network via a Pkarr relay server to
|
||
|
|
* retrieve the DID Document that corresponds to the given DID identifier.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* - If a `gatewayUri` option is not specified, a default Pkarr relay is used to access the DHT
|
||
|
|
* network.
|
||
|
|
* - It decodes the DID identifier and retrieves the associated DID Document and metadata.
|
||
|
|
* - In case of resolution failure, appropriate error information is returned.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const resolutionResult = await DidDht.resolve('did:dht:example');
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param didUri - The DID to be resolved.
|
||
|
|
* @param options - Optional parameters for resolving the DID. Unused by this DID method.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of
|
||
|
|
* the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(didUri_1) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* (didUri, options = {}) {
|
||
|
|
var _a;
|
||
|
|
const gatewayUri = (_a = options === null || options === void 0 ? void 0 : options.gatewayUri) !== null && _a !== void 0 ? _a : DEFAULT_GATEWAY_URI;
|
||
|
|
try {
|
||
|
|
yield DidDhtUtils.identifierToIdentityKey({ didUri });
|
||
|
|
const { didDocument, didDocumentMetadata } = yield DidDhtDocument.get({ didUri, gatewayUri });
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), {
|
||
|
|
didDocument,
|
||
|
|
didDocumentMetadata
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
if (!(error instanceof DidError))
|
||
|
|
throw new Error(error);
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: Object.assign({ error: error.code }, error.message && { errorMessage: error.message }) });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidDht.methodName = "dht";
|
||
|
|
var DidDhtDocument = class _DidDhtDocument {
|
||
|
|
/**
|
||
|
|
* Retrieves a DID document and its metadata from the DHT network.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the get operation.
|
||
|
|
* @param params.didUri - The DID URI containing the Identity Key.
|
||
|
|
* @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object containing the DID
|
||
|
|
* document and its metadata.
|
||
|
|
*/
|
||
|
|
static get(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ didUri, gatewayUri }) {
|
||
|
|
const publicKeyBytes = DidDhtUtils.identifierToIdentityKeyBytes({ didUri });
|
||
|
|
const bep44Message = yield _DidDhtDocument.pkarrGet({ gatewayUri, publicKeyBytes });
|
||
|
|
const dnsPacket = yield DidDhtUtils.parseBep44GetMessage({ bep44Message });
|
||
|
|
const resolutionResult = yield _DidDhtDocument.fromDnsPacket({ didUri, dnsPacket });
|
||
|
|
resolutionResult.didDocumentMetadata.versionId = bep44Message.seq.toString();
|
||
|
|
return resolutionResult;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Publishes a DID document to the DHT network.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when publishing the DID document to the DHT network.
|
||
|
|
* @param params.did - The DID object whose DID document will be published.
|
||
|
|
* @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
|
||
|
|
* @returns A promise that resolves to a {@link DidRegistrationResult} object that contains
|
||
|
|
* the result of registering the DID with a DID DHT Gateway or Pkarr relay.
|
||
|
|
*/
|
||
|
|
static put(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ did, gatewayUri }) {
|
||
|
|
const dnsPacket = yield _DidDhtDocument.toDnsPacket({
|
||
|
|
didDocument: did.document,
|
||
|
|
didMetadata: did.metadata,
|
||
|
|
authoritativeGatewayUris: [gatewayUri]
|
||
|
|
});
|
||
|
|
const bep44Message = yield DidDhtUtils.createBep44PutMessage({
|
||
|
|
dnsPacket,
|
||
|
|
publicKeyBytes: DidDhtUtils.identifierToIdentityKeyBytes({ didUri: did.uri }),
|
||
|
|
signer: yield did.getSigner({ methodId: "0" })
|
||
|
|
});
|
||
|
|
const putResult = yield _DidDhtDocument.pkarrPut({ gatewayUri, bep44Message });
|
||
|
|
return {
|
||
|
|
didDocument: did.document,
|
||
|
|
didDocumentMetadata: Object.assign(Object.assign({}, did.metadata), { published: putResult, versionId: bep44Message.seq.toString() }),
|
||
|
|
didRegistrationMetadata: {}
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Retrieves a signed BEP44 message from a DID DHT Gateway or Pkarr Relay server.
|
||
|
|
*
|
||
|
|
* @see {@link https://github.com/Nuhvi/pkarr/blob/main/design/relays.md | Pkarr Relay design}
|
||
|
|
*
|
||
|
|
* @param params
|
||
|
|
* @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
|
||
|
|
* @param params.publicKeyBytes - The public key bytes of the Identity Key, z-base-32 encoded.
|
||
|
|
* @returns A promise resolving to a BEP44 message containing the signed DNS packet.
|
||
|
|
*/
|
||
|
|
static pkarrGet(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ gatewayUri, publicKeyBytes }) {
|
||
|
|
const identifier = import_common2.Convert.uint8Array(publicKeyBytes).toBase32Z();
|
||
|
|
const url = new URL(identifier, gatewayUri).href;
|
||
|
|
let response;
|
||
|
|
try {
|
||
|
|
response = yield fetch(url, { method: "GET" });
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new DidError(DidErrorCode.NotFound, `Pkarr record not found for: ${identifier}`);
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
if (error instanceof DidError)
|
||
|
|
throw error;
|
||
|
|
throw new DidError(DidErrorCode.InternalError, `Failed to fetch Pkarr record: ${error.message}`);
|
||
|
|
}
|
||
|
|
const messageBytes = yield response.arrayBuffer();
|
||
|
|
if (!messageBytes) {
|
||
|
|
throw new DidError(DidErrorCode.NotFound, `Pkarr record not found for: ${identifier}`);
|
||
|
|
}
|
||
|
|
if (messageBytes.byteLength < 72) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocumentLength, `Pkarr response must be at least 72 bytes but got: ${messageBytes.byteLength}`);
|
||
|
|
}
|
||
|
|
if (messageBytes.byteLength > 1072) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocumentLength, `Pkarr response exceeds 1000 byte limit: ${messageBytes.byteLength}`);
|
||
|
|
}
|
||
|
|
const bep44Message = {
|
||
|
|
k: publicKeyBytes,
|
||
|
|
seq: Number(new DataView(messageBytes).getBigUint64(64)),
|
||
|
|
sig: new Uint8Array(messageBytes, 0, 64),
|
||
|
|
v: new Uint8Array(messageBytes, 72)
|
||
|
|
};
|
||
|
|
return bep44Message;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Publishes a signed BEP44 message to a DID DHT Gateway or Pkarr Relay server.
|
||
|
|
*
|
||
|
|
* @see {@link https://github.com/Nuhvi/pkarr/blob/main/design/relays.md | Pkarr Relay design}
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when publishing a signed BEP44 message to a Pkarr relay server.
|
||
|
|
* @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
|
||
|
|
* @param params.bep44Message - The BEP44 message to be published, containing the signed DNS packet.
|
||
|
|
* @returns A promise resolving to `true` if the message was successfully published, otherwise `false`.
|
||
|
|
*/
|
||
|
|
static pkarrPut(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ gatewayUri, bep44Message }) {
|
||
|
|
const identifier = import_common2.Convert.uint8Array(bep44Message.k).toBase32Z();
|
||
|
|
const url = new URL(identifier, gatewayUri).href;
|
||
|
|
const body = new Uint8Array(bep44Message.v.length + 72);
|
||
|
|
body.set(bep44Message.sig, 0);
|
||
|
|
new DataView(body.buffer).setBigUint64(bep44Message.sig.length, BigInt(bep44Message.seq));
|
||
|
|
body.set(bep44Message.v, bep44Message.sig.length + 8);
|
||
|
|
let response;
|
||
|
|
try {
|
||
|
|
response = yield fetch(url, {
|
||
|
|
method: "PUT",
|
||
|
|
headers: { "Content-Type": "application/octet-stream" },
|
||
|
|
body
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, `Failed to put Pkarr record for identifier ${identifier}: ${error.message}`);
|
||
|
|
}
|
||
|
|
return response.ok;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a DNS packet to a DID document according to the DID DHT specification.
|
||
|
|
*
|
||
|
|
* @see {@link https://did-dht.com/#dids-as-dns-records | DID DHT Specification, § DIDs as DNS Records}
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when converting a DNS packet to a DID document.
|
||
|
|
* @param params.didUri - The DID URI of the DID document.
|
||
|
|
* @param params.dnsPacket - The DNS packet to convert to a DID document.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object containing the DID
|
||
|
|
* document and its metadata.
|
||
|
|
*/
|
||
|
|
static fromDnsPacket(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ didUri, dnsPacket }) {
|
||
|
|
var _b, _c, _d;
|
||
|
|
const didDocument = { id: didUri };
|
||
|
|
const didDocumentMetadata = {
|
||
|
|
published: true
|
||
|
|
};
|
||
|
|
const idLookup = /* @__PURE__ */ new Map();
|
||
|
|
for (const answer of (_b = dnsPacket === null || dnsPacket === void 0 ? void 0 : dnsPacket.answers) !== null && _b !== void 0 ? _b : []) {
|
||
|
|
if (answer.type !== "TXT")
|
||
|
|
continue;
|
||
|
|
const dnsRecordId = answer.name.split(".")[0].substring(1);
|
||
|
|
switch (true) {
|
||
|
|
case dnsRecordId.startsWith("aka"): {
|
||
|
|
const data = DidDhtUtils.parseTxtDataToString(answer.data);
|
||
|
|
didDocument.alsoKnownAs = data.split(VALUE_SEPARATOR);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case dnsRecordId.startsWith("cnt"): {
|
||
|
|
const data = DidDhtUtils.parseTxtDataToString(answer.data);
|
||
|
|
didDocument.controller = data.includes(VALUE_SEPARATOR) ? data.split(VALUE_SEPARATOR) : data;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case dnsRecordId.startsWith("k"): {
|
||
|
|
const { id, t, k, c, a: parsedAlg } = DidDhtUtils.parseTxtDataToObject(answer.data);
|
||
|
|
const publicKeyBytes = import_common2.Convert.base64Url(k).toUint8Array();
|
||
|
|
const namedCurve = DidDhtRegisteredKeyType[Number(t)];
|
||
|
|
let publicKey = yield DidDhtUtils.keyConverter(namedCurve).bytesToPublicKey({ publicKeyBytes });
|
||
|
|
publicKey.alg = parsedAlg || KeyTypeToDefaultAlgorithmMap[Number(t)];
|
||
|
|
const vmId = dnsRecordId === "k0" ? "0" : id !== void 0 ? id : yield (0, import_crypto3.computeJwkThumbprint)({ jwk: publicKey });
|
||
|
|
(_c = didDocument.verificationMethod) !== null && _c !== void 0 ? _c : didDocument.verificationMethod = [];
|
||
|
|
const methodId = `${didUri}#${vmId}`;
|
||
|
|
didDocument.verificationMethod.push({
|
||
|
|
id: methodId,
|
||
|
|
type: "JsonWebKey",
|
||
|
|
controller: c !== null && c !== void 0 ? c : didUri,
|
||
|
|
publicKeyJwk: publicKey
|
||
|
|
});
|
||
|
|
idLookup.set(dnsRecordId, methodId);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case dnsRecordId.startsWith("s"): {
|
||
|
|
const _e = DidDhtUtils.parseTxtDataToObject(answer.data), { id, t, se } = _e, customProperties = __rest(_e, ["id", "t", "se"]);
|
||
|
|
const serviceEndpoint = se.includes(VALUE_SEPARATOR) ? se.split(VALUE_SEPARATOR) : [se];
|
||
|
|
const serviceProperties = Object.fromEntries(Object.entries(customProperties).map(([k, v]) => [k, v.includes(VALUE_SEPARATOR) ? v.split(VALUE_SEPARATOR) : v]));
|
||
|
|
(_d = didDocument.service) !== null && _d !== void 0 ? _d : didDocument.service = [];
|
||
|
|
didDocument.service.push(Object.assign(Object.assign({}, serviceProperties), { id: `${didUri}#${id}`, type: t, serviceEndpoint }));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case dnsRecordId.startsWith("typ"): {
|
||
|
|
const { id: types } = DidDhtUtils.parseTxtDataToObject(answer.data);
|
||
|
|
didDocumentMetadata.types = types.split(VALUE_SEPARATOR).map((typeInteger) => Number(typeInteger));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case dnsRecordId.startsWith("did"): {
|
||
|
|
const recordIdsToMethodIds = (data) => data.split(VALUE_SEPARATOR).map((dnsRecordId2) => idLookup.get(dnsRecordId2)).filter((id) => typeof id === "string");
|
||
|
|
const { auth, asm, del, inv: inv2, agm } = DidDhtUtils.parseTxtDataToObject(answer.data);
|
||
|
|
if (auth)
|
||
|
|
didDocument.authentication = recordIdsToMethodIds(auth);
|
||
|
|
if (asm)
|
||
|
|
didDocument.assertionMethod = recordIdsToMethodIds(asm);
|
||
|
|
if (del)
|
||
|
|
didDocument.capabilityDelegation = recordIdsToMethodIds(del);
|
||
|
|
if (inv2)
|
||
|
|
didDocument.capabilityInvocation = recordIdsToMethodIds(inv2);
|
||
|
|
if (agm)
|
||
|
|
didDocument.keyAgreement = recordIdsToMethodIds(agm);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return { didDocument, didDocumentMetadata, didResolutionMetadata: {} };
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a DID document to a DNS packet according to the DID DHT specification.
|
||
|
|
*
|
||
|
|
* @see {@link https://did-dht.com/#dids-as-dns-records | DID DHT Specification, § DIDs as DNS Records}
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when converting a DID document to a DNS packet.
|
||
|
|
* @param params.didDocument - The DID document to convert to a DNS packet.
|
||
|
|
* @param params.didMetadata - The DID metadata to include in the DNS packet.
|
||
|
|
* @param params.authoritativeGatewayUris - The URIs of the Authoritative Gateways to generate NS records from.
|
||
|
|
* @param params.previousDidProof - The signature proof that this DID is linked to the given previous DID.
|
||
|
|
* @returns A promise that resolves to a DNS packet.
|
||
|
|
*/
|
||
|
|
static toDnsPacket(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ didDocument, didMetadata, authoritativeGatewayUris, previousDidProof }) {
|
||
|
|
var _b, _c, _d, _e, _f;
|
||
|
|
const txtRecords = [];
|
||
|
|
const nsRecords = [];
|
||
|
|
const idLookup = /* @__PURE__ */ new Map();
|
||
|
|
const serviceIds = [];
|
||
|
|
const verificationMethodIds = [];
|
||
|
|
if (previousDidProof !== void 0) {
|
||
|
|
const { signature, previousDid } = previousDidProof;
|
||
|
|
yield DidDhtUtils.validatePreviousDidProof({
|
||
|
|
newDid: didDocument.id,
|
||
|
|
previousDidProof
|
||
|
|
});
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: "_prv._did.",
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: `id=${previousDid};s=${signature}`
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (didDocument.alsoKnownAs) {
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: "_aka._did.",
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: didDocument.alsoKnownAs.join(VALUE_SEPARATOR)
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (didDocument.controller) {
|
||
|
|
const controller = Array.isArray(didDocument.controller) ? didDocument.controller.join(VALUE_SEPARATOR) : didDocument.controller;
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: "_cnt._did.",
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: controller
|
||
|
|
});
|
||
|
|
}
|
||
|
|
for (const [index, verificationMethod] of (_c = (_b = didDocument.verificationMethod) === null || _b === void 0 ? void 0 : _b.entries()) !== null && _c !== void 0 ? _c : []) {
|
||
|
|
const dnsRecordId = `k${index}`;
|
||
|
|
verificationMethodIds.push(dnsRecordId);
|
||
|
|
let methodId = verificationMethod.id.split("#").pop();
|
||
|
|
idLookup.set(methodId, dnsRecordId);
|
||
|
|
const publicKey = verificationMethod.publicKeyJwk;
|
||
|
|
if (!((publicKey === null || publicKey === void 0 ? void 0 : publicKey.crv) && publicKey.crv in AlgorithmToKeyTypeMap)) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Verification method '${verificationMethod.id}' contains an unsupported key type: ${(_d = publicKey === null || publicKey === void 0 ? void 0 : publicKey.crv) !== null && _d !== void 0 ? _d : "undefined"}`);
|
||
|
|
}
|
||
|
|
const keyType = DidDhtRegisteredKeyType[publicKey.crv];
|
||
|
|
const publicKeyBytes = yield DidDhtUtils.keyConverter(publicKey.crv).publicKeyToBytes({ publicKey });
|
||
|
|
const publicKeyBase64Url = import_common2.Convert.uint8Array(publicKeyBytes).toBase64Url();
|
||
|
|
const txtData = [`t=${keyType}`, `k=${publicKeyBase64Url}`];
|
||
|
|
if (methodId !== "0" && (yield (0, import_crypto3.computeJwkThumbprint)({ jwk: publicKey })) !== methodId) {
|
||
|
|
txtData.unshift(`id=${methodId}`);
|
||
|
|
}
|
||
|
|
if (publicKey.alg !== KeyTypeToDefaultAlgorithmMap[keyType]) {
|
||
|
|
txtData.push(`a=${publicKey.alg}`);
|
||
|
|
}
|
||
|
|
if (verificationMethod.controller !== didDocument.id)
|
||
|
|
txtData.push(`c=${verificationMethod.controller}`);
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: `_${dnsRecordId}._did.`,
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: txtData.join(PROPERTY_SEPARATOR)
|
||
|
|
});
|
||
|
|
}
|
||
|
|
(_e = didDocument.service) === null || _e === void 0 ? void 0 : _e.forEach((service, index) => {
|
||
|
|
const dnsRecordId = `s${index}`;
|
||
|
|
serviceIds.push(dnsRecordId);
|
||
|
|
let { id, type: t, serviceEndpoint: se } = service, customProperties = __rest(service, ["id", "type", "serviceEndpoint"]);
|
||
|
|
id = extractDidFragment(id);
|
||
|
|
se = Array.isArray(se) ? se.join(",") : se;
|
||
|
|
const txtData = Object.entries(Object.assign({ id, t, se }, customProperties)).map(([key, value]) => `${key}=${value}`);
|
||
|
|
const txtDataString = txtData.join(PROPERTY_SEPARATOR);
|
||
|
|
const data = DidDhtUtils.chunkDataIfNeeded(txtDataString);
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: `_${dnsRecordId}._did.`,
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data
|
||
|
|
});
|
||
|
|
});
|
||
|
|
const rootRecord = [`v=${DID_DHT_SPECIFICATION_VERSION}`];
|
||
|
|
if (verificationMethodIds.length) {
|
||
|
|
rootRecord.push(`vm=${verificationMethodIds.join(VALUE_SEPARATOR)}`);
|
||
|
|
}
|
||
|
|
Object.keys(DidVerificationRelationship).forEach((relationship) => {
|
||
|
|
var _a2;
|
||
|
|
const dnsRecordIds = (_a2 = didDocument[relationship]) === null || _a2 === void 0 ? void 0 : _a2.map((id) => idLookup.get(id.split("#").pop()));
|
||
|
|
if (dnsRecordIds) {
|
||
|
|
const recordName = DidDhtVerificationRelationship[relationship];
|
||
|
|
rootRecord.push(`${recordName}=${dnsRecordIds.join(VALUE_SEPARATOR)}`);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
if (serviceIds.length) {
|
||
|
|
rootRecord.push(`svc=${serviceIds.join(VALUE_SEPARATOR)}`);
|
||
|
|
}
|
||
|
|
if ((_f = didMetadata.types) === null || _f === void 0 ? void 0 : _f.length) {
|
||
|
|
const types = didMetadata.types;
|
||
|
|
const typeIntegers = types.map((type) => typeof type === "string" ? DidDhtRegisteredDidType[type] : type);
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: "_typ._did.",
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: `id=${typeIntegers.join(VALUE_SEPARATOR)}`
|
||
|
|
});
|
||
|
|
}
|
||
|
|
txtRecords.push({
|
||
|
|
type: "TXT",
|
||
|
|
name: "_did." + _DidDhtDocument.getUniqueDidSuffix(didDocument.id) + ".",
|
||
|
|
// name of a Root Record MUST end in `<ID>.`
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: rootRecord.join(PROPERTY_SEPARATOR)
|
||
|
|
});
|
||
|
|
for (const gatewayUri of authoritativeGatewayUris || []) {
|
||
|
|
nsRecords.push({
|
||
|
|
type: "NS",
|
||
|
|
name: "_did." + _DidDhtDocument.getUniqueDidSuffix(didDocument.id) + ".",
|
||
|
|
// name of an NS record a authoritative gateway MUST end in `<ID>.`
|
||
|
|
ttl: DNS_RECORD_TTL,
|
||
|
|
data: gatewayUri + "."
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const dnsPacket = {
|
||
|
|
id: 0,
|
||
|
|
type: "response",
|
||
|
|
flags: import_dns_packet.AUTHORITATIVE_ANSWER,
|
||
|
|
answers: [...txtRecords, ...nsRecords]
|
||
|
|
};
|
||
|
|
return dnsPacket;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Gets the unique portion of the DID identifier after the last `:` character.
|
||
|
|
* e.g. `did:dht:example` -> `example`
|
||
|
|
*
|
||
|
|
* @param did - The DID to extract the unique suffix from.
|
||
|
|
*/
|
||
|
|
static getUniqueDidSuffix(did) {
|
||
|
|
return did.split(":")[2];
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var DidDhtUtils = class _DidDhtUtils {
|
||
|
|
/**
|
||
|
|
* Creates a BEP44 put message, which is used to publish a DID document to the DHT network.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when creating the BEP44 put message
|
||
|
|
* @param params.dnsPacket - The DNS packet to encode in the BEP44 message.
|
||
|
|
* @param params.publicKeyBytes - The public key bytes of the Identity Key.
|
||
|
|
* @param params.signer - Signer that can sign and verify data using the Identity Key.
|
||
|
|
* @returns A promise that resolves to a BEP44 put message.
|
||
|
|
*/
|
||
|
|
static createBep44PutMessage(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ dnsPacket, publicKeyBytes, signer }) {
|
||
|
|
const sequenceNumber = Math.ceil(Date.now() / 1e3);
|
||
|
|
const encodedDnsPacket = (0, import_dns_packet.encode)(dnsPacket);
|
||
|
|
const bencodedData = bencode_default.encode({ seq: sequenceNumber, v: encodedDnsPacket }).subarray(1, -1);
|
||
|
|
if (bencodedData.length > 1e3) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocumentLength, `DNS packet exceeds the 1000 byte maximum size: ${bencodedData.length} bytes`);
|
||
|
|
}
|
||
|
|
const signature = yield signer.sign({ data: bencodedData });
|
||
|
|
return { k: publicKeyBytes, seq: sequenceNumber, sig: signature, v: encodedDnsPacket };
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a DID URI to a JSON Web Key (JWK) representing the Identity Key.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use for the conversion.
|
||
|
|
* @param params.didUri - The DID URI containing the Identity Key.
|
||
|
|
* @returns A promise that resolves to a JWK representing the Identity Key.
|
||
|
|
*/
|
||
|
|
static identifierToIdentityKey(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ didUri }) {
|
||
|
|
let identityKeyBytes = _DidDhtUtils.identifierToIdentityKeyBytes({ didUri });
|
||
|
|
const identityKey = yield import_crypto3.Ed25519.bytesToPublicKey({ publicKeyBytes: identityKeyBytes });
|
||
|
|
return identityKey;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a DID URI to the byte array representation of the Identity Key.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use for the conversion.
|
||
|
|
* @param params.didUri - The DID URI containing the Identity Key.
|
||
|
|
* @returns A byte array representation of the Identity Key.
|
||
|
|
*/
|
||
|
|
static identifierToIdentityKeyBytes({ didUri }) {
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
if (!parsedDid) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDid, `Invalid DID URI: ${didUri}`);
|
||
|
|
}
|
||
|
|
if (parsedDid.method !== DidDht.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
let identityKeyBytes;
|
||
|
|
try {
|
||
|
|
identityKeyBytes = import_common2.Convert.base32Z(parsedDid.id).toUint8Array();
|
||
|
|
} catch (_a) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKey, `Failed to decode method-specific identifier`);
|
||
|
|
}
|
||
|
|
if (identityKeyBytes.length !== 32) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyLength, `Invalid public key length: ${identityKeyBytes.length}`);
|
||
|
|
}
|
||
|
|
return identityKeyBytes;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Encodes a DID DHT Identity Key into a DID identifier.
|
||
|
|
*
|
||
|
|
* This method first z-base-32 encodes the Identity Key. The resulting string is prefixed with
|
||
|
|
* `did:dht:` to form the DID identifier.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use for the conversion.
|
||
|
|
* @param params.identityKey The Identity Key from which the DID identifier is computed.
|
||
|
|
* @returns A promise that resolves to a string containing the DID identifier.
|
||
|
|
*/
|
||
|
|
static identityKeyToIdentifier(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ identityKey }) {
|
||
|
|
const publicKeyBytes = yield import_crypto3.Ed25519.publicKeyToBytes({ publicKey: identityKey });
|
||
|
|
const identifier = import_common2.Convert.uint8Array(publicKeyBytes).toBase32Z();
|
||
|
|
return `did:${DidDht.methodName}:${identifier}`;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Returns the appropriate key converter for the specified cryptographic curve.
|
||
|
|
*
|
||
|
|
* @param curve - The cryptographic curve to use for the key conversion.
|
||
|
|
* @returns An `AsymmetricKeyConverter` for the specified curve.
|
||
|
|
*/
|
||
|
|
static keyConverter(curve) {
|
||
|
|
const converters = {
|
||
|
|
"Ed25519": import_crypto3.Ed25519,
|
||
|
|
"P-256": {
|
||
|
|
// Wrap the key converter which produces uncompressed public key bytes to produce compressed key bytes as required by the DID DHT spec.
|
||
|
|
// See https://did-dht.com/#representing-keys for more info.
|
||
|
|
publicKeyToBytes: (_a) => __awaiter4(this, [_a], void 0, function* ({ publicKey }) {
|
||
|
|
const publicKeyBytes = yield import_crypto3.Secp256r1.publicKeyToBytes({ publicKey });
|
||
|
|
const compressedPublicKey = yield import_crypto3.Secp256r1.compressPublicKey({ publicKeyBytes });
|
||
|
|
return compressedPublicKey;
|
||
|
|
}),
|
||
|
|
bytesToPublicKey: import_crypto3.Secp256r1.bytesToPublicKey,
|
||
|
|
privateKeyToBytes: import_crypto3.Secp256r1.privateKeyToBytes,
|
||
|
|
bytesToPrivateKey: import_crypto3.Secp256r1.bytesToPrivateKey
|
||
|
|
},
|
||
|
|
"secp256k1": {
|
||
|
|
// Wrap the key converter which produces uncompressed public key bytes to produce compressed key bytes as required by the DID DHT spec.
|
||
|
|
// See https://did-dht.com/#representing-keys for more info.
|
||
|
|
publicKeyToBytes: (_b) => __awaiter4(this, [_b], void 0, function* ({ publicKey }) {
|
||
|
|
const publicKeyBytes = yield import_crypto3.Secp256k1.publicKeyToBytes({ publicKey });
|
||
|
|
const compressedPublicKey = yield import_crypto3.Secp256k1.compressPublicKey({ publicKeyBytes });
|
||
|
|
return compressedPublicKey;
|
||
|
|
}),
|
||
|
|
bytesToPublicKey: import_crypto3.Secp256k1.bytesToPublicKey,
|
||
|
|
privateKeyToBytes: import_crypto3.Secp256k1.privateKeyToBytes,
|
||
|
|
bytesToPrivateKey: import_crypto3.Secp256k1.bytesToPrivateKey
|
||
|
|
},
|
||
|
|
X25519: import_crypto3.X25519
|
||
|
|
};
|
||
|
|
const converter = converters[curve];
|
||
|
|
if (!converter)
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);
|
||
|
|
return converter;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Parses and verifies a BEP44 Get message, converting it to a DNS packet.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to use when verifying and parsing the BEP44 Get response message.
|
||
|
|
* @param params.bep44Message - The BEP44 message to verify and parse.
|
||
|
|
* @returns A promise that resolves to a DNS packet.
|
||
|
|
*/
|
||
|
|
static parseBep44GetMessage(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ bep44Message }) {
|
||
|
|
const publicKey = yield import_crypto3.Ed25519.bytesToPublicKey({ publicKeyBytes: bep44Message.k });
|
||
|
|
const bencodedData = bencode_default.encode({ seq: bep44Message.seq, v: bep44Message.v }).subarray(1, -1);
|
||
|
|
const isValid = yield import_crypto3.Ed25519.verify({
|
||
|
|
key: publicKey,
|
||
|
|
signature: bep44Message.sig,
|
||
|
|
data: bencodedData
|
||
|
|
});
|
||
|
|
if (!isValid) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidSignature, `Invalid signature for DHT BEP44 message`);
|
||
|
|
}
|
||
|
|
return (0, import_dns_packet.decode)(bep44Message.v);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decodes and parses the data value of a DNS TXT record into a key-value object.
|
||
|
|
*
|
||
|
|
* @param txtData - The data value of a DNS TXT record.
|
||
|
|
* @returns An object containing the key/value pairs of the TXT record data.
|
||
|
|
*/
|
||
|
|
static parseTxtDataToObject(txtData) {
|
||
|
|
return this.parseTxtDataToString(txtData).split(PROPERTY_SEPARATOR).reduce((acc, pair) => {
|
||
|
|
const [key, value] = pair.split("=");
|
||
|
|
acc[key] = value;
|
||
|
|
return acc;
|
||
|
|
}, {});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decodes and parses the data value of a DNS TXT record into a string.
|
||
|
|
*
|
||
|
|
* @param txtData - The data value of a DNS TXT record.
|
||
|
|
* @returns A string representation of the TXT record data.
|
||
|
|
*/
|
||
|
|
static parseTxtDataToString(txtData) {
|
||
|
|
if (typeof txtData === "string") {
|
||
|
|
return txtData;
|
||
|
|
} else if (txtData instanceof Uint8Array) {
|
||
|
|
return import_common2.Convert.uint8Array(txtData).toString();
|
||
|
|
} else if (Array.isArray(txtData)) {
|
||
|
|
return txtData.map((item) => this.parseTxtDataToString(item)).join("");
|
||
|
|
} else {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "Pkarr returned DNS TXT record with invalid data type");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Validates the proof of previous DID given.
|
||
|
|
*
|
||
|
|
* @param params - The parameters to validate the previous DID proof.
|
||
|
|
* @param params.newDid - The new DID that the previous DID is linking to.
|
||
|
|
* @param params.previousDidProof - The proof of the previous DID, containing the previous DID and signature signed by the previous DID.
|
||
|
|
*/
|
||
|
|
static validatePreviousDidProof(_a) {
|
||
|
|
return __awaiter4(this, arguments, void 0, function* ({ newDid, previousDidProof }) {
|
||
|
|
const key = yield _DidDhtUtils.identifierToIdentityKey({ didUri: previousDidProof.previousDid });
|
||
|
|
const data = _DidDhtUtils.identifierToIdentityKeyBytes({ didUri: newDid });
|
||
|
|
const signature = import_common2.Convert.base64Url(previousDidProof.signature).toUint8Array();
|
||
|
|
const isValid = yield import_crypto3.Ed25519.verify({ key, data, signature });
|
||
|
|
if (!isValid) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPreviousDidProof, "The previous DID proof is invalid.");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Splits a string into chunks of length 255 if the string exceeds length 255.
|
||
|
|
* @param data - The string to split into chunks.
|
||
|
|
* @returns The original string if its length is less than or equal to 255, otherwise an array of chunked strings.
|
||
|
|
*/
|
||
|
|
static chunkDataIfNeeded(data) {
|
||
|
|
if (data.length <= 255) {
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
const chunks = [];
|
||
|
|
for (let i = 0; i < data.length; i += 255) {
|
||
|
|
chunks.push(data.slice(i, i + 255));
|
||
|
|
}
|
||
|
|
return chunks;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/ErrorCode.js
|
||
|
|
var ErrorCode_default = {
|
||
|
|
DeltaExceedsMaximumSize: "DeltaExceedsMaximumSize",
|
||
|
|
DidDocumentPublicKeyIdDuplicated: "DidDocumentPublicKeyIdDuplicated",
|
||
|
|
DidDocumentPublicKeyMissingOrIncorrectType: "DidDocumentPublicKeyMissingOrIncorrectType",
|
||
|
|
DidDocumentServiceIdDuplicated: "DidDocumentServiceIdDuplicated",
|
||
|
|
DidSuffixIncorrectLength: "DidSuffixIncorrectLength",
|
||
|
|
EncodedStringIncorrectEncoding: "EncodedStringIncorrectEncoding",
|
||
|
|
IdNotUsingBase64UrlCharacterSet: "IdNotUsingBase64UrlCharacterSet",
|
||
|
|
IdTooLong: "IdTooLong",
|
||
|
|
JwkEs256kMissingOrInvalidCrv: "JwkEs256kMissingOrInvalidCrv",
|
||
|
|
JwkEs256kMissingOrInvalidKty: "JwkEs256kMissingOrInvalidKty",
|
||
|
|
JwkEs256kHasIncorrectLengthOfX: "JwkEs256kHasIncorrectLengthOfX",
|
||
|
|
JwkEs256kHasIncorrectLengthOfY: "JwkEs256kHasIncorrectLengthOfY",
|
||
|
|
JwkEs256kHasIncorrectLengthOfD: "JwkEs256kHasIncorrectLengthOfD",
|
||
|
|
MultihashStringNotAMultihash: "MultihashStringNotAMultihash",
|
||
|
|
MultihashUnsupportedHashAlgorithm: "MultihashUnsupportedHashAlgorithm",
|
||
|
|
PublicKeyJwkEs256kHasUnexpectedProperty: "PublicKeyJwkEs256kHasUnexpectedProperty",
|
||
|
|
PublicKeyPurposeDuplicated: "PublicKeyPurposeDuplicated",
|
||
|
|
ServiceEndpointCannotBeAnArray: "ServiceEndpointCannotBeAnArray",
|
||
|
|
ServiceEndpointStringNotValidUri: "ServiceEndpointStringNotValidUri",
|
||
|
|
ServiceTypeTooLong: "ServiceTypeTooLong"
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/IonError.js
|
||
|
|
var IonError = class extends Error {
|
||
|
|
constructor(code, message) {
|
||
|
|
super(`${code}: ${message}`);
|
||
|
|
this.code = code;
|
||
|
|
Object.setPrototypeOf(this, new.target.prototype);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/bytes.js
|
||
|
|
var empty = new Uint8Array(0);
|
||
|
|
var coerce = (o) => {
|
||
|
|
if (o instanceof Uint8Array && o.constructor.name === "Uint8Array")
|
||
|
|
return o;
|
||
|
|
if (o instanceof ArrayBuffer)
|
||
|
|
return new Uint8Array(o);
|
||
|
|
if (ArrayBuffer.isView(o)) {
|
||
|
|
return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
|
||
|
|
}
|
||
|
|
throw new Error("Unknown type, must be binary type");
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/bases/base.js
|
||
|
|
var Encoder = class {
|
||
|
|
/**
|
||
|
|
* @param {Base} name
|
||
|
|
* @param {Prefix} prefix
|
||
|
|
* @param {(bytes:Uint8Array) => string} baseEncode
|
||
|
|
*/
|
||
|
|
constructor(name, prefix, baseEncode) {
|
||
|
|
this.name = name;
|
||
|
|
this.prefix = prefix;
|
||
|
|
this.baseEncode = baseEncode;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {Uint8Array} bytes
|
||
|
|
* @returns {API.Multibase<Prefix>}
|
||
|
|
*/
|
||
|
|
encode(bytes) {
|
||
|
|
if (bytes instanceof Uint8Array) {
|
||
|
|
return `${this.prefix}${this.baseEncode(bytes)}`;
|
||
|
|
} else {
|
||
|
|
throw Error("Unknown type, must be binary type");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var Decoder = class {
|
||
|
|
/**
|
||
|
|
* @param {Base} name
|
||
|
|
* @param {Prefix} prefix
|
||
|
|
* @param {(text:string) => Uint8Array} baseDecode
|
||
|
|
*/
|
||
|
|
constructor(name, prefix, baseDecode) {
|
||
|
|
this.name = name;
|
||
|
|
this.prefix = prefix;
|
||
|
|
if (prefix.codePointAt(0) === void 0) {
|
||
|
|
throw new Error("Invalid prefix character");
|
||
|
|
}
|
||
|
|
this.prefixCodePoint = /** @type {number} */
|
||
|
|
prefix.codePointAt(0);
|
||
|
|
this.baseDecode = baseDecode;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {string} text
|
||
|
|
*/
|
||
|
|
decode(text) {
|
||
|
|
if (typeof text === "string") {
|
||
|
|
if (text.codePointAt(0) !== this.prefixCodePoint) {
|
||
|
|
throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
|
||
|
|
}
|
||
|
|
return this.baseDecode(text.slice(this.prefix.length));
|
||
|
|
} else {
|
||
|
|
throw Error("Can only multibase decode strings");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @template {string} OtherPrefix
|
||
|
|
* @param {API.UnibaseDecoder<OtherPrefix>|ComposedDecoder<OtherPrefix>} decoder
|
||
|
|
* @returns {ComposedDecoder<Prefix|OtherPrefix>}
|
||
|
|
*/
|
||
|
|
or(decoder2) {
|
||
|
|
return or(this, decoder2);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var ComposedDecoder = class {
|
||
|
|
/**
|
||
|
|
* @param {Decoders<Prefix>} decoders
|
||
|
|
*/
|
||
|
|
constructor(decoders) {
|
||
|
|
this.decoders = decoders;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @template {string} OtherPrefix
|
||
|
|
* @param {API.UnibaseDecoder<OtherPrefix>|ComposedDecoder<OtherPrefix>} decoder
|
||
|
|
* @returns {ComposedDecoder<Prefix|OtherPrefix>}
|
||
|
|
*/
|
||
|
|
or(decoder2) {
|
||
|
|
return or(this, decoder2);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {string} input
|
||
|
|
* @returns {Uint8Array}
|
||
|
|
*/
|
||
|
|
decode(input) {
|
||
|
|
const prefix = (
|
||
|
|
/** @type {Prefix} */
|
||
|
|
input[0]
|
||
|
|
);
|
||
|
|
const decoder2 = this.decoders[prefix];
|
||
|
|
if (decoder2) {
|
||
|
|
return decoder2.decode(input);
|
||
|
|
} else {
|
||
|
|
throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var or = (left, right) => new ComposedDecoder(
|
||
|
|
/** @type {Decoders<L|R>} */
|
||
|
|
{
|
||
|
|
...left.decoders || { [
|
||
|
|
/** @type API.UnibaseDecoder<L> */
|
||
|
|
left.prefix
|
||
|
|
]: left },
|
||
|
|
...right.decoders || { [
|
||
|
|
/** @type API.UnibaseDecoder<R> */
|
||
|
|
right.prefix
|
||
|
|
]: right }
|
||
|
|
}
|
||
|
|
);
|
||
|
|
var Codec = class {
|
||
|
|
/**
|
||
|
|
* @param {Base} name
|
||
|
|
* @param {Prefix} prefix
|
||
|
|
* @param {(bytes:Uint8Array) => string} baseEncode
|
||
|
|
* @param {(text:string) => Uint8Array} baseDecode
|
||
|
|
*/
|
||
|
|
constructor(name, prefix, baseEncode, baseDecode) {
|
||
|
|
this.name = name;
|
||
|
|
this.prefix = prefix;
|
||
|
|
this.baseEncode = baseEncode;
|
||
|
|
this.baseDecode = baseDecode;
|
||
|
|
this.encoder = new Encoder(name, prefix, baseEncode);
|
||
|
|
this.decoder = new Decoder(name, prefix, baseDecode);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {Uint8Array} input
|
||
|
|
*/
|
||
|
|
encode(input) {
|
||
|
|
return this.encoder.encode(input);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {string} input
|
||
|
|
*/
|
||
|
|
decode(input) {
|
||
|
|
return this.decoder.decode(input);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var from = ({ name, prefix, encode: encode4, decode: decode6 }) => new Codec(name, prefix, encode4, decode6);
|
||
|
|
var decode2 = (string, alphabet2, bitsPerChar, name) => {
|
||
|
|
const codes = {};
|
||
|
|
for (let i = 0; i < alphabet2.length; ++i) {
|
||
|
|
codes[alphabet2[i]] = i;
|
||
|
|
}
|
||
|
|
let end = string.length;
|
||
|
|
while (string[end - 1] === "=") {
|
||
|
|
--end;
|
||
|
|
}
|
||
|
|
const out = new Uint8Array(end * bitsPerChar / 8 | 0);
|
||
|
|
let bits = 0;
|
||
|
|
let buffer = 0;
|
||
|
|
let written = 0;
|
||
|
|
for (let i = 0; i < end; ++i) {
|
||
|
|
const value = codes[string[i]];
|
||
|
|
if (value === void 0) {
|
||
|
|
throw new SyntaxError(`Non-${name} character`);
|
||
|
|
}
|
||
|
|
buffer = buffer << bitsPerChar | value;
|
||
|
|
bits += bitsPerChar;
|
||
|
|
if (bits >= 8) {
|
||
|
|
bits -= 8;
|
||
|
|
out[written++] = 255 & buffer >> bits;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (bits >= bitsPerChar || 255 & buffer << 8 - bits) {
|
||
|
|
throw new SyntaxError("Unexpected end of data");
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
};
|
||
|
|
var encode2 = (data, alphabet2, bitsPerChar) => {
|
||
|
|
const pad = alphabet2[alphabet2.length - 1] === "=";
|
||
|
|
const mask = (1 << bitsPerChar) - 1;
|
||
|
|
let out = "";
|
||
|
|
let bits = 0;
|
||
|
|
let buffer = 0;
|
||
|
|
for (let i = 0; i < data.length; ++i) {
|
||
|
|
buffer = buffer << 8 | data[i];
|
||
|
|
bits += 8;
|
||
|
|
while (bits > bitsPerChar) {
|
||
|
|
bits -= bitsPerChar;
|
||
|
|
out += alphabet2[mask & buffer >> bits];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (bits) {
|
||
|
|
out += alphabet2[mask & buffer << bitsPerChar - bits];
|
||
|
|
}
|
||
|
|
if (pad) {
|
||
|
|
while (out.length * bitsPerChar & 7) {
|
||
|
|
out += "=";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
};
|
||
|
|
var rfc4648 = ({ name, prefix, bitsPerChar, alphabet: alphabet2 }) => {
|
||
|
|
return from({
|
||
|
|
prefix,
|
||
|
|
name,
|
||
|
|
encode(input) {
|
||
|
|
return encode2(input, alphabet2, bitsPerChar);
|
||
|
|
},
|
||
|
|
decode(input) {
|
||
|
|
return decode2(input, alphabet2, bitsPerChar, name);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/bases/base64.js
|
||
|
|
var base64 = rfc4648({
|
||
|
|
prefix: "m",
|
||
|
|
name: "base64",
|
||
|
|
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
|
||
|
|
bitsPerChar: 6
|
||
|
|
});
|
||
|
|
var base64pad = rfc4648({
|
||
|
|
prefix: "M",
|
||
|
|
name: "base64pad",
|
||
|
|
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||
|
|
bitsPerChar: 6
|
||
|
|
});
|
||
|
|
var base64url = rfc4648({
|
||
|
|
prefix: "u",
|
||
|
|
name: "base64url",
|
||
|
|
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
|
||
|
|
bitsPerChar: 6
|
||
|
|
});
|
||
|
|
var base64urlpad = rfc4648({
|
||
|
|
prefix: "U",
|
||
|
|
name: "base64urlpad",
|
||
|
|
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
|
||
|
|
bitsPerChar: 6
|
||
|
|
});
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/Encoder.js
|
||
|
|
var Encoder2 = class _Encoder {
|
||
|
|
/**
|
||
|
|
* Encodes given bytes into a Base64URL string.
|
||
|
|
*/
|
||
|
|
static encode(content) {
|
||
|
|
const encodedContent = base64url.baseEncode(content);
|
||
|
|
return encodedContent;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decodes the given Base64URL string into bytes.
|
||
|
|
*/
|
||
|
|
static decodeAsBytes(encodedContent, inputContextForErrorLogging) {
|
||
|
|
if (!_Encoder.isBase64UrlString(encodedContent)) {
|
||
|
|
throw new IonError(ErrorCode_default.EncodedStringIncorrectEncoding, `Given ${inputContextForErrorLogging} must be base64url string.`);
|
||
|
|
}
|
||
|
|
return base64url.baseDecode(encodedContent);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decodes the given Base64URL string into the original string.
|
||
|
|
*/
|
||
|
|
static decodeAsString(encodedContent, inputContextForErrorLogging) {
|
||
|
|
const rawBytes = _Encoder.decodeAsBytes(encodedContent, inputContextForErrorLogging);
|
||
|
|
return _Encoder.bytesToString(rawBytes);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Tests if the given string is a Base64URL string.
|
||
|
|
*/
|
||
|
|
static isBase64UrlString(input) {
|
||
|
|
const isBase64UrlString = /^[A-Za-z0-9_-]+$/.test(input);
|
||
|
|
return isBase64UrlString;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts input string to bytes.
|
||
|
|
*/
|
||
|
|
static stringToBytes(input) {
|
||
|
|
const bytes = new TextEncoder().encode(input);
|
||
|
|
return bytes;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts bytes to string.
|
||
|
|
*/
|
||
|
|
static bytesToString(input) {
|
||
|
|
const output = new TextDecoder().decode(input);
|
||
|
|
return output;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/IonRequest.js
|
||
|
|
var URI = __toESM(require_uri_all(), 1);
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/enums/OperationKeyType.js
|
||
|
|
var OperationKeyType;
|
||
|
|
(function(OperationKeyType2) {
|
||
|
|
OperationKeyType2["Public"] = "public";
|
||
|
|
OperationKeyType2["Private"] = "private";
|
||
|
|
})(OperationKeyType || (OperationKeyType = {}));
|
||
|
|
var OperationKeyType_default = OperationKeyType;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/InputValidator.js
|
||
|
|
var InputValidator = class {
|
||
|
|
/**
|
||
|
|
* Validates the schema of a ES256K JWK key.
|
||
|
|
*/
|
||
|
|
static validateEs256kOperationKey(operationKeyJwk, operationKeyType) {
|
||
|
|
const allowedProperties = /* @__PURE__ */ new Set(["kty", "crv", "x", "y"]);
|
||
|
|
if (operationKeyType === OperationKeyType_default.Private) {
|
||
|
|
allowedProperties.add("d");
|
||
|
|
}
|
||
|
|
for (const property in operationKeyJwk) {
|
||
|
|
if (!allowedProperties.has(property)) {
|
||
|
|
throw new IonError(ErrorCode_default.PublicKeyJwkEs256kHasUnexpectedProperty, `SECP256K1 JWK key has unexpected property '${property}'.`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (operationKeyJwk.crv !== "secp256k1") {
|
||
|
|
throw new IonError(ErrorCode_default.JwkEs256kMissingOrInvalidCrv, `SECP256K1 JWK 'crv' property must be 'secp256k1' but got '${operationKeyJwk.crv}.'`);
|
||
|
|
}
|
||
|
|
if (operationKeyJwk.kty !== "EC") {
|
||
|
|
throw new IonError(ErrorCode_default.JwkEs256kMissingOrInvalidKty, `SECP256K1 JWK 'kty' property must be 'EC' but got '${operationKeyJwk.kty}.'`);
|
||
|
|
}
|
||
|
|
if (operationKeyJwk.x.length !== 43) {
|
||
|
|
throw new IonError(ErrorCode_default.JwkEs256kHasIncorrectLengthOfX, `SECP256K1 JWK 'x' property must be 43 bytes.`);
|
||
|
|
}
|
||
|
|
if (operationKeyJwk.y.length !== 43) {
|
||
|
|
throw new IonError(ErrorCode_default.JwkEs256kHasIncorrectLengthOfY, `SECP256K1 JWK 'y' property must be 43 bytes.`);
|
||
|
|
}
|
||
|
|
if (operationKeyType === OperationKeyType_default.Private && (operationKeyJwk.d === void 0 || operationKeyJwk.d.length !== 43)) {
|
||
|
|
throw new IonError(ErrorCode_default.JwkEs256kHasIncorrectLengthOfD, `SECP256K1 JWK 'd' property must be 43 bytes.`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Validates an `id` property (in `IonPublicKeyModel` and `IonServiceModel`).
|
||
|
|
*/
|
||
|
|
static validateId(id) {
|
||
|
|
const maxIdLength = 50;
|
||
|
|
if (id.length > maxIdLength) {
|
||
|
|
throw new IonError(ErrorCode_default.IdTooLong, `Key ID length ${id.length} exceed max allowed length of ${maxIdLength}.`);
|
||
|
|
}
|
||
|
|
if (!Encoder2.isBase64UrlString(id)) {
|
||
|
|
throw new IonError(ErrorCode_default.IdNotUsingBase64UrlCharacterSet, `Key ID '${id}' is not a Base64URL string.`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Validates the given public key purposes.
|
||
|
|
*/
|
||
|
|
static validatePublicKeyPurposes(purposes) {
|
||
|
|
if (purposes === void 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const processedPurposes = /* @__PURE__ */ new Set();
|
||
|
|
for (const purpose of purposes) {
|
||
|
|
if (processedPurposes.has(purpose)) {
|
||
|
|
throw new IonError(ErrorCode_default.PublicKeyPurposeDuplicated, `Public key purpose '${purpose}' already specified.`);
|
||
|
|
}
|
||
|
|
processedPurposes.add(purpose);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/IonSdkConfig.js
|
||
|
|
var IonSdkConfig = class {
|
||
|
|
};
|
||
|
|
IonSdkConfig.hashAlgorithmInMultihashCode = 18;
|
||
|
|
IonSdkConfig.maxCanonicalizedDeltaSizeInBytes = 1e3;
|
||
|
|
var IonSdkConfig_default = IonSdkConfig;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/JsonCanonicalizer.js
|
||
|
|
var canonicalize = __toESM(require_canonicalize(), 1);
|
||
|
|
var JsonCanonicalizer = class _JsonCanonicalizer {
|
||
|
|
/**
|
||
|
|
* Canonicalizes the given content as bytes.
|
||
|
|
*/
|
||
|
|
static canonicalizeAsBytes(content) {
|
||
|
|
const contentWithoutUndefinedProperties = _JsonCanonicalizer.removeAllUndefinedProperties(content);
|
||
|
|
const canonicalizedString = canonicalize.default(contentWithoutUndefinedProperties);
|
||
|
|
const contentBytes = Encoder2.stringToBytes(canonicalizedString);
|
||
|
|
return contentBytes;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Removes all properties within the given object with `undefined` as value.
|
||
|
|
*/
|
||
|
|
static removeAllUndefinedProperties(content) {
|
||
|
|
for (const key in content) {
|
||
|
|
if (typeof content[key] === "object") {
|
||
|
|
_JsonCanonicalizer.removeAllUndefinedProperties(content[key]);
|
||
|
|
} else if (content[key] === void 0) {
|
||
|
|
delete content[key];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return content;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/vendor/varint.js
|
||
|
|
var encode_1 = encode3;
|
||
|
|
var MSB = 128;
|
||
|
|
var REST = 127;
|
||
|
|
var MSBALL = ~REST;
|
||
|
|
var INT = Math.pow(2, 31);
|
||
|
|
function encode3(num, out, offset) {
|
||
|
|
out = out || [];
|
||
|
|
offset = offset || 0;
|
||
|
|
var oldOffset = offset;
|
||
|
|
while (num >= INT) {
|
||
|
|
out[offset++] = num & 255 | MSB;
|
||
|
|
num /= 128;
|
||
|
|
}
|
||
|
|
while (num & MSBALL) {
|
||
|
|
out[offset++] = num & 255 | MSB;
|
||
|
|
num >>>= 7;
|
||
|
|
}
|
||
|
|
out[offset] = num | 0;
|
||
|
|
encode3.bytes = offset - oldOffset + 1;
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
var decode3 = read;
|
||
|
|
var MSB$1 = 128;
|
||
|
|
var REST$1 = 127;
|
||
|
|
function read(buf, offset) {
|
||
|
|
var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
|
||
|
|
do {
|
||
|
|
if (counter >= l) {
|
||
|
|
read.bytes = 0;
|
||
|
|
throw new RangeError("Could not decode varint");
|
||
|
|
}
|
||
|
|
b = buf[counter++];
|
||
|
|
res += shift < 28 ? (b & REST$1) << shift : (b & REST$1) * Math.pow(2, shift);
|
||
|
|
shift += 7;
|
||
|
|
} while (b >= MSB$1);
|
||
|
|
read.bytes = counter - offset;
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
var N1 = Math.pow(2, 7);
|
||
|
|
var N2 = Math.pow(2, 14);
|
||
|
|
var N3 = Math.pow(2, 21);
|
||
|
|
var N4 = Math.pow(2, 28);
|
||
|
|
var N5 = Math.pow(2, 35);
|
||
|
|
var N6 = Math.pow(2, 42);
|
||
|
|
var N7 = Math.pow(2, 49);
|
||
|
|
var N8 = Math.pow(2, 56);
|
||
|
|
var N9 = Math.pow(2, 63);
|
||
|
|
var length = function(value) {
|
||
|
|
return value < N1 ? 1 : value < N2 ? 2 : value < N3 ? 3 : value < N4 ? 4 : value < N5 ? 5 : value < N6 ? 6 : value < N7 ? 7 : value < N8 ? 8 : value < N9 ? 9 : 10;
|
||
|
|
};
|
||
|
|
var varint = {
|
||
|
|
encode: encode_1,
|
||
|
|
decode: decode3,
|
||
|
|
encodingLength: length
|
||
|
|
};
|
||
|
|
var _brrp_varint = varint;
|
||
|
|
var varint_default = _brrp_varint;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/varint.js
|
||
|
|
var decode4 = (data, offset = 0) => {
|
||
|
|
const code = varint_default.decode(data, offset);
|
||
|
|
return [code, varint_default.decode.bytes];
|
||
|
|
};
|
||
|
|
var encodeTo = (int, target, offset = 0) => {
|
||
|
|
varint_default.encode(int, target, offset);
|
||
|
|
return target;
|
||
|
|
};
|
||
|
|
var encodingLength3 = (int) => {
|
||
|
|
return varint_default.encodingLength(int);
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/hashes/digest.js
|
||
|
|
var create = (code, digest) => {
|
||
|
|
const size = digest.byteLength;
|
||
|
|
const sizeOffset = encodingLength3(code);
|
||
|
|
const digestOffset = sizeOffset + encodingLength3(size);
|
||
|
|
const bytes = new Uint8Array(digestOffset + size);
|
||
|
|
encodeTo(code, bytes, 0);
|
||
|
|
encodeTo(size, bytes, sizeOffset);
|
||
|
|
bytes.set(digest, digestOffset);
|
||
|
|
return new Digest(code, size, digest, bytes);
|
||
|
|
};
|
||
|
|
var decode5 = (multihash) => {
|
||
|
|
const bytes = coerce(multihash);
|
||
|
|
const [code, sizeOffset] = decode4(bytes);
|
||
|
|
const [size, digestOffset] = decode4(bytes.subarray(sizeOffset));
|
||
|
|
const digest = bytes.subarray(sizeOffset + digestOffset);
|
||
|
|
if (digest.byteLength !== size) {
|
||
|
|
throw new Error("Incorrect length");
|
||
|
|
}
|
||
|
|
return new Digest(code, size, digest, bytes);
|
||
|
|
};
|
||
|
|
var Digest = class {
|
||
|
|
/**
|
||
|
|
* Creates a multihash digest.
|
||
|
|
*
|
||
|
|
* @param {Code} code
|
||
|
|
* @param {Size} size
|
||
|
|
* @param {Uint8Array} digest
|
||
|
|
* @param {Uint8Array} bytes
|
||
|
|
*/
|
||
|
|
constructor(code, size, digest, bytes) {
|
||
|
|
this.code = code;
|
||
|
|
this.size = size;
|
||
|
|
this.digest = digest;
|
||
|
|
this.bytes = bytes;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/hashes/sha2.js
|
||
|
|
var import_crypto4 = __toESM(require("crypto"), 1);
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/hashes/hasher.js
|
||
|
|
var from2 = ({ name, code, encode: encode4 }) => new Hasher(name, code, encode4);
|
||
|
|
var Hasher = class {
|
||
|
|
/**
|
||
|
|
*
|
||
|
|
* @param {Name} name
|
||
|
|
* @param {Code} code
|
||
|
|
* @param {(input: Uint8Array) => Await<Uint8Array>} encode
|
||
|
|
*/
|
||
|
|
constructor(name, code, encode4) {
|
||
|
|
this.name = name;
|
||
|
|
this.code = code;
|
||
|
|
this.encode = encode4;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* @param {Uint8Array} input
|
||
|
|
* @returns {Await<Digest.Digest<Code, number>>}
|
||
|
|
*/
|
||
|
|
digest(input) {
|
||
|
|
if (input instanceof Uint8Array) {
|
||
|
|
const result = this.encode(input);
|
||
|
|
return result instanceof Uint8Array ? create(this.code, result) : result.then((digest) => create(this.code, digest));
|
||
|
|
} else {
|
||
|
|
throw Error("Unknown type, must be binary type");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/multiformats@12.1.3/node_modules/multiformats/src/hashes/sha2.js
|
||
|
|
var sha256 = from2({
|
||
|
|
name: "sha2-256",
|
||
|
|
code: 18,
|
||
|
|
encode: (input) => coerce(import_crypto4.default.createHash("sha256").update(input).digest())
|
||
|
|
});
|
||
|
|
var sha512 = from2({
|
||
|
|
name: "sha2-512",
|
||
|
|
code: 19,
|
||
|
|
encode: (input) => coerce(import_crypto4.default.createHash("sha512").update(input).digest())
|
||
|
|
});
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/Multihash.js
|
||
|
|
var __awaiter5 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var Multihash = class _Multihash {
|
||
|
|
/**
|
||
|
|
* Multihashes the content using the hashing algorithm specified.
|
||
|
|
* @param hashAlgorithmInMultihashCode The hashing algorithm to use.
|
||
|
|
* @returns A multihash of the content.
|
||
|
|
*/
|
||
|
|
static hash(content, hashAlgorithmInMultihashCode) {
|
||
|
|
return __awaiter5(this, void 0, void 0, function* () {
|
||
|
|
let multihash;
|
||
|
|
switch (hashAlgorithmInMultihashCode) {
|
||
|
|
case 18:
|
||
|
|
let hasher = yield sha256.digest(content);
|
||
|
|
multihash = hasher.bytes;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
throw new IonError(ErrorCode_default.MultihashUnsupportedHashAlgorithm, `Hash algorithm defined in multihash code ${hashAlgorithmInMultihashCode} is not supported.`);
|
||
|
|
}
|
||
|
|
return multihash;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Hashes the content using the hashing algorithm specified as a generic (non-multihash) hash.
|
||
|
|
* @param hashAlgorithmInMultihashCode The hashing algorithm to use.
|
||
|
|
* @returns A multihash bytes.
|
||
|
|
*/
|
||
|
|
static hashAsNonMultihashBytes(content, hashAlgorithmInMultihashCode) {
|
||
|
|
return __awaiter5(this, void 0, void 0, function* () {
|
||
|
|
let hash;
|
||
|
|
switch (hashAlgorithmInMultihashCode) {
|
||
|
|
case 18:
|
||
|
|
hash = yield sha256.encode(content);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
throw new IonError(ErrorCode_default.MultihashUnsupportedHashAlgorithm, `Hash algorithm defined in multihash code ${hashAlgorithmInMultihashCode} is not supported.`);
|
||
|
|
}
|
||
|
|
return hash;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Canonicalize the given content, then double hashes the result using the latest supported hash algorithm, then encodes the multihash.
|
||
|
|
* Mainly used for testing purposes.
|
||
|
|
*/
|
||
|
|
static canonicalizeThenHashThenEncode(content, hashAlgorithmInMultihashCode) {
|
||
|
|
return __awaiter5(this, void 0, void 0, function* () {
|
||
|
|
const canonicalizedStringBytes = JsonCanonicalizer.canonicalizeAsBytes(content);
|
||
|
|
const multihashEncodedString = yield _Multihash.hashThenEncode(canonicalizedStringBytes, hashAlgorithmInMultihashCode);
|
||
|
|
return multihashEncodedString;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Canonicalize the given content, then double hashes the result using the latest supported hash algorithm, then encodes the multihash.
|
||
|
|
* Mainly used for testing purposes.
|
||
|
|
*/
|
||
|
|
static canonicalizeThenDoubleHashThenEncode(content, hashAlgorithmInMultihashCode) {
|
||
|
|
return __awaiter5(this, void 0, void 0, function* () {
|
||
|
|
const contentBytes = JsonCanonicalizer.canonicalizeAsBytes(content);
|
||
|
|
const intermediateHashBytes = yield _Multihash.hashAsNonMultihashBytes(contentBytes, hashAlgorithmInMultihashCode);
|
||
|
|
const multihashEncodedString = yield _Multihash.hashThenEncode(intermediateHashBytes, hashAlgorithmInMultihashCode);
|
||
|
|
return multihashEncodedString;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Hashes the content using the hashing algorithm specified then encodes the multihash bytes as string.
|
||
|
|
* @param hashAlgorithmInMultihashCode The hashing algorithm to use.
|
||
|
|
*/
|
||
|
|
static hashThenEncode(content, hashAlgorithmInMultihashCode) {
|
||
|
|
return __awaiter5(this, void 0, void 0, function* () {
|
||
|
|
const multihashBytes = yield _Multihash.hash(content, hashAlgorithmInMultihashCode);
|
||
|
|
const multihashEncodedString = Encoder2.encode(multihashBytes);
|
||
|
|
return multihashEncodedString;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Checks if the given encoded hash is a multihash computed using the configured hashing algorithm.
|
||
|
|
*/
|
||
|
|
static validateEncodedHashComputedUsingSupportedHashAlgorithm(encodedMultihash, inputContextForErrorLogging) {
|
||
|
|
let multihash;
|
||
|
|
const multihashBytes = Encoder2.decodeAsBytes(encodedMultihash, inputContextForErrorLogging);
|
||
|
|
try {
|
||
|
|
multihash = decode5(multihashBytes);
|
||
|
|
} catch (_a) {
|
||
|
|
throw new IonError(ErrorCode_default.MultihashStringNotAMultihash, `Given ${inputContextForErrorLogging} string '${encodedMultihash}' is not a multihash after decoding.`);
|
||
|
|
}
|
||
|
|
const hashAlgorithmInMultihashCode = IonSdkConfig_default.hashAlgorithmInMultihashCode;
|
||
|
|
if (hashAlgorithmInMultihashCode !== multihash.code) {
|
||
|
|
throw new IonError(ErrorCode_default.MultihashUnsupportedHashAlgorithm, `Given ${inputContextForErrorLogging} uses unsupported multihash algorithm with code ${multihash.code}, should use ${hashAlgorithmInMultihashCode} or change IonSdkConfig to desired hashing algorithm.`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/enums/OperationType.js
|
||
|
|
var OperationType;
|
||
|
|
(function(OperationType2) {
|
||
|
|
OperationType2["Create"] = "create";
|
||
|
|
OperationType2["Update"] = "update";
|
||
|
|
OperationType2["Deactivate"] = "deactivate";
|
||
|
|
OperationType2["Recover"] = "recover";
|
||
|
|
})(OperationType || (OperationType = {}));
|
||
|
|
var OperationType_default = OperationType;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/enums/PatchAction.js
|
||
|
|
var PatchAction;
|
||
|
|
(function(PatchAction2) {
|
||
|
|
PatchAction2["Replace"] = "replace";
|
||
|
|
PatchAction2["AddPublicKeys"] = "add-public-keys";
|
||
|
|
PatchAction2["RemovePublicKeys"] = "remove-public-keys";
|
||
|
|
PatchAction2["AddServices"] = "add-services";
|
||
|
|
PatchAction2["RemoveServices"] = "remove-services";
|
||
|
|
})(PatchAction || (PatchAction = {}));
|
||
|
|
var PatchAction_default = PatchAction;
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/IonRequest.js
|
||
|
|
var __awaiter6 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var IonRequest = class _IonRequest {
|
||
|
|
/**
|
||
|
|
* Creates an ION DID create request.
|
||
|
|
* @param input.document The initial state to be associate with the ION DID to be created using a `replace` document patch action.
|
||
|
|
*/
|
||
|
|
static createCreateRequest(input) {
|
||
|
|
return __awaiter6(this, void 0, void 0, function* () {
|
||
|
|
const recoveryKey = input.recoveryKey;
|
||
|
|
const updateKey = input.updateKey;
|
||
|
|
const didDocumentKeys = input.document.publicKeys;
|
||
|
|
const services = input.document.services;
|
||
|
|
InputValidator.validateEs256kOperationKey(recoveryKey, OperationKeyType_default.Public);
|
||
|
|
InputValidator.validateEs256kOperationKey(updateKey, OperationKeyType_default.Public);
|
||
|
|
_IonRequest.validateDidDocumentKeys(didDocumentKeys);
|
||
|
|
_IonRequest.validateServices(services);
|
||
|
|
const hashAlgorithmInMultihashCode = IonSdkConfig_default.hashAlgorithmInMultihashCode;
|
||
|
|
const patches = [{
|
||
|
|
action: PatchAction_default.Replace,
|
||
|
|
document: input.document
|
||
|
|
}];
|
||
|
|
const delta = {
|
||
|
|
updateCommitment: yield Multihash.canonicalizeThenDoubleHashThenEncode(updateKey, hashAlgorithmInMultihashCode),
|
||
|
|
patches
|
||
|
|
};
|
||
|
|
_IonRequest.validateDeltaSize(delta);
|
||
|
|
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
|
||
|
|
const suffixData = {
|
||
|
|
deltaHash,
|
||
|
|
recoveryCommitment: yield Multihash.canonicalizeThenDoubleHashThenEncode(recoveryKey, hashAlgorithmInMultihashCode)
|
||
|
|
};
|
||
|
|
const operationRequest = {
|
||
|
|
type: OperationType_default.Create,
|
||
|
|
suffixData,
|
||
|
|
delta
|
||
|
|
};
|
||
|
|
return operationRequest;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static createDeactivateRequest(input) {
|
||
|
|
return __awaiter6(this, void 0, void 0, function* () {
|
||
|
|
_IonRequest.validateDidSuffix(input.didSuffix);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.recoveryPublicKey, OperationKeyType_default.Public);
|
||
|
|
const hashAlgorithmInMultihashCode = IonSdkConfig_default.hashAlgorithmInMultihashCode;
|
||
|
|
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.recoveryPublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const dataToBeSigned = {
|
||
|
|
didSuffix: input.didSuffix,
|
||
|
|
recoveryKey: input.recoveryPublicKey
|
||
|
|
};
|
||
|
|
const compactJws = yield input.signer.sign({ alg: "ES256K" }, dataToBeSigned);
|
||
|
|
return {
|
||
|
|
type: OperationType_default.Deactivate,
|
||
|
|
didSuffix: input.didSuffix,
|
||
|
|
revealValue,
|
||
|
|
signedData: compactJws
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static createRecoverRequest(input) {
|
||
|
|
return __awaiter6(this, void 0, void 0, function* () {
|
||
|
|
_IonRequest.validateDidSuffix(input.didSuffix);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.recoveryPublicKey, OperationKeyType_default.Public);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.nextRecoveryPublicKey, OperationKeyType_default.Public);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.nextUpdatePublicKey, OperationKeyType_default.Public);
|
||
|
|
_IonRequest.validateDidDocumentKeys(input.document.publicKeys);
|
||
|
|
_IonRequest.validateServices(input.document.services);
|
||
|
|
const hashAlgorithmInMultihashCode = IonSdkConfig_default.hashAlgorithmInMultihashCode;
|
||
|
|
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.recoveryPublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const patches = [{
|
||
|
|
action: PatchAction_default.Replace,
|
||
|
|
document: input.document
|
||
|
|
}];
|
||
|
|
const nextUpdateCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextUpdatePublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const delta = {
|
||
|
|
patches,
|
||
|
|
updateCommitment: nextUpdateCommitmentHash
|
||
|
|
};
|
||
|
|
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
|
||
|
|
const nextRecoveryCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextRecoveryPublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const dataToBeSigned = {
|
||
|
|
recoveryCommitment: nextRecoveryCommitmentHash,
|
||
|
|
recoveryKey: input.recoveryPublicKey,
|
||
|
|
deltaHash
|
||
|
|
};
|
||
|
|
const compactJws = yield input.signer.sign({ alg: "ES256K" }, dataToBeSigned);
|
||
|
|
return {
|
||
|
|
type: OperationType_default.Recover,
|
||
|
|
didSuffix: input.didSuffix,
|
||
|
|
revealValue,
|
||
|
|
delta,
|
||
|
|
signedData: compactJws
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static createUpdateRequest(input) {
|
||
|
|
return __awaiter6(this, void 0, void 0, function* () {
|
||
|
|
_IonRequest.validateDidSuffix(input.didSuffix);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.updatePublicKey, OperationKeyType_default.Public);
|
||
|
|
InputValidator.validateEs256kOperationKey(input.nextUpdatePublicKey, OperationKeyType_default.Public);
|
||
|
|
_IonRequest.validateServices(input.servicesToAdd);
|
||
|
|
_IonRequest.validateDidDocumentKeys(input.publicKeysToAdd);
|
||
|
|
if (input.idsOfServicesToRemove !== void 0) {
|
||
|
|
for (const id of input.idsOfServicesToRemove) {
|
||
|
|
InputValidator.validateId(id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (input.idsOfPublicKeysToRemove !== void 0) {
|
||
|
|
for (const id of input.idsOfPublicKeysToRemove) {
|
||
|
|
InputValidator.validateId(id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const patches = [];
|
||
|
|
const servicesToAdd = input.servicesToAdd;
|
||
|
|
if (servicesToAdd !== void 0 && servicesToAdd.length > 0) {
|
||
|
|
const patch = {
|
||
|
|
action: PatchAction_default.AddServices,
|
||
|
|
services: servicesToAdd
|
||
|
|
};
|
||
|
|
patches.push(patch);
|
||
|
|
}
|
||
|
|
const idsOfServicesToRemove = input.idsOfServicesToRemove;
|
||
|
|
if (idsOfServicesToRemove !== void 0 && idsOfServicesToRemove.length > 0) {
|
||
|
|
const patch = {
|
||
|
|
action: PatchAction_default.RemoveServices,
|
||
|
|
ids: idsOfServicesToRemove
|
||
|
|
};
|
||
|
|
patches.push(patch);
|
||
|
|
}
|
||
|
|
const publicKeysToAdd = input.publicKeysToAdd;
|
||
|
|
if (publicKeysToAdd !== void 0 && publicKeysToAdd.length > 0) {
|
||
|
|
const patch = {
|
||
|
|
action: PatchAction_default.AddPublicKeys,
|
||
|
|
publicKeys: publicKeysToAdd
|
||
|
|
};
|
||
|
|
patches.push(patch);
|
||
|
|
}
|
||
|
|
const idsOfPublicKeysToRemove = input.idsOfPublicKeysToRemove;
|
||
|
|
if (idsOfPublicKeysToRemove !== void 0 && idsOfPublicKeysToRemove.length > 0) {
|
||
|
|
const patch = {
|
||
|
|
action: PatchAction_default.RemovePublicKeys,
|
||
|
|
ids: idsOfPublicKeysToRemove
|
||
|
|
};
|
||
|
|
patches.push(patch);
|
||
|
|
}
|
||
|
|
const hashAlgorithmInMultihashCode = IonSdkConfig_default.hashAlgorithmInMultihashCode;
|
||
|
|
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.updatePublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const nextUpdateCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextUpdatePublicKey, hashAlgorithmInMultihashCode);
|
||
|
|
const delta = {
|
||
|
|
patches,
|
||
|
|
updateCommitment: nextUpdateCommitmentHash
|
||
|
|
};
|
||
|
|
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
|
||
|
|
const dataToBeSigned = {
|
||
|
|
updateKey: input.updatePublicKey,
|
||
|
|
deltaHash
|
||
|
|
};
|
||
|
|
const compactJws = yield input.signer.sign({ alg: "ES256K" }, dataToBeSigned);
|
||
|
|
return {
|
||
|
|
type: OperationType_default.Update,
|
||
|
|
didSuffix: input.didSuffix,
|
||
|
|
revealValue,
|
||
|
|
delta,
|
||
|
|
signedData: compactJws
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static validateDidSuffix(didSuffix) {
|
||
|
|
Multihash.validateEncodedHashComputedUsingSupportedHashAlgorithm(didSuffix, "didSuffix");
|
||
|
|
}
|
||
|
|
static validateDidDocumentKeys(publicKeys) {
|
||
|
|
if (publicKeys === void 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const publicKeyIdSet = /* @__PURE__ */ new Set();
|
||
|
|
for (const publicKey of publicKeys) {
|
||
|
|
if (Array.isArray(publicKey.publicKeyJwk)) {
|
||
|
|
throw new IonError(ErrorCode_default.DidDocumentPublicKeyMissingOrIncorrectType, `DID Document key 'publicKeyJwk' property is not a non-array object.`);
|
||
|
|
}
|
||
|
|
InputValidator.validateId(publicKey.id);
|
||
|
|
if (publicKeyIdSet.has(publicKey.id)) {
|
||
|
|
throw new IonError(ErrorCode_default.DidDocumentPublicKeyIdDuplicated, `DID Document key with ID '${publicKey.id}' already exists.`);
|
||
|
|
}
|
||
|
|
publicKeyIdSet.add(publicKey.id);
|
||
|
|
InputValidator.validatePublicKeyPurposes(publicKey.purposes);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
static validateServices(services) {
|
||
|
|
if (services !== void 0 && services.length !== 0) {
|
||
|
|
const serviceIdSet = /* @__PURE__ */ new Set();
|
||
|
|
for (const service of services) {
|
||
|
|
_IonRequest.validateService(service);
|
||
|
|
if (serviceIdSet.has(service.id)) {
|
||
|
|
throw new IonError(ErrorCode_default.DidDocumentServiceIdDuplicated, "Service id has to be unique");
|
||
|
|
}
|
||
|
|
serviceIdSet.add(service.id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
static validateService(service) {
|
||
|
|
InputValidator.validateId(service.id);
|
||
|
|
const maxTypeLength = 30;
|
||
|
|
if (service.type.length > maxTypeLength) {
|
||
|
|
const errorMessage = `Service endpoint type length ${service.type.length} exceeds max allowed length of ${maxTypeLength}.`;
|
||
|
|
throw new IonError(ErrorCode_default.ServiceTypeTooLong, errorMessage);
|
||
|
|
}
|
||
|
|
if (Array.isArray(service.serviceEndpoint)) {
|
||
|
|
const errorMessage = "Service endpoint value cannot be an array.";
|
||
|
|
throw new IonError(ErrorCode_default.ServiceEndpointCannotBeAnArray, errorMessage);
|
||
|
|
}
|
||
|
|
if (typeof service.serviceEndpoint === "string") {
|
||
|
|
const uri = URI.parse(service.serviceEndpoint);
|
||
|
|
if (uri.error !== void 0) {
|
||
|
|
throw new IonError(ErrorCode_default.ServiceEndpointStringNotValidUri, `Service endpoint string '${service.serviceEndpoint}' is not a URI.`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
static validateDeltaSize(delta) {
|
||
|
|
const deltaBytes = JsonCanonicalizer.canonicalizeAsBytes(delta);
|
||
|
|
if (deltaBytes.length > IonSdkConfig_default.maxCanonicalizedDeltaSizeInBytes) {
|
||
|
|
const errorMessage = `Delta of ${deltaBytes.length} bytes exceeded limit of ${IonSdkConfig_default.maxCanonicalizedDeltaSizeInBytes} bytes.`;
|
||
|
|
throw new IonError(ErrorCode_default.DeltaExceedsMaximumSize, errorMessage);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/IonDid.js
|
||
|
|
var __awaiter7 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var IonDid = class _IonDid {
|
||
|
|
/**
|
||
|
|
* Creates a long-form DID.
|
||
|
|
* @param input.document The initial state to be associate with the ION DID to be created using a `replace` document patch action.
|
||
|
|
*/
|
||
|
|
static createLongFormDid(input) {
|
||
|
|
return __awaiter7(this, void 0, void 0, function* () {
|
||
|
|
const createRequest = yield IonRequest.createCreateRequest(input);
|
||
|
|
const didUniqueSuffix = yield _IonDid.computeDidUniqueSuffix(createRequest.suffixData);
|
||
|
|
let shortFormDid;
|
||
|
|
if (IonSdkConfig_default.network === void 0 || IonSdkConfig_default.network === "mainnet") {
|
||
|
|
shortFormDid = `did:ion:${didUniqueSuffix}`;
|
||
|
|
} else {
|
||
|
|
shortFormDid = `did:ion:${IonSdkConfig_default.network}:${didUniqueSuffix}`;
|
||
|
|
}
|
||
|
|
const initialState = {
|
||
|
|
suffixData: createRequest.suffixData,
|
||
|
|
delta: createRequest.delta
|
||
|
|
};
|
||
|
|
const canonicalizedInitialStateBytes = JsonCanonicalizer.canonicalizeAsBytes(initialState);
|
||
|
|
const encodedCanonicalizedInitialStateString = Encoder2.encode(canonicalizedInitialStateBytes);
|
||
|
|
const longFormDid = `${shortFormDid}:${encodedCanonicalizedInitialStateString}`;
|
||
|
|
return longFormDid;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Computes the DID unique suffix given the encoded suffix data string.
|
||
|
|
*/
|
||
|
|
static computeDidUniqueSuffix(suffixData) {
|
||
|
|
return __awaiter7(this, void 0, void 0, function* () {
|
||
|
|
const canonicalizedStringBytes = JsonCanonicalizer.canonicalizeAsBytes(suffixData);
|
||
|
|
const multihash = yield Multihash.hash(canonicalizedStringBytes, IonSdkConfig_default.hashAlgorithmInMultihashCode);
|
||
|
|
const encodedMultihash = Encoder2.encode(multihash);
|
||
|
|
return encodedMultihash;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@noble+ed25519@2.0.0/node_modules/@noble/ed25519/index.js
|
||
|
|
var P = 2n ** 255n - 19n;
|
||
|
|
var N = 2n ** 252n + 27742317777372353535851937790883648493n;
|
||
|
|
var Gx = 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an;
|
||
|
|
var Gy = 0x6666666666666666666666666666666666666666666666666666666666666658n;
|
||
|
|
var CURVE = {
|
||
|
|
a: -1n,
|
||
|
|
d: 37095705934669439343138083508754565189542113879843219016388785533085940283555n,
|
||
|
|
p: P,
|
||
|
|
n: N,
|
||
|
|
h: 8,
|
||
|
|
Gx,
|
||
|
|
Gy
|
||
|
|
// field prime, curve (group) order, cofactor
|
||
|
|
};
|
||
|
|
var err = (m = "") => {
|
||
|
|
throw new Error(m);
|
||
|
|
};
|
||
|
|
var str = (s) => typeof s === "string";
|
||
|
|
var au8 = (a, l) => (
|
||
|
|
// is Uint8Array (of specific length)
|
||
|
|
!(a instanceof Uint8Array) || typeof l === "number" && l > 0 && a.length !== l ? err("Uint8Array expected") : a
|
||
|
|
);
|
||
|
|
var u8n = (data) => new Uint8Array(data);
|
||
|
|
var toU8 = (a, len) => au8(str(a) ? h2b(a) : u8n(a), len);
|
||
|
|
var mod = (a, b = P) => {
|
||
|
|
let r = a % b;
|
||
|
|
return r >= 0n ? r : b + r;
|
||
|
|
};
|
||
|
|
var isPoint = (p) => p instanceof Point ? p : err("Point expected");
|
||
|
|
var Gpows = void 0;
|
||
|
|
var Point = class _Point {
|
||
|
|
constructor(ex, ey, ez, et) {
|
||
|
|
this.ex = ex;
|
||
|
|
this.ey = ey;
|
||
|
|
this.ez = ez;
|
||
|
|
this.et = et;
|
||
|
|
}
|
||
|
|
static fromAffine(p) {
|
||
|
|
return new _Point(p.x, p.y, 1n, mod(p.x * p.y));
|
||
|
|
}
|
||
|
|
static fromHex(hex, strict = true) {
|
||
|
|
const { d } = CURVE;
|
||
|
|
hex = toU8(hex, 32);
|
||
|
|
const normed = hex.slice();
|
||
|
|
normed[31] = hex[31] & ~128;
|
||
|
|
const y = b2n_LE(normed);
|
||
|
|
if (y === 0n) {
|
||
|
|
} else {
|
||
|
|
if (strict && !(0n < y && y < P))
|
||
|
|
err("bad y coord 1");
|
||
|
|
if (!strict && !(0n < y && y < 2n ** 256n))
|
||
|
|
err("bad y coord 2");
|
||
|
|
}
|
||
|
|
const y2 = mod(y * y);
|
||
|
|
const u = mod(y2 - 1n);
|
||
|
|
const v = mod(d * y2 + 1n);
|
||
|
|
let { isValid, value: x } = uvRatio(u, v);
|
||
|
|
if (!isValid)
|
||
|
|
err("bad y coordinate 3");
|
||
|
|
const isXOdd = (x & 1n) === 1n;
|
||
|
|
const isHeadOdd = (hex[31] & 128) !== 0;
|
||
|
|
if (isHeadOdd !== isXOdd)
|
||
|
|
x = mod(-x);
|
||
|
|
return new _Point(x, y, 1n, mod(x * y));
|
||
|
|
}
|
||
|
|
get x() {
|
||
|
|
return this.toAffine().x;
|
||
|
|
}
|
||
|
|
// .x, .y will call expensive toAffine.
|
||
|
|
get y() {
|
||
|
|
return this.toAffine().y;
|
||
|
|
}
|
||
|
|
// Should be used with care.
|
||
|
|
equals(other) {
|
||
|
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||
|
|
const { ex: X2, ey: Y2, ez: Z2 } = isPoint(other);
|
||
|
|
const X1Z2 = mod(X1 * Z2), X2Z1 = mod(X2 * Z1);
|
||
|
|
const Y1Z2 = mod(Y1 * Z2), Y2Z1 = mod(Y2 * Z1);
|
||
|
|
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
||
|
|
}
|
||
|
|
is0() {
|
||
|
|
return this.equals(I);
|
||
|
|
}
|
||
|
|
negate() {
|
||
|
|
return new _Point(mod(-this.ex), this.ey, this.ez, mod(-this.et));
|
||
|
|
}
|
||
|
|
double() {
|
||
|
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||
|
|
const { a } = CURVE;
|
||
|
|
const A = mod(X1 * X1);
|
||
|
|
const B = mod(Y1 * Y1);
|
||
|
|
const C = mod(2n * mod(Z1 * Z1));
|
||
|
|
const D = mod(a * A);
|
||
|
|
const x1y1 = X1 + Y1;
|
||
|
|
const E = mod(mod(x1y1 * x1y1) - A - B);
|
||
|
|
const G3 = D + B;
|
||
|
|
const F = G3 - C;
|
||
|
|
const H = D - B;
|
||
|
|
const X3 = mod(E * F);
|
||
|
|
const Y3 = mod(G3 * H);
|
||
|
|
const T3 = mod(E * H);
|
||
|
|
const Z3 = mod(F * G3);
|
||
|
|
return new _Point(X3, Y3, Z3, T3);
|
||
|
|
}
|
||
|
|
add(other) {
|
||
|
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
||
|
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = isPoint(other);
|
||
|
|
const { a, d } = CURVE;
|
||
|
|
const A = mod(X1 * X2);
|
||
|
|
const B = mod(Y1 * Y2);
|
||
|
|
const C = mod(T1 * d * T2);
|
||
|
|
const D = mod(Z1 * Z2);
|
||
|
|
const E = mod((X1 + Y1) * (X2 + Y2) - A - B);
|
||
|
|
const F = mod(D - C);
|
||
|
|
const G3 = mod(D + C);
|
||
|
|
const H = mod(B - a * A);
|
||
|
|
const X3 = mod(E * F);
|
||
|
|
const Y3 = mod(G3 * H);
|
||
|
|
const T3 = mod(E * H);
|
||
|
|
const Z3 = mod(F * G3);
|
||
|
|
return new _Point(X3, Y3, Z3, T3);
|
||
|
|
}
|
||
|
|
mul(n, safe = true) {
|
||
|
|
if (n === 0n)
|
||
|
|
return safe === true ? err("cannot multiply by 0") : I;
|
||
|
|
if (!(typeof n === "bigint" && 0n < n && n < N))
|
||
|
|
err("invalid scalar, must be < L");
|
||
|
|
if (!safe && this.is0() || n === 1n)
|
||
|
|
return this;
|
||
|
|
if (this.equals(G))
|
||
|
|
return wNAF(n).p;
|
||
|
|
let p = I, f = G;
|
||
|
|
for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
|
||
|
|
if (n & 1n)
|
||
|
|
p = p.add(d);
|
||
|
|
else if (safe)
|
||
|
|
f = f.add(d);
|
||
|
|
}
|
||
|
|
return p;
|
||
|
|
}
|
||
|
|
multiply(scalar) {
|
||
|
|
return this.mul(scalar);
|
||
|
|
}
|
||
|
|
// Aliases for compatibilty
|
||
|
|
clearCofactor() {
|
||
|
|
return this.mul(BigInt(CURVE.h), false);
|
||
|
|
}
|
||
|
|
// multiply by cofactor
|
||
|
|
isSmallOrder() {
|
||
|
|
return this.clearCofactor().is0();
|
||
|
|
}
|
||
|
|
// check if P is small order
|
||
|
|
isTorsionFree() {
|
||
|
|
let p = this.mul(N / 2n, false).double();
|
||
|
|
if (N % 2n)
|
||
|
|
p = p.add(this);
|
||
|
|
return p.is0();
|
||
|
|
}
|
||
|
|
toAffine() {
|
||
|
|
const { ex: x, ey: y, ez: z } = this;
|
||
|
|
if (this.is0())
|
||
|
|
return { x: 0n, y: 0n };
|
||
|
|
const iz = invert(z);
|
||
|
|
if (mod(z * iz) !== 1n)
|
||
|
|
err("invalid inverse");
|
||
|
|
return { x: mod(x * iz), y: mod(y * iz) };
|
||
|
|
}
|
||
|
|
toRawBytes() {
|
||
|
|
const { x, y } = this.toAffine();
|
||
|
|
const b = n2b_32LE(y);
|
||
|
|
b[31] |= x & 1n ? 128 : 0;
|
||
|
|
return b;
|
||
|
|
}
|
||
|
|
toHex() {
|
||
|
|
return b2h(this.toRawBytes());
|
||
|
|
}
|
||
|
|
// encode to hex string
|
||
|
|
};
|
||
|
|
Point.BASE = new Point(Gx, Gy, 1n, mod(Gx * Gy));
|
||
|
|
Point.ZERO = new Point(0n, 1n, 1n, 0n);
|
||
|
|
var { BASE: G, ZERO: I } = Point;
|
||
|
|
var padh = (num, pad) => num.toString(16).padStart(pad, "0");
|
||
|
|
var b2h = (b) => Array.from(b).map((e) => padh(e, 2)).join("");
|
||
|
|
var h2b = (hex) => {
|
||
|
|
const l = hex.length;
|
||
|
|
if (!str(hex) || l % 2)
|
||
|
|
err("hex invalid 1");
|
||
|
|
const arr = u8n(l / 2);
|
||
|
|
for (let i = 0; i < arr.length; i++) {
|
||
|
|
const j = i * 2;
|
||
|
|
const h = hex.slice(j, j + 2);
|
||
|
|
const b = Number.parseInt(h, 16);
|
||
|
|
if (Number.isNaN(b) || b < 0)
|
||
|
|
err("hex invalid 2");
|
||
|
|
arr[i] = b;
|
||
|
|
}
|
||
|
|
return arr;
|
||
|
|
};
|
||
|
|
var n2b_32LE = (num) => h2b(padh(num, 32 * 2)).reverse();
|
||
|
|
var b2n_LE = (b) => BigInt("0x" + b2h(u8n(au8(b)).reverse()));
|
||
|
|
var concatB = (...arrs) => {
|
||
|
|
const r = u8n(arrs.reduce((sum, a) => sum + au8(a).length, 0));
|
||
|
|
let pad = 0;
|
||
|
|
arrs.forEach((a) => {
|
||
|
|
r.set(a, pad);
|
||
|
|
pad += a.length;
|
||
|
|
});
|
||
|
|
return r;
|
||
|
|
};
|
||
|
|
var invert = (num, md = P) => {
|
||
|
|
if (num === 0n || md <= 0n)
|
||
|
|
err("no inverse n=" + num + " mod=" + md);
|
||
|
|
let a = mod(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;
|
||
|
|
while (a !== 0n) {
|
||
|
|
const q = b / a, r = b % a;
|
||
|
|
const m = x - u * q, n = y - v * q;
|
||
|
|
b = a, a = r, x = u, y = v, u = m, v = n;
|
||
|
|
}
|
||
|
|
return b === 1n ? mod(x, md) : err("no inverse");
|
||
|
|
};
|
||
|
|
var pow2 = (x, power) => {
|
||
|
|
let r = x;
|
||
|
|
while (power-- > 0n) {
|
||
|
|
r *= r;
|
||
|
|
r %= P;
|
||
|
|
}
|
||
|
|
return r;
|
||
|
|
};
|
||
|
|
var pow_2_252_3 = (x) => {
|
||
|
|
const x2 = x * x % P;
|
||
|
|
const b2 = x2 * x % P;
|
||
|
|
const b4 = pow2(b2, 2n) * b2 % P;
|
||
|
|
const b5 = pow2(b4, 1n) * x % P;
|
||
|
|
const b10 = pow2(b5, 5n) * b5 % P;
|
||
|
|
const b20 = pow2(b10, 10n) * b10 % P;
|
||
|
|
const b40 = pow2(b20, 20n) * b20 % P;
|
||
|
|
const b80 = pow2(b40, 40n) * b40 % P;
|
||
|
|
const b160 = pow2(b80, 80n) * b80 % P;
|
||
|
|
const b240 = pow2(b160, 80n) * b80 % P;
|
||
|
|
const b250 = pow2(b240, 10n) * b10 % P;
|
||
|
|
const pow_p_5_8 = pow2(b250, 2n) * x % P;
|
||
|
|
return { pow_p_5_8, b2 };
|
||
|
|
};
|
||
|
|
var RM1 = 19681161376707505956807079304988542015446066515923890162744021073123829784752n;
|
||
|
|
var uvRatio = (u, v) => {
|
||
|
|
const v3 = mod(v * v * v);
|
||
|
|
const v7 = mod(v3 * v3 * v);
|
||
|
|
const pow = pow_2_252_3(u * v7).pow_p_5_8;
|
||
|
|
let x = mod(u * v3 * pow);
|
||
|
|
const vx2 = mod(v * x * x);
|
||
|
|
const root1 = x;
|
||
|
|
const root2 = mod(x * RM1);
|
||
|
|
const useRoot1 = vx2 === u;
|
||
|
|
const useRoot2 = vx2 === mod(-u);
|
||
|
|
const noRoot = vx2 === mod(-u * RM1);
|
||
|
|
if (useRoot1)
|
||
|
|
x = root1;
|
||
|
|
if (useRoot2 || noRoot)
|
||
|
|
x = root2;
|
||
|
|
if ((mod(x) & 1n) === 1n)
|
||
|
|
x = mod(-x);
|
||
|
|
return { isValid: useRoot1 || useRoot2, value: x };
|
||
|
|
};
|
||
|
|
var _shaS;
|
||
|
|
var cr = () => (
|
||
|
|
// We support: 1) browsers 2) node.js 19+
|
||
|
|
typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0
|
||
|
|
);
|
||
|
|
var etc = {
|
||
|
|
bytesToHex: b2h,
|
||
|
|
hexToBytes: h2b,
|
||
|
|
concatBytes: concatB,
|
||
|
|
mod,
|
||
|
|
invert,
|
||
|
|
randomBytes: (len) => {
|
||
|
|
const crypto2 = cr();
|
||
|
|
if (!crypto2)
|
||
|
|
err("crypto.getRandomValues must be defined");
|
||
|
|
return crypto2.getRandomValues(u8n(len));
|
||
|
|
},
|
||
|
|
sha512Async: async (...messages) => {
|
||
|
|
const crypto2 = cr();
|
||
|
|
if (!crypto2)
|
||
|
|
err("crypto.subtle or etc.sha512Async must be defined");
|
||
|
|
const m = concatB(...messages);
|
||
|
|
return u8n(await crypto2.subtle.digest("SHA-512", m.buffer));
|
||
|
|
},
|
||
|
|
sha512Sync: void 0
|
||
|
|
// Actual logic below
|
||
|
|
};
|
||
|
|
Object.defineProperties(etc, { sha512Sync: {
|
||
|
|
configurable: false,
|
||
|
|
get() {
|
||
|
|
return _shaS;
|
||
|
|
},
|
||
|
|
set(f) {
|
||
|
|
if (!_shaS)
|
||
|
|
_shaS = f;
|
||
|
|
}
|
||
|
|
} });
|
||
|
|
var W = 8;
|
||
|
|
var precompute = () => {
|
||
|
|
const points = [];
|
||
|
|
const windows = 256 / W + 1;
|
||
|
|
let p = G, b = p;
|
||
|
|
for (let w = 0; w < windows; w++) {
|
||
|
|
b = p;
|
||
|
|
points.push(b);
|
||
|
|
for (let i = 1; i < 2 ** (W - 1); i++) {
|
||
|
|
b = b.add(p);
|
||
|
|
points.push(b);
|
||
|
|
}
|
||
|
|
p = b.double();
|
||
|
|
}
|
||
|
|
return points;
|
||
|
|
};
|
||
|
|
var wNAF = (n) => {
|
||
|
|
const comp = Gpows || (Gpows = precompute());
|
||
|
|
const neg = (cnd, p2) => {
|
||
|
|
let n2 = p2.negate();
|
||
|
|
return cnd ? n2 : p2;
|
||
|
|
};
|
||
|
|
let p = I, f = G;
|
||
|
|
const windows = 1 + 256 / W;
|
||
|
|
const wsize = 2 ** (W - 1);
|
||
|
|
const mask = BigInt(2 ** W - 1);
|
||
|
|
const maxNum = 2 ** W;
|
||
|
|
const shiftBy = BigInt(W);
|
||
|
|
for (let w = 0; w < windows; w++) {
|
||
|
|
const off = w * wsize;
|
||
|
|
let wbits = Number(n & mask);
|
||
|
|
n >>= shiftBy;
|
||
|
|
if (wbits > wsize) {
|
||
|
|
wbits -= maxNum;
|
||
|
|
n += 1n;
|
||
|
|
}
|
||
|
|
const off1 = off, off2 = off + Math.abs(wbits) - 1;
|
||
|
|
const cnd1 = w % 2 !== 0, cnd2 = wbits < 0;
|
||
|
|
if (wbits === 0) {
|
||
|
|
f = f.add(neg(cnd1, comp[off1]));
|
||
|
|
} else {
|
||
|
|
p = p.add(neg(cnd2, comp[off2]));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return { p, f };
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@noble+secp256k1@2.0.0/node_modules/@noble/secp256k1/index.js
|
||
|
|
var B256 = 2n ** 256n;
|
||
|
|
var P2 = B256 - 0x1000003d1n;
|
||
|
|
var N10 = B256 - 0x14551231950b75fc4402da1732fc9bebfn;
|
||
|
|
var Gx2 = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n;
|
||
|
|
var Gy2 = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n;
|
||
|
|
var CURVE2 = { p: P2, n: N10, a: 0n, b: 7n, Gx: Gx2, Gy: Gy2 };
|
||
|
|
var fLen = 32;
|
||
|
|
var crv = (x) => mod2(mod2(x * x) * x + CURVE2.b);
|
||
|
|
var err2 = (m = "") => {
|
||
|
|
throw new Error(m);
|
||
|
|
};
|
||
|
|
var big = (n) => typeof n === "bigint";
|
||
|
|
var str2 = (s) => typeof s === "string";
|
||
|
|
var fe = (n) => big(n) && 0n < n && n < P2;
|
||
|
|
var ge = (n) => big(n) && 0n < n && n < N10;
|
||
|
|
var au82 = (a, l) => (
|
||
|
|
// is Uint8Array (of specific length)
|
||
|
|
!(a instanceof Uint8Array) || typeof l === "number" && l > 0 && a.length !== l ? err2("Uint8Array expected") : a
|
||
|
|
);
|
||
|
|
var u8n2 = (data) => new Uint8Array(data);
|
||
|
|
var toU82 = (a, len) => au82(str2(a) ? h2b2(a) : u8n2(a), len);
|
||
|
|
var mod2 = (a, b = P2) => {
|
||
|
|
let r = a % b;
|
||
|
|
return r >= 0n ? r : b + r;
|
||
|
|
};
|
||
|
|
var isPoint2 = (p) => p instanceof Point2 ? p : err2("Point expected");
|
||
|
|
var Gpows2 = void 0;
|
||
|
|
var Point2 = class _Point {
|
||
|
|
constructor(px, py, pz) {
|
||
|
|
this.px = px;
|
||
|
|
this.py = py;
|
||
|
|
this.pz = pz;
|
||
|
|
}
|
||
|
|
//3d=less inversions
|
||
|
|
static fromAffine(p) {
|
||
|
|
return new _Point(p.x, p.y, 1n);
|
||
|
|
}
|
||
|
|
static fromHex(hex) {
|
||
|
|
hex = toU82(hex);
|
||
|
|
let p = void 0;
|
||
|
|
const head = hex[0], tail = hex.subarray(1);
|
||
|
|
const x = slcNum(tail, 0, fLen), len = hex.length;
|
||
|
|
if (len === 33 && [2, 3].includes(head)) {
|
||
|
|
if (!fe(x))
|
||
|
|
err2("Point hex invalid: x not FE");
|
||
|
|
let y = sqrt(crv(x));
|
||
|
|
const isYOdd = (y & 1n) === 1n;
|
||
|
|
const headOdd = (head & 1) === 1;
|
||
|
|
if (headOdd !== isYOdd)
|
||
|
|
y = mod2(-y);
|
||
|
|
p = new _Point(x, y, 1n);
|
||
|
|
}
|
||
|
|
if (len === 65 && head === 4)
|
||
|
|
p = new _Point(x, slcNum(tail, fLen, 2 * fLen), 1n);
|
||
|
|
return p ? p.ok() : err2("Point is not on curve");
|
||
|
|
}
|
||
|
|
static fromPrivateKey(k) {
|
||
|
|
return G2.mul(toPriv(k));
|
||
|
|
}
|
||
|
|
// Create point from a private key.
|
||
|
|
get x() {
|
||
|
|
return this.aff().x;
|
||
|
|
}
|
||
|
|
// .x, .y will call expensive toAffine:
|
||
|
|
get y() {
|
||
|
|
return this.aff().y;
|
||
|
|
}
|
||
|
|
// should be used with care.
|
||
|
|
equals(other) {
|
||
|
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
||
|
|
const { px: X2, py: Y2, pz: Z2 } = isPoint2(other);
|
||
|
|
const X1Z2 = mod2(X1 * Z2), X2Z1 = mod2(X2 * Z1);
|
||
|
|
const Y1Z2 = mod2(Y1 * Z2), Y2Z1 = mod2(Y2 * Z1);
|
||
|
|
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
||
|
|
}
|
||
|
|
negate() {
|
||
|
|
return new _Point(this.px, mod2(-this.py), this.pz);
|
||
|
|
}
|
||
|
|
// Flip point over y coord
|
||
|
|
double() {
|
||
|
|
return this.add(this);
|
||
|
|
}
|
||
|
|
// Point doubling: P+P, complete formula.
|
||
|
|
add(other) {
|
||
|
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
||
|
|
const { px: X2, py: Y2, pz: Z2 } = isPoint2(other);
|
||
|
|
const { a, b } = CURVE2;
|
||
|
|
let X3 = 0n, Y3 = 0n, Z3 = 0n;
|
||
|
|
const b3 = mod2(b * 3n);
|
||
|
|
let t0 = mod2(X1 * X2), t1 = mod2(Y1 * Y2), t2 = mod2(Z1 * Z2), t3 = mod2(X1 + Y1);
|
||
|
|
let t4 = mod2(X2 + Y2);
|
||
|
|
t3 = mod2(t3 * t4);
|
||
|
|
t4 = mod2(t0 + t1);
|
||
|
|
t3 = mod2(t3 - t4);
|
||
|
|
t4 = mod2(X1 + Z1);
|
||
|
|
let t5 = mod2(X2 + Z2);
|
||
|
|
t4 = mod2(t4 * t5);
|
||
|
|
t5 = mod2(t0 + t2);
|
||
|
|
t4 = mod2(t4 - t5);
|
||
|
|
t5 = mod2(Y1 + Z1);
|
||
|
|
X3 = mod2(Y2 + Z2);
|
||
|
|
t5 = mod2(t5 * X3);
|
||
|
|
X3 = mod2(t1 + t2);
|
||
|
|
t5 = mod2(t5 - X3);
|
||
|
|
Z3 = mod2(a * t4);
|
||
|
|
X3 = mod2(b3 * t2);
|
||
|
|
Z3 = mod2(X3 + Z3);
|
||
|
|
X3 = mod2(t1 - Z3);
|
||
|
|
Z3 = mod2(t1 + Z3);
|
||
|
|
Y3 = mod2(X3 * Z3);
|
||
|
|
t1 = mod2(t0 + t0);
|
||
|
|
t1 = mod2(t1 + t0);
|
||
|
|
t2 = mod2(a * t2);
|
||
|
|
t4 = mod2(b3 * t4);
|
||
|
|
t1 = mod2(t1 + t2);
|
||
|
|
t2 = mod2(t0 - t2);
|
||
|
|
t2 = mod2(a * t2);
|
||
|
|
t4 = mod2(t4 + t2);
|
||
|
|
t0 = mod2(t1 * t4);
|
||
|
|
Y3 = mod2(Y3 + t0);
|
||
|
|
t0 = mod2(t5 * t4);
|
||
|
|
X3 = mod2(t3 * X3);
|
||
|
|
X3 = mod2(X3 - t0);
|
||
|
|
t0 = mod2(t3 * t1);
|
||
|
|
Z3 = mod2(t5 * Z3);
|
||
|
|
Z3 = mod2(Z3 + t0);
|
||
|
|
return new _Point(X3, Y3, Z3);
|
||
|
|
}
|
||
|
|
mul(n, safe = true) {
|
||
|
|
if (!safe && n === 0n)
|
||
|
|
return I2;
|
||
|
|
if (!ge(n))
|
||
|
|
err2("invalid scalar");
|
||
|
|
if (this.equals(G2))
|
||
|
|
return wNAF2(n).p;
|
||
|
|
let p = I2, f = G2;
|
||
|
|
for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
|
||
|
|
if (n & 1n)
|
||
|
|
p = p.add(d);
|
||
|
|
else if (safe)
|
||
|
|
f = f.add(d);
|
||
|
|
}
|
||
|
|
return p;
|
||
|
|
}
|
||
|
|
mulAddQUns(R, u1, u2) {
|
||
|
|
return this.mul(u1, false).add(R.mul(u2, false)).ok();
|
||
|
|
}
|
||
|
|
// to private keys. Doesn't use Shamir trick
|
||
|
|
toAffine() {
|
||
|
|
const { px: x, py: y, pz: z } = this;
|
||
|
|
if (this.equals(I2))
|
||
|
|
return { x: 0n, y: 0n };
|
||
|
|
if (z === 1n)
|
||
|
|
return { x, y };
|
||
|
|
const iz = inv(z);
|
||
|
|
if (mod2(z * iz) !== 1n)
|
||
|
|
err2("invalid inverse");
|
||
|
|
return { x: mod2(x * iz), y: mod2(y * iz) };
|
||
|
|
}
|
||
|
|
assertValidity() {
|
||
|
|
const { x, y } = this.aff();
|
||
|
|
if (!fe(x) || !fe(y))
|
||
|
|
err2("Point invalid: x or y");
|
||
|
|
return mod2(y * y) === crv(x) ? (
|
||
|
|
// y² = x³ + ax + b, must be equal
|
||
|
|
this
|
||
|
|
) : err2("Point invalid: not on curve");
|
||
|
|
}
|
||
|
|
multiply(n) {
|
||
|
|
return this.mul(n);
|
||
|
|
}
|
||
|
|
// Aliases to compress code
|
||
|
|
aff() {
|
||
|
|
return this.toAffine();
|
||
|
|
}
|
||
|
|
ok() {
|
||
|
|
return this.assertValidity();
|
||
|
|
}
|
||
|
|
toHex(isCompressed = true) {
|
||
|
|
const { x, y } = this.aff();
|
||
|
|
const head = isCompressed ? (y & 1n) === 0n ? "02" : "03" : "04";
|
||
|
|
return head + n2h(x) + (isCompressed ? "" : n2h(y));
|
||
|
|
}
|
||
|
|
toRawBytes(isCompressed = true) {
|
||
|
|
return h2b2(this.toHex(isCompressed));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Point2.BASE = new Point2(Gx2, Gy2, 1n);
|
||
|
|
Point2.ZERO = new Point2(0n, 1n, 0n);
|
||
|
|
var { BASE: G2, ZERO: I2 } = Point2;
|
||
|
|
var padh2 = (n, pad) => n.toString(16).padStart(pad, "0");
|
||
|
|
var b2h2 = (b) => Array.from(b).map((e) => padh2(e, 2)).join("");
|
||
|
|
var h2b2 = (hex) => {
|
||
|
|
const l = hex.length;
|
||
|
|
if (!str2(hex) || l % 2)
|
||
|
|
err2("hex invalid 1");
|
||
|
|
const arr = u8n2(l / 2);
|
||
|
|
for (let i = 0; i < arr.length; i++) {
|
||
|
|
const j = i * 2;
|
||
|
|
const h = hex.slice(j, j + 2);
|
||
|
|
const b = Number.parseInt(h, 16);
|
||
|
|
if (Number.isNaN(b) || b < 0)
|
||
|
|
err2("hex invalid 2");
|
||
|
|
arr[i] = b;
|
||
|
|
}
|
||
|
|
return arr;
|
||
|
|
};
|
||
|
|
var b2n = (b) => BigInt("0x" + (b2h2(b) || "0"));
|
||
|
|
var slcNum = (b, from3, to) => b2n(b.slice(from3, to));
|
||
|
|
var n2b = (num) => {
|
||
|
|
return big(num) && num >= 0n && num < B256 ? h2b2(padh2(num, 2 * fLen)) : err2("bigint expected");
|
||
|
|
};
|
||
|
|
var n2h = (num) => b2h2(n2b(num));
|
||
|
|
var concatB2 = (...arrs) => {
|
||
|
|
const r = u8n2(arrs.reduce((sum, a) => sum + au82(a).length, 0));
|
||
|
|
let pad = 0;
|
||
|
|
arrs.forEach((a) => {
|
||
|
|
r.set(a, pad);
|
||
|
|
pad += a.length;
|
||
|
|
});
|
||
|
|
return r;
|
||
|
|
};
|
||
|
|
var inv = (num, md = P2) => {
|
||
|
|
if (num === 0n || md <= 0n)
|
||
|
|
err2("no inverse n=" + num + " mod=" + md);
|
||
|
|
let a = mod2(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;
|
||
|
|
while (a !== 0n) {
|
||
|
|
const q = b / a, r = b % a;
|
||
|
|
const m = x - u * q, n = y - v * q;
|
||
|
|
b = a, a = r, x = u, y = v, u = m, v = n;
|
||
|
|
}
|
||
|
|
return b === 1n ? mod2(x, md) : err2("no inverse");
|
||
|
|
};
|
||
|
|
var sqrt = (n) => {
|
||
|
|
let r = 1n;
|
||
|
|
for (let num = n, e = (P2 + 1n) / 4n; e > 0n; e >>= 1n) {
|
||
|
|
if (e & 1n)
|
||
|
|
r = r * num % P2;
|
||
|
|
num = num * num % P2;
|
||
|
|
}
|
||
|
|
return mod2(r * r) === n ? r : err2("sqrt invalid");
|
||
|
|
};
|
||
|
|
var toPriv = (p) => {
|
||
|
|
if (!big(p))
|
||
|
|
p = b2n(toU82(p, fLen));
|
||
|
|
return ge(p) ? p : err2("private key out of range");
|
||
|
|
};
|
||
|
|
var cr2 = () => (
|
||
|
|
// We support: 1) browsers 2) node.js 19+ 3) deno, other envs with crypto
|
||
|
|
typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0
|
||
|
|
);
|
||
|
|
var _hmacSync;
|
||
|
|
function hashToPrivateKey(hash) {
|
||
|
|
hash = toU82(hash);
|
||
|
|
const minLen = fLen + 8;
|
||
|
|
if (hash.length < minLen || hash.length > 1024)
|
||
|
|
err2("expected proper params");
|
||
|
|
const num = mod2(b2n(hash), N10 - 1n) + 1n;
|
||
|
|
return n2b(num);
|
||
|
|
}
|
||
|
|
var etc2 = {
|
||
|
|
hexToBytes: h2b2,
|
||
|
|
bytesToHex: b2h2,
|
||
|
|
concatBytes: concatB2,
|
||
|
|
bytesToNumberBE: b2n,
|
||
|
|
numberToBytesBE: n2b,
|
||
|
|
mod: mod2,
|
||
|
|
invert: inv,
|
||
|
|
hmacSha256Async: async (key, ...msgs) => {
|
||
|
|
const crypto2 = cr2();
|
||
|
|
if (!crypto2)
|
||
|
|
return err2("etc.hmacSha256Async not set");
|
||
|
|
const s = crypto2.subtle;
|
||
|
|
const k = await s.importKey("raw", key, { name: "HMAC", hash: { name: "SHA-256" } }, false, ["sign"]);
|
||
|
|
return u8n2(await s.sign("HMAC", k, concatB2(...msgs)));
|
||
|
|
},
|
||
|
|
hmacSha256Sync: _hmacSync,
|
||
|
|
hashToPrivateKey,
|
||
|
|
randomBytes: (len) => {
|
||
|
|
const crypto2 = cr2();
|
||
|
|
if (!crypto2)
|
||
|
|
err2("crypto.getRandomValues must be defined");
|
||
|
|
return crypto2.getRandomValues(u8n2(len));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Object.defineProperties(etc2, { hmacSha256Sync: {
|
||
|
|
configurable: false,
|
||
|
|
get() {
|
||
|
|
return _hmacSync;
|
||
|
|
},
|
||
|
|
set(f) {
|
||
|
|
if (!_hmacSync)
|
||
|
|
_hmacSync = f;
|
||
|
|
}
|
||
|
|
} });
|
||
|
|
var W2 = 8;
|
||
|
|
var precompute2 = () => {
|
||
|
|
const points = [];
|
||
|
|
const windows = 256 / W2 + 1;
|
||
|
|
let p = G2, b = p;
|
||
|
|
for (let w = 0; w < windows; w++) {
|
||
|
|
b = p;
|
||
|
|
points.push(b);
|
||
|
|
for (let i = 1; i < 2 ** (W2 - 1); i++) {
|
||
|
|
b = b.add(p);
|
||
|
|
points.push(b);
|
||
|
|
}
|
||
|
|
p = b.double();
|
||
|
|
}
|
||
|
|
return points;
|
||
|
|
};
|
||
|
|
var wNAF2 = (n) => {
|
||
|
|
const comp = Gpows2 || (Gpows2 = precompute2());
|
||
|
|
const neg = (cnd, p2) => {
|
||
|
|
let n2 = p2.negate();
|
||
|
|
return cnd ? n2 : p2;
|
||
|
|
};
|
||
|
|
let p = I2, f = G2;
|
||
|
|
const windows = 1 + 256 / W2;
|
||
|
|
const wsize = 2 ** (W2 - 1);
|
||
|
|
const mask = BigInt(2 ** W2 - 1);
|
||
|
|
const maxNum = 2 ** W2;
|
||
|
|
const shiftBy = BigInt(W2);
|
||
|
|
for (let w = 0; w < windows; w++) {
|
||
|
|
const off = w * wsize;
|
||
|
|
let wbits = Number(n & mask);
|
||
|
|
n >>= shiftBy;
|
||
|
|
if (wbits > wsize) {
|
||
|
|
wbits -= maxNum;
|
||
|
|
n += 1n;
|
||
|
|
}
|
||
|
|
const off1 = off, off2 = off + Math.abs(wbits) - 1;
|
||
|
|
const cnd1 = w % 2 !== 0, cnd2 = wbits < 0;
|
||
|
|
if (wbits === 0) {
|
||
|
|
f = f.add(neg(cnd1, comp[off1]));
|
||
|
|
} else {
|
||
|
|
p = p.add(neg(cnd2, comp[off2]));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return { p, f };
|
||
|
|
};
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/enums/IonNetwork.js
|
||
|
|
var IonNetwork;
|
||
|
|
(function(IonNetwork2) {
|
||
|
|
IonNetwork2["Mainnet"] = "mainnet";
|
||
|
|
IonNetwork2["Testnet"] = "test";
|
||
|
|
})(IonNetwork || (IonNetwork = {}));
|
||
|
|
|
||
|
|
// ../../node_modules/.pnpm/@decentralized-identity+ion-sdk@1.0.4/node_modules/@decentralized-identity/ion-sdk/dist/lib/enums/IonPublicKeyPurpose.js
|
||
|
|
var IonPublicKeyPurpose;
|
||
|
|
(function(IonPublicKeyPurpose2) {
|
||
|
|
IonPublicKeyPurpose2["Authentication"] = "authentication";
|
||
|
|
IonPublicKeyPurpose2["AssertionMethod"] = "assertionMethod";
|
||
|
|
IonPublicKeyPurpose2["CapabilityInvocation"] = "capabilityInvocation";
|
||
|
|
IonPublicKeyPurpose2["CapabilityDelegation"] = "capabilityDelegation";
|
||
|
|
IonPublicKeyPurpose2["KeyAgreement"] = "keyAgreement";
|
||
|
|
})(IonPublicKeyPurpose || (IonPublicKeyPurpose = {}));
|
||
|
|
|
||
|
|
// dist/esm/methods/did-ion.js
|
||
|
|
var import_crypto5 = require("@web5/crypto");
|
||
|
|
var __awaiter8 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidIonRegisteredKeyType;
|
||
|
|
(function(DidIonRegisteredKeyType2) {
|
||
|
|
DidIonRegisteredKeyType2["Ed25519"] = "Ed25519";
|
||
|
|
DidIonRegisteredKeyType2["secp256k1"] = "secp256k1";
|
||
|
|
DidIonRegisteredKeyType2["secp256r1"] = "secp256r1";
|
||
|
|
DidIonRegisteredKeyType2["X25519"] = "X25519";
|
||
|
|
})(DidIonRegisteredKeyType || (DidIonRegisteredKeyType = {}));
|
||
|
|
var AlgorithmToKeyTypeMap2 = {
|
||
|
|
Ed25519: DidIonRegisteredKeyType.Ed25519,
|
||
|
|
ES256K: DidIonRegisteredKeyType.secp256k1,
|
||
|
|
ES256: DidIonRegisteredKeyType.secp256r1,
|
||
|
|
"P-256": DidIonRegisteredKeyType.secp256r1,
|
||
|
|
secp256k1: DidIonRegisteredKeyType.secp256k1,
|
||
|
|
secp256r1: DidIonRegisteredKeyType.secp256r1
|
||
|
|
};
|
||
|
|
var DEFAULT_GATEWAY_URI2 = "https://ion.tbd.engineering";
|
||
|
|
var DidIon = class _DidIon extends DidMethod {
|
||
|
|
/**
|
||
|
|
* Creates a new DID using the `did:ion` method formed from a newly generated key.
|
||
|
|
*
|
||
|
|
* Notes:
|
||
|
|
* - If no `options` are given, by default a new Ed25519 key will be generated.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // DID Creation
|
||
|
|
* const did = await DidIon.create();
|
||
|
|
*
|
||
|
|
* // DID Creation with a KMS
|
||
|
|
* const keyManager = new LocalKeyManager();
|
||
|
|
* const did = await DidIon.create({ keyManager });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the create operation.
|
||
|
|
* @param params.keyManager - Optionally specify a Key Management System (KMS) used to generate
|
||
|
|
* keys and sign data.
|
||
|
|
* @param params.options - Optional parameters that can be specified when creating a new DID.
|
||
|
|
* @returns A Promise resolving to a {@link BearerDid} object representing the new DID.
|
||
|
|
*/
|
||
|
|
static create() {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ keyManager = new import_crypto5.LocalKeyManager(), options = {} } = {}) {
|
||
|
|
var _a, _b, _c, _d, _e, _f, _g;
|
||
|
|
if ((_a = options.verificationMethods) === null || _a === void 0 ? void 0 : _a.some((vm) => !(vm.algorithm in AlgorithmToKeyTypeMap2))) {
|
||
|
|
throw new Error("One or more verification method algorithms are not supported");
|
||
|
|
}
|
||
|
|
const methodIds = (_b = options.verificationMethods) === null || _b === void 0 ? void 0 : _b.filter((vm) => "id" in vm).map((vm) => vm.id);
|
||
|
|
if (methodIds && methodIds.length !== new Set(methodIds).size) {
|
||
|
|
throw new Error("One or more verification method IDs are not unique");
|
||
|
|
}
|
||
|
|
if ((_c = options.services) === null || _c === void 0 ? void 0 : _c.some((s) => !s.id || !s.type || !s.serviceEndpoint)) {
|
||
|
|
throw new Error("One or more services are missing required properties");
|
||
|
|
}
|
||
|
|
const defaultVerificationMethod = {
|
||
|
|
algorithm: "Ed25519",
|
||
|
|
purposes: ["authentication", "assertionMethod", "capabilityDelegation", "capabilityInvocation"]
|
||
|
|
};
|
||
|
|
const verificationMethodsToAdd = [];
|
||
|
|
for (const vm of (_d = options.verificationMethods) !== null && _d !== void 0 ? _d : [defaultVerificationMethod]) {
|
||
|
|
const keyUri = yield keyManager.generateKey({ algorithm: vm.algorithm });
|
||
|
|
const publicKey = yield keyManager.getPublicKey({ keyUri });
|
||
|
|
verificationMethodsToAdd.push({
|
||
|
|
id: vm.id,
|
||
|
|
publicKeyJwk: publicKey,
|
||
|
|
purposes: (_e = vm.purposes) !== null && _e !== void 0 ? _e : ["authentication", "assertionMethod", "capabilityDelegation", "capabilityInvocation"]
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const recoveryKeyUri = yield keyManager.generateKey({ algorithm: DidIonRegisteredKeyType.secp256k1 });
|
||
|
|
const recoveryKey = yield keyManager.getPublicKey({ keyUri: recoveryKeyUri });
|
||
|
|
const updateKeyUri = yield keyManager.generateKey({ algorithm: DidIonRegisteredKeyType.secp256k1 });
|
||
|
|
const updateKey = yield keyManager.getPublicKey({ keyUri: updateKeyUri });
|
||
|
|
const longFormDidUri = yield DidIonUtils.computeLongFormDidUri({
|
||
|
|
recoveryKey,
|
||
|
|
updateKey,
|
||
|
|
services: (_f = options.services) !== null && _f !== void 0 ? _f : [],
|
||
|
|
verificationMethods: verificationMethodsToAdd
|
||
|
|
});
|
||
|
|
const { didDocument, didResolutionMetadata } = yield _DidIon.resolve(longFormDidUri, { gatewayUri: options.gatewayUri });
|
||
|
|
if (didDocument === null) {
|
||
|
|
throw new Error(`Unable to resolve DID during creation: ${didResolutionMetadata === null || didResolutionMetadata === void 0 ? void 0 : didResolutionMetadata.error}`);
|
||
|
|
}
|
||
|
|
const did = new BearerDid({
|
||
|
|
uri: longFormDidUri,
|
||
|
|
document: didDocument,
|
||
|
|
metadata: {
|
||
|
|
published: false,
|
||
|
|
canonicalId: longFormDidUri.split(":", 3).join(":"),
|
||
|
|
recoveryKey,
|
||
|
|
updateKey
|
||
|
|
},
|
||
|
|
keyManager
|
||
|
|
});
|
||
|
|
if ((_g = options.publish) !== null && _g !== void 0 ? _g : true) {
|
||
|
|
const registrationResult = yield _DidIon.publish({ did, gatewayUri: options.gatewayUri });
|
||
|
|
did.metadata = registrationResult.didDocumentMetadata;
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Given the W3C DID Document of a `did:ion` DID, return the verification method that will be used
|
||
|
|
* for signing messages and credentials. If given, the `methodId` parameter is used to select the
|
||
|
|
* verification method. If not given, the first verification method in the authentication property
|
||
|
|
* in the DID Document is used.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `getSigningMethod` operation.
|
||
|
|
* @param params.didDocument - DID Document to get the verification method from.
|
||
|
|
* @param params.methodId - ID of the verification method to use for signing.
|
||
|
|
* @returns Verification method to use for signing.
|
||
|
|
*/
|
||
|
|
static getSigningMethod(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ didDocument, methodId }) {
|
||
|
|
var _b;
|
||
|
|
const parsedDid = Did.parse(didDocument.id);
|
||
|
|
if (parsedDid && parsedDid.method !== this.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
const verificationMethod = (_b = didDocument.verificationMethod) === null || _b === void 0 ? void 0 : _b.find((vm) => {
|
||
|
|
var _a2;
|
||
|
|
return vm.id === (methodId !== null && methodId !== void 0 ? methodId : (_a2 = didDocument.assertionMethod) === null || _a2 === void 0 ? void 0 : _a2[0]);
|
||
|
|
});
|
||
|
|
if (!(verificationMethod && verificationMethod.publicKeyJwk)) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "A verification method intended for signing could not be determined from the DID Document");
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Instantiates a {@link BearerDid} object for the DID ION method from a given {@link PortableDid}.
|
||
|
|
*
|
||
|
|
* This method allows for the creation of a `BearerDid` object using a previously created DID's
|
||
|
|
* key material, DID document, and metadata.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Export an existing BearerDid to PortableDid format.
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // Reconstruct a BearerDid object from the PortableDid.
|
||
|
|
* const did = await DidIon.import({ portableDid });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the import operation.
|
||
|
|
* @param params.portableDid - The PortableDid object to import.
|
||
|
|
* @param params.keyManager - Optionally specify an external Key Management System (KMS) used to
|
||
|
|
* generate keys and sign data. If not given, a new
|
||
|
|
* {@link LocalKeyManager} instance will be created and
|
||
|
|
* used.
|
||
|
|
* @returns A Promise resolving to a `BearerDid` object representing the DID formed from the
|
||
|
|
* provided PortableDid.
|
||
|
|
* @throws An error if the DID document does not contain any verification methods or the keys for
|
||
|
|
* any verification method are missing in the key manager.
|
||
|
|
*/
|
||
|
|
static import(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ portableDid, keyManager = new import_crypto5.LocalKeyManager() }) {
|
||
|
|
const parsedDid = Did.parse(portableDid.uri);
|
||
|
|
if ((parsedDid === null || parsedDid === void 0 ? void 0 : parsedDid.method) !== _DidIon.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported`);
|
||
|
|
}
|
||
|
|
const did = yield BearerDid.import({ portableDid, keyManager });
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Publishes a DID to a Sidetree node, making it publicly discoverable and resolvable.
|
||
|
|
*
|
||
|
|
* This method handles the publication of a DID Document associated with a `did:ion` DID to a
|
||
|
|
* Sidetree node.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* - This method is typically invoked automatically during the creation of a new DID unless the
|
||
|
|
* `publish` option is set to `false`.
|
||
|
|
* - For existing, unpublished DIDs, it can be used to publish the DID Document to a Sidetree node.
|
||
|
|
* - The method relies on the specified Sidetree node to interface with the network.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `publish` operation.
|
||
|
|
* @param params.did - The `BearerDid` object representing the DID to be published.
|
||
|
|
* @param params.gatewayUri - Optional. The URI of a server involved in executing DID
|
||
|
|
* method operations. In the context of publishing, the
|
||
|
|
* endpoint is expected to be a Sidetree node. If not
|
||
|
|
* specified, a default node is used.
|
||
|
|
* @returns A Promise resolving to a boolean indicating whether the publication was successful.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Generate a new DID and keys but explicitly disable publishing.
|
||
|
|
* const did = await DidIon.create({ options: { publish: false } });
|
||
|
|
* // Publish the DID to the Sidetree network.
|
||
|
|
* const isPublished = await DidIon.publish({ did });
|
||
|
|
* // `isPublished` is true if the DID was successfully published.
|
||
|
|
* ```
|
||
|
|
*/
|
||
|
|
static publish(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ did, gatewayUri = DEFAULT_GATEWAY_URI2 }) {
|
||
|
|
var _b, _c, _d;
|
||
|
|
const verificationMethods = (_c = (_b = did.document.verificationMethod) === null || _b === void 0 ? void 0 : _b.map((vm) => ({
|
||
|
|
id: vm.id,
|
||
|
|
publicKeyJwk: vm.publicKeyJwk,
|
||
|
|
purposes: getVerificationRelationshipsById({ didDocument: did.document, methodId: vm.id })
|
||
|
|
}))) !== null && _c !== void 0 ? _c : [];
|
||
|
|
const ionDocument = yield DidIonUtils.createIonDocument({
|
||
|
|
services: (_d = did.document.service) !== null && _d !== void 0 ? _d : [],
|
||
|
|
verificationMethods
|
||
|
|
});
|
||
|
|
const createOperation = yield DidIonUtils.constructCreateRequest({
|
||
|
|
ionDocument,
|
||
|
|
recoveryKey: did.metadata.recoveryKey,
|
||
|
|
updateKey: did.metadata.updateKey
|
||
|
|
});
|
||
|
|
try {
|
||
|
|
const operationsUrl = DidIonUtils.appendPathToUrl({
|
||
|
|
baseUrl: gatewayUri,
|
||
|
|
path: `/operations`
|
||
|
|
});
|
||
|
|
const response = yield fetch(operationsUrl, {
|
||
|
|
method: "POST",
|
||
|
|
mode: "cors",
|
||
|
|
headers: { "Content-Type": "application/json" },
|
||
|
|
body: JSON.stringify(createOperation)
|
||
|
|
});
|
||
|
|
return {
|
||
|
|
didDocument: did.document,
|
||
|
|
didDocumentMetadata: Object.assign(Object.assign({}, did.metadata), { published: response.ok }),
|
||
|
|
didRegistrationMetadata: {}
|
||
|
|
};
|
||
|
|
} catch (error) {
|
||
|
|
return {
|
||
|
|
didDocument: null,
|
||
|
|
didDocumentMetadata: {
|
||
|
|
published: false
|
||
|
|
},
|
||
|
|
didRegistrationMetadata: {
|
||
|
|
error: DidErrorCode.InternalError,
|
||
|
|
errorMessage: `Failed to publish DID document for: ${did.uri}`
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Resolves a `did:ion` identifier to its corresponding DID document.
|
||
|
|
*
|
||
|
|
* This method performs the resolution of a `did:ion` DID, retrieving its DID Document from the
|
||
|
|
* Sidetree-based DID overlay network. The process involves querying a Sidetree node to retrieve
|
||
|
|
* the DID Document that corresponds to the given DID identifier.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* - If a `gatewayUri` option is not specified, a default node is used to access the Sidetree
|
||
|
|
* network.
|
||
|
|
* - It decodes the DID identifier and retrieves the associated DID Document and metadata.
|
||
|
|
* - In case of resolution failure, appropriate error information is returned.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const resolutionResult = await DidIon.resolve('did:ion:example');
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param didUri - The DID to be resolved.
|
||
|
|
* @param options - Optional parameters for resolving the DID. Unused by this DID method.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(didUri_1) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* (didUri, options = {}) {
|
||
|
|
var _a, _b;
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
if (!parsedDid) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "invalidDid" } });
|
||
|
|
}
|
||
|
|
if (parsedDid.method !== _DidIon.methodName) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "methodNotSupported" } });
|
||
|
|
}
|
||
|
|
const gatewayUri = (_a = options === null || options === void 0 ? void 0 : options.gatewayUri) !== null && _a !== void 0 ? _a : DEFAULT_GATEWAY_URI2;
|
||
|
|
try {
|
||
|
|
const resolutionUrl = DidIonUtils.appendPathToUrl({
|
||
|
|
baseUrl: gatewayUri,
|
||
|
|
path: `/identifiers/${didUri}`
|
||
|
|
});
|
||
|
|
const response = yield fetch(resolutionUrl);
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new DidError(DidErrorCode.NotFound, `Unable to find DID document for: ${didUri}`);
|
||
|
|
}
|
||
|
|
const { didDocument, didDocumentMetadata } = yield response.json();
|
||
|
|
return Object.assign(Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), didDocument && { didDocument }), { didDocumentMetadata: Object.assign({ published: (_b = didDocumentMetadata === null || didDocumentMetadata === void 0 ? void 0 : didDocumentMetadata.method) === null || _b === void 0 ? void 0 : _b.published }, didDocumentMetadata) });
|
||
|
|
} catch (error) {
|
||
|
|
if (!(error instanceof DidError))
|
||
|
|
throw new Error(error);
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: Object.assign({ error: error.code }, error.message && { errorMessage: error.message }) });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidIon.methodName = "ion";
|
||
|
|
var DidIonUtils = class _DidIonUtils {
|
||
|
|
/**
|
||
|
|
* Appends a specified path to a base URL, ensuring proper formatting of the resulting URL.
|
||
|
|
*
|
||
|
|
* This method is useful for constructing URLs for accessing various endpoints, such as Sidetree
|
||
|
|
* nodes in the ION network. It handles the nuances of URL path concatenation, including the
|
||
|
|
* addition or removal of leading/trailing slashes, to create a well-formed URL.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for URL construction.
|
||
|
|
* @param params.baseUrl - The base URL to which the path will be appended.
|
||
|
|
* @param params.path - The path to append to the base URL.
|
||
|
|
* @returns The fully constructed URL string with the path appended to the base URL.
|
||
|
|
*/
|
||
|
|
static appendPathToUrl({ baseUrl, path }) {
|
||
|
|
const url = new URL(baseUrl);
|
||
|
|
url.pathname = url.pathname.endsWith("/") ? url.pathname : url.pathname + "/";
|
||
|
|
url.pathname += path.startsWith("/") ? path.substring(1) : path;
|
||
|
|
return url.toString();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Computes the Long Form DID URI given an ION DID's recovery key, update key, services, and
|
||
|
|
* verification methods.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for computing the Long Form DID URI.
|
||
|
|
* @param params.recoveryKey - The ION Recovery Key.
|
||
|
|
* @param params.updateKey - The ION Update Key.
|
||
|
|
* @param params.services - An array of services associated with the DID.
|
||
|
|
* @param params.verificationMethods - An array of verification methods associated with the DID.
|
||
|
|
* @returns A Promise resolving to the Long Form DID URI.
|
||
|
|
*/
|
||
|
|
static computeLongFormDidUri(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ recoveryKey, updateKey, services, verificationMethods }) {
|
||
|
|
const ionDocument = yield _DidIonUtils.createIonDocument({ services, verificationMethods });
|
||
|
|
const normalizedRecoveryKey = _DidIonUtils.normalizeJwk(recoveryKey);
|
||
|
|
const normalizedUpdateKey = _DidIonUtils.normalizeJwk(updateKey);
|
||
|
|
const longFormDidUri = yield IonDid.createLongFormDid({
|
||
|
|
document: ionDocument,
|
||
|
|
recoveryKey: normalizedRecoveryKey,
|
||
|
|
updateKey: normalizedUpdateKey
|
||
|
|
});
|
||
|
|
return longFormDidUri;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Constructs a Sidetree Create Operation request for a DID document within the ION network.
|
||
|
|
*
|
||
|
|
* This method prepares the necessary payload for submitting a Create Operation to a Sidetree
|
||
|
|
* node, encapsulating the details of the DID document, recovery key, and update key.
|
||
|
|
*
|
||
|
|
* @param params - Parameters required to construct the Create Operation request.
|
||
|
|
* @param params.ionDocument - The DID document model containing public keys and service endpoints.
|
||
|
|
* @param params.recoveryKey - The recovery public key in JWK format.
|
||
|
|
* @param params.updateKey - The update public key in JWK format.
|
||
|
|
* @returns A promise resolving to the ION Create Operation request model, ready for submission to a Sidetree node.
|
||
|
|
*/
|
||
|
|
static constructCreateRequest(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ ionDocument, recoveryKey, updateKey }) {
|
||
|
|
const createRequest = yield IonRequest.createCreateRequest({
|
||
|
|
document: ionDocument,
|
||
|
|
recoveryKey: _DidIonUtils.normalizeJwk(recoveryKey),
|
||
|
|
updateKey: _DidIonUtils.normalizeJwk(updateKey)
|
||
|
|
});
|
||
|
|
return createRequest;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Assembles an ION document model from provided services and verification methods
|
||
|
|
*
|
||
|
|
* This model serves as the foundation for a DID document in the ION network, facilitating the
|
||
|
|
* creation and management of decentralized identities. It translates service endpoints and
|
||
|
|
* public keys into a format compatible with the Sidetree protocol, ensuring the resulting DID
|
||
|
|
* document adheres to the required specifications for ION DIDs. This method is essential for
|
||
|
|
* constructing the payload needed to register or update DIDs within the ION network.
|
||
|
|
*
|
||
|
|
* @param params - The parameters containing the services and verification methods to include in the ION document.
|
||
|
|
* @param params.services - A list of service endpoints to be included in the DID document, specifying ways to interact with the DID subject.
|
||
|
|
* @param params.verificationMethods - A list of verification methods to be included, detailing the cryptographic keys and their intended uses within the DID document.
|
||
|
|
* @returns A Promise resolving to an `IonDocumentModel`, ready for use in Sidetree operations like DID creation and updates.
|
||
|
|
*/
|
||
|
|
static createIonDocument(_a) {
|
||
|
|
return __awaiter8(this, arguments, void 0, function* ({ services, verificationMethods }) {
|
||
|
|
var _b, _c;
|
||
|
|
const ionPublicKeys = [];
|
||
|
|
for (const vm of verificationMethods) {
|
||
|
|
let methodId = (_c = (_b = vm.id) !== null && _b !== void 0 ? _b : vm.publicKeyJwk.kid) !== null && _c !== void 0 ? _c : yield (0, import_crypto5.computeJwkThumbprint)({ jwk: vm.publicKeyJwk });
|
||
|
|
methodId = `${methodId.split("#").pop()}`;
|
||
|
|
const publicKey = {
|
||
|
|
id: methodId,
|
||
|
|
publicKeyJwk: _DidIonUtils.normalizeJwk(vm.publicKeyJwk),
|
||
|
|
purposes: vm.purposes,
|
||
|
|
type: "JsonWebKey2020"
|
||
|
|
};
|
||
|
|
ionPublicKeys.push(publicKey);
|
||
|
|
}
|
||
|
|
const ionServices = services.map((service) => Object.assign(Object.assign({}, service), {
|
||
|
|
id: `${service.id.split("#").pop()}`
|
||
|
|
// Remove fragment prefix, if any.
|
||
|
|
}));
|
||
|
|
const ionDocumentModel = {
|
||
|
|
publicKeys: ionPublicKeys,
|
||
|
|
services: ionServices
|
||
|
|
};
|
||
|
|
return ionDocumentModel;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Normalize the given JWK to include only specific members and in lexicographic order.
|
||
|
|
*
|
||
|
|
* @param jwk - The JWK to normalize.
|
||
|
|
* @returns The normalized JWK.
|
||
|
|
*/
|
||
|
|
static normalizeJwk(jwk) {
|
||
|
|
const keyType = jwk.kty;
|
||
|
|
let normalizedJwk;
|
||
|
|
if (keyType === "EC") {
|
||
|
|
normalizedJwk = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
|
||
|
|
} else if (keyType === "oct") {
|
||
|
|
normalizedJwk = { k: jwk.k, kty: jwk.kty };
|
||
|
|
} else if (keyType === "OKP") {
|
||
|
|
normalizedJwk = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
|
||
|
|
} else if (keyType === "RSA") {
|
||
|
|
normalizedJwk = { e: jwk.e, kty: jwk.kty, n: jwk.n };
|
||
|
|
} else {
|
||
|
|
throw new Error(`Unsupported key type: ${keyType}`);
|
||
|
|
}
|
||
|
|
return normalizedJwk;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/methods/did-jwk.js
|
||
|
|
var import_common3 = require("@web5/common");
|
||
|
|
var import_crypto6 = require("@web5/crypto");
|
||
|
|
var __awaiter9 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidJwk = class _DidJwk extends DidMethod {
|
||
|
|
/**
|
||
|
|
* Creates a new DID using the `did:jwk` method formed from a newly generated key.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* The DID URI is formed by Base64URL-encoding the JWK and prefixing with `did:jwk:`.
|
||
|
|
*
|
||
|
|
* Notes:
|
||
|
|
* - If no `options` are given, by default a new Ed25519 key will be generated.
|
||
|
|
* - The `algorithm` and `verificationMethods` options are mutually exclusive. If both are given,
|
||
|
|
* an error will be thrown.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // DID Creation
|
||
|
|
* const did = await DidJwk.create();
|
||
|
|
*
|
||
|
|
* // DID Creation with a KMS
|
||
|
|
* const keyManager = new LocalKeyManager();
|
||
|
|
* const did = await DidJwk.create({ keyManager });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the create operation.
|
||
|
|
* @param params.keyManager - Optionally specify a Key Management System (KMS) used to generate
|
||
|
|
* keys and sign data.
|
||
|
|
* @param params.options - Optional parameters that can be specified when creating a new DID.
|
||
|
|
* @returns A Promise resolving to a {@link BearerDid} object representing the new DID.
|
||
|
|
*/
|
||
|
|
static create() {
|
||
|
|
return __awaiter9(this, arguments, void 0, function* ({ keyManager = new import_crypto6.LocalKeyManager(), options = {} } = {}) {
|
||
|
|
var _a, _b, _c, _d;
|
||
|
|
if (options.algorithm && options.verificationMethods) {
|
||
|
|
throw new Error(`The 'algorithm' and 'verificationMethods' options are mutually exclusive`);
|
||
|
|
}
|
||
|
|
if (options.verificationMethods && options.verificationMethods.length !== 1) {
|
||
|
|
throw new Error(`The 'verificationMethods' option must contain exactly one entry`);
|
||
|
|
}
|
||
|
|
const algorithm = (_d = (_a = options.algorithm) !== null && _a !== void 0 ? _a : (_c = (_b = options.verificationMethods) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.algorithm) !== null && _d !== void 0 ? _d : "Ed25519";
|
||
|
|
const keyUri = yield keyManager.generateKey({ algorithm });
|
||
|
|
const publicKey = yield keyManager.getPublicKey({ keyUri });
|
||
|
|
const identifier = import_common3.Convert.object(publicKey).toBase64Url();
|
||
|
|
const didUri = `did:${_DidJwk.methodName}:${identifier}`;
|
||
|
|
const didResolutionResult = yield _DidJwk.resolve(didUri);
|
||
|
|
const document = didResolutionResult.didDocument;
|
||
|
|
const did = new BearerDid({
|
||
|
|
uri: didUri,
|
||
|
|
document,
|
||
|
|
metadata: {},
|
||
|
|
keyManager
|
||
|
|
});
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Given the W3C DID Document of a `did:jwk` DID, return the verification method that will be used
|
||
|
|
* for signing messages and credentials. If given, the `methodId` parameter is used to select the
|
||
|
|
* verification method. If not given, the first verification method in the DID Document is used.
|
||
|
|
*
|
||
|
|
* Note that for DID JWK, only one verification method can exist so specifying `methodId` could be
|
||
|
|
* considered redundant or unnecessary. The option is provided for consistency with other DID
|
||
|
|
* method implementations.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `getSigningMethod` operation.
|
||
|
|
* @param params.didDocument - DID Document to get the verification method from.
|
||
|
|
* @param params.methodId - ID of the verification method to use for signing.
|
||
|
|
* @returns Verification method to use for signing.
|
||
|
|
*/
|
||
|
|
static getSigningMethod(_a) {
|
||
|
|
return __awaiter9(this, arguments, void 0, function* ({ didDocument }) {
|
||
|
|
var _b;
|
||
|
|
const parsedDid = Did.parse(didDocument.id);
|
||
|
|
if (parsedDid && parsedDid.method !== this.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
const [verificationMethod] = (_b = didDocument.verificationMethod) !== null && _b !== void 0 ? _b : [];
|
||
|
|
if (!(verificationMethod && verificationMethod.publicKeyJwk)) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "A verification method intended for signing could not be determined from the DID Document");
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Instantiates a {@link BearerDid} object for the DID JWK method from a given {@link PortableDid}.
|
||
|
|
*
|
||
|
|
* This method allows for the creation of a `BearerDid` object using a previously created DID's
|
||
|
|
* key material, DID document, and metadata.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* The `verificationMethod` array of the DID document must contain exactly one key since the
|
||
|
|
* `did:jwk` method only supports a single verification method.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Export an existing BearerDid to PortableDid format.
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // Reconstruct a BearerDid object from the PortableDid.
|
||
|
|
* const did = await DidJwk.import({ portableDid });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the import operation.
|
||
|
|
* @param params.portableDid - The PortableDid object to import.
|
||
|
|
* @param params.keyManager - Optionally specify an external Key Management System (KMS) used to
|
||
|
|
* generate keys and sign data. If not given, a new
|
||
|
|
* {@link LocalKeyManager} instance will be created and
|
||
|
|
* used.
|
||
|
|
* @returns A Promise resolving to a `BearerDid` object representing the DID formed from the provided keys.
|
||
|
|
* @throws An error if the DID document does not contain exactly one verification method.
|
||
|
|
*/
|
||
|
|
static import(_a) {
|
||
|
|
return __awaiter9(this, arguments, void 0, function* ({ portableDid, keyManager = new import_crypto6.LocalKeyManager() }) {
|
||
|
|
const parsedDid = Did.parse(portableDid.uri);
|
||
|
|
if ((parsedDid === null || parsedDid === void 0 ? void 0 : parsedDid.method) !== _DidJwk.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported`);
|
||
|
|
}
|
||
|
|
const did = yield BearerDid.import({ portableDid, keyManager });
|
||
|
|
if (did.document.verificationMethod.length !== 1) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocument, `DID document must contain exactly one verification method`);
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Resolves a `did:jwk` identifier to a DID Document.
|
||
|
|
*
|
||
|
|
* @param didUri - The DID to be resolved.
|
||
|
|
* @param _options - Optional parameters for resolving the DID. Unused by this DID method.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(didUri, _options) {
|
||
|
|
return __awaiter9(this, void 0, void 0, function* () {
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
let publicKey;
|
||
|
|
try {
|
||
|
|
publicKey = import_common3.Convert.base64Url(parsedDid.id).toObject();
|
||
|
|
} catch (_a) {
|
||
|
|
}
|
||
|
|
if (!parsedDid || !publicKey) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "invalidDid" } });
|
||
|
|
}
|
||
|
|
if (parsedDid.method !== _DidJwk.methodName) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "methodNotSupported" } });
|
||
|
|
}
|
||
|
|
const didDocument = {
|
||
|
|
"@context": [
|
||
|
|
"https://www.w3.org/ns/did/v1"
|
||
|
|
],
|
||
|
|
id: parsedDid.uri
|
||
|
|
};
|
||
|
|
const keyUri = `${didDocument.id}#0`;
|
||
|
|
didDocument.verificationMethod = [{
|
||
|
|
id: keyUri,
|
||
|
|
type: "JsonWebKey",
|
||
|
|
controller: didDocument.id,
|
||
|
|
publicKeyJwk: publicKey
|
||
|
|
}];
|
||
|
|
didDocument.authentication = [keyUri];
|
||
|
|
didDocument.assertionMethod = [keyUri];
|
||
|
|
didDocument.capabilityInvocation = [keyUri];
|
||
|
|
didDocument.capabilityDelegation = [keyUri];
|
||
|
|
didDocument.keyAgreement = [keyUri];
|
||
|
|
switch (publicKey.use) {
|
||
|
|
case "sig": {
|
||
|
|
delete didDocument.keyAgreement;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "enc": {
|
||
|
|
delete didDocument.authentication;
|
||
|
|
delete didDocument.assertionMethod;
|
||
|
|
delete didDocument.capabilityInvocation;
|
||
|
|
delete didDocument.capabilityDelegation;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didDocument });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidJwk.methodName = "jwk";
|
||
|
|
|
||
|
|
// dist/esm/methods/did-key.js
|
||
|
|
var import_common4 = require("@web5/common");
|
||
|
|
var import_crypto7 = require("@web5/crypto");
|
||
|
|
var __awaiter10 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidKeyRegisteredKeyType;
|
||
|
|
(function(DidKeyRegisteredKeyType2) {
|
||
|
|
DidKeyRegisteredKeyType2["Ed25519"] = "Ed25519";
|
||
|
|
DidKeyRegisteredKeyType2["secp256k1"] = "secp256k1";
|
||
|
|
DidKeyRegisteredKeyType2["secp256r1"] = "secp256r1";
|
||
|
|
DidKeyRegisteredKeyType2["X25519"] = "X25519";
|
||
|
|
})(DidKeyRegisteredKeyType || (DidKeyRegisteredKeyType = {}));
|
||
|
|
var DidKeyVerificationMethodType = {
|
||
|
|
/** Represents an Ed25519 public key used for digital signatures. */
|
||
|
|
Ed25519VerificationKey2020: "https://w3id.org/security/suites/ed25519-2020/v1",
|
||
|
|
/** Represents a JSON Web Key (JWK) used for digital signatures and key agreement protocols. */
|
||
|
|
JsonWebKey2020: "https://w3id.org/security/suites/jws-2020/v1",
|
||
|
|
/** Represents an X25519 public key used for key agreement protocols. */
|
||
|
|
X25519KeyAgreementKey2020: "https://w3id.org/security/suites/x25519-2020/v1"
|
||
|
|
};
|
||
|
|
var AlgorithmToKeyTypeMap3 = {
|
||
|
|
Ed25519: DidKeyRegisteredKeyType.Ed25519,
|
||
|
|
ES256K: DidKeyRegisteredKeyType.secp256k1,
|
||
|
|
ES256: DidKeyRegisteredKeyType.secp256r1,
|
||
|
|
"P-256": DidKeyRegisteredKeyType.secp256r1,
|
||
|
|
secp256k1: DidKeyRegisteredKeyType.secp256k1,
|
||
|
|
secp256r1: DidKeyRegisteredKeyType.secp256r1,
|
||
|
|
X25519: DidKeyRegisteredKeyType.X25519
|
||
|
|
};
|
||
|
|
var DidKey = class _DidKey extends DidMethod {
|
||
|
|
/**
|
||
|
|
* Creates a new DID using the `did:key` method formed from a newly generated key.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* The DID URI is formed by
|
||
|
|
* {@link https://datatracker.ietf.org/doc/html/draft-multiformats-multibase#name-base-58-bitcoin-encoding | Multibase base58-btc}
|
||
|
|
* encoding the
|
||
|
|
* {@link https://github.com/multiformats/multicodec/blob/master/README.md | Multicodec}-encoded
|
||
|
|
* public key and prefixing with `did:key:`.
|
||
|
|
*
|
||
|
|
* This method can optionally derive an encryption key from the public key used to create the DID
|
||
|
|
* if and only if the public key algorithm is `Ed25519`. This feature enables the same DID to be
|
||
|
|
* used for encrypted communication, in addition to signature verification. To enable this
|
||
|
|
* feature, specify an `algorithm` of `Ed25519` as either a top-level option or in a
|
||
|
|
* `verificationMethod` and set the `enableEncryptionKeyDerivation` option to `true`.
|
||
|
|
*
|
||
|
|
* Notes:
|
||
|
|
* - If no `options` are given, by default a new Ed25519 key will be generated.
|
||
|
|
* - The `algorithm` and `verificationMethods` options are mutually exclusive. If both are given,
|
||
|
|
* an error will be thrown.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // DID Creation
|
||
|
|
* const did = await DidKey.create();
|
||
|
|
*
|
||
|
|
* // DID Creation with a KMS
|
||
|
|
* const keyManager = new LocalKeyManager();
|
||
|
|
* const did = await DidKey.create({ keyManager });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the create operation.
|
||
|
|
* @param params.keyManager - Key Management System (KMS) used to generate keys and sign data.
|
||
|
|
* @param params.options - Optional parameters that can be specified when creating a new DID.
|
||
|
|
* @returns A Promise resolving to a {@link BearerDid} object representing the new DID.
|
||
|
|
*/
|
||
|
|
static create() {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ keyManager = new import_crypto7.LocalKeyManager(), options = {} } = {}) {
|
||
|
|
var _a, _b, _c, _d;
|
||
|
|
if (options.algorithm && options.verificationMethods) {
|
||
|
|
throw new Error(`The 'algorithm' and 'verificationMethods' options are mutually exclusive`);
|
||
|
|
}
|
||
|
|
if (options.verificationMethods && options.verificationMethods.length !== 1) {
|
||
|
|
throw new Error(`The 'verificationMethods' option must contain exactly one entry`);
|
||
|
|
}
|
||
|
|
const algorithm = (_d = (_a = options.algorithm) !== null && _a !== void 0 ? _a : (_c = (_b = options.verificationMethods) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.algorithm) !== null && _d !== void 0 ? _d : "Ed25519";
|
||
|
|
const keyUri = yield keyManager.generateKey({ algorithm });
|
||
|
|
const publicKey = yield keyManager.getPublicKey({ keyUri });
|
||
|
|
const identifier = yield DidKeyUtils.publicKeyToMultibaseId({ publicKey });
|
||
|
|
const didUri = `did:${_DidKey.methodName}:${identifier}`;
|
||
|
|
const didResolutionResult = yield _DidKey.resolve(didUri, options);
|
||
|
|
const document = didResolutionResult.didDocument;
|
||
|
|
const did = new BearerDid({
|
||
|
|
uri: didUri,
|
||
|
|
document,
|
||
|
|
metadata: {},
|
||
|
|
keyManager
|
||
|
|
});
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Given the W3C DID Document of a `did:key` DID, return the verification method that will be used
|
||
|
|
* for signing messages and credentials. With DID Key, the first verification method in the
|
||
|
|
* authentication property in the DID Document is used.
|
||
|
|
*
|
||
|
|
* Note that for DID Key, only one verification method intended for signing can exist so
|
||
|
|
* specifying `methodId` could be considered redundant or unnecessary. The option is provided for
|
||
|
|
* consistency with other DID method implementations.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the `getSigningMethod` operation.
|
||
|
|
* @param params.didDocument - DID Document to get the verification method from.
|
||
|
|
* @param params.methodId - ID of the verification method to use for signing.
|
||
|
|
* @returns Verification method to use for signing.
|
||
|
|
*/
|
||
|
|
static getSigningMethod(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ didDocument }) {
|
||
|
|
var _b;
|
||
|
|
const parsedDid = Did.parse(didDocument.id);
|
||
|
|
if (parsedDid && parsedDid.method !== this.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
const [methodId] = didDocument.assertionMethod || [];
|
||
|
|
const verificationMethod = (_b = didDocument.verificationMethod) === null || _b === void 0 ? void 0 : _b.find((vm) => vm.id === methodId);
|
||
|
|
if (!(verificationMethod && verificationMethod.publicKeyJwk)) {
|
||
|
|
throw new DidError(DidErrorCode.InternalError, "A verification method intended for signing could not be determined from the DID Document");
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Instantiates a {@link BearerDid} object for the DID Key method from a given {@link PortableDid}.
|
||
|
|
*
|
||
|
|
* This method allows for the creation of a `BearerDid` object using a previously created DID's
|
||
|
|
* key material, DID document, and metadata.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* The `verificationMethod` array of the DID document must contain exactly one key since the
|
||
|
|
* `did:key` method only supports a single verification method.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* // Export an existing BearerDid to PortableDid format.
|
||
|
|
* const portableDid = await did.export();
|
||
|
|
* // Reconstruct a BearerDid object from the PortableDid.
|
||
|
|
* const did = await DidKey.import({ portableDid });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the import operation.
|
||
|
|
* @param params.portableDid - The PortableDid object to import.
|
||
|
|
* @param params.keyManager - Optionally specify an external Key Management System (KMS) used to
|
||
|
|
* generate keys and sign data. If not given, a new
|
||
|
|
* {@link LocalKeyManager} instance will be created and
|
||
|
|
* used.
|
||
|
|
* @returns A Promise resolving to a `BearerDid` object representing the DID formed from the provided keys.
|
||
|
|
* @throws An error if the DID document does not contain exactly one verification method.
|
||
|
|
*/
|
||
|
|
static import(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ portableDid, keyManager = new import_crypto7.LocalKeyManager() }) {
|
||
|
|
const parsedDid = Did.parse(portableDid.uri);
|
||
|
|
if ((parsedDid === null || parsedDid === void 0 ? void 0 : parsedDid.method) !== _DidKey.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported`);
|
||
|
|
}
|
||
|
|
const did = yield BearerDid.import({ portableDid, keyManager });
|
||
|
|
if (did.document.verificationMethod.length !== 1) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidDocument, `DID document must contain exactly one verification method`);
|
||
|
|
}
|
||
|
|
return did;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Resolves a `did:key` identifier to a DID Document.
|
||
|
|
*
|
||
|
|
* @param didUri - The DID to be resolved.
|
||
|
|
* @param options - Optional parameters for resolving the DID.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(didUri, options) {
|
||
|
|
return __awaiter10(this, void 0, void 0, function* () {
|
||
|
|
try {
|
||
|
|
const didDocument = yield _DidKey.createDocument({ didUri, options });
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didDocument });
|
||
|
|
} catch (error) {
|
||
|
|
if (!(error instanceof DidError))
|
||
|
|
throw new Error(error);
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: Object.assign({ error: error.code }, error.message && { errorMessage: error.message }) });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Expands a did:key identifier to a DID Document.
|
||
|
|
*
|
||
|
|
* Reference: https://w3c-ccg.github.io/did-method-key/#document-creation-algorithm
|
||
|
|
*
|
||
|
|
* @param options
|
||
|
|
* @returns - A DID dodcument.
|
||
|
|
*/
|
||
|
|
static createDocument(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ didUri, options = {} }) {
|
||
|
|
const { defaultContext = "https://www.w3.org/ns/did/v1", enableEncryptionKeyDerivation = false, enableExperimentalPublicKeyTypes = false, publicKeyFormat = "JsonWebKey2020" } = options;
|
||
|
|
const didDocument = { id: "" };
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
if (!parsedDid) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDid, `Invalid DID URI: ${didUri}`);
|
||
|
|
}
|
||
|
|
const multibaseValue = parsedDid.id;
|
||
|
|
if (parsedDid.method !== _DidKey.methodName) {
|
||
|
|
throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
|
||
|
|
}
|
||
|
|
if (!_DidKey.validateIdentifier(parsedDid)) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDid, `Invalid DID URI: ${didUri}`);
|
||
|
|
}
|
||
|
|
const signatureVerificationMethod = yield _DidKey.createSignatureMethod({
|
||
|
|
didUri,
|
||
|
|
multibaseValue,
|
||
|
|
options: { enableExperimentalPublicKeyTypes, publicKeyFormat }
|
||
|
|
});
|
||
|
|
didDocument.id = parsedDid.uri;
|
||
|
|
didDocument.verificationMethod = [signatureVerificationMethod];
|
||
|
|
didDocument.authentication = [signatureVerificationMethod.id];
|
||
|
|
didDocument.assertionMethod = [signatureVerificationMethod.id];
|
||
|
|
didDocument.capabilityInvocation = [signatureVerificationMethod.id];
|
||
|
|
didDocument.capabilityDelegation = [signatureVerificationMethod.id];
|
||
|
|
if (enableEncryptionKeyDerivation === true) {
|
||
|
|
const encryptionPublicKeyFormat = publicKeyFormat === "Ed25519VerificationKey2020" ? "X25519KeyAgreementKey2020" : "JsonWebKey2020";
|
||
|
|
const encryptionVerificationMethod = yield this.createEncryptionMethod({
|
||
|
|
didUri,
|
||
|
|
multibaseValue,
|
||
|
|
options: { enableExperimentalPublicKeyTypes, publicKeyFormat: encryptionPublicKeyFormat }
|
||
|
|
});
|
||
|
|
didDocument.verificationMethod.push(encryptionVerificationMethod);
|
||
|
|
didDocument.keyAgreement = [encryptionVerificationMethod.id];
|
||
|
|
}
|
||
|
|
const contextArray = [defaultContext];
|
||
|
|
const verificationMethodTypes = getVerificationMethodTypes({ didDocument });
|
||
|
|
verificationMethodTypes.forEach((typeName) => {
|
||
|
|
const typeUrl = DidKeyVerificationMethodType[typeName];
|
||
|
|
contextArray.push(typeUrl);
|
||
|
|
});
|
||
|
|
didDocument["@context"] = contextArray;
|
||
|
|
return didDocument;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decoding a multibase-encoded multicodec value into a verification method
|
||
|
|
* that is suitable for verifying that encrypted information will be
|
||
|
|
* received by the intended recipient.
|
||
|
|
*/
|
||
|
|
static createEncryptionMethod(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ didUri, multibaseValue, options }) {
|
||
|
|
const { enableExperimentalPublicKeyTypes, publicKeyFormat } = options;
|
||
|
|
const verificationMethod = { id: "", type: "", controller: "" };
|
||
|
|
const { keyBytes: publicKeyBytes, multicodecCode: multicodecValue } = yield _DidKey.deriveEncryptionKey({ multibaseValue });
|
||
|
|
const actualLength = publicKeyBytes.byteLength;
|
||
|
|
const expectedLength = DidKeyUtils.MULTICODEC_PUBLIC_KEY_LENGTH[multicodecValue];
|
||
|
|
if (actualLength !== expectedLength) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyLength, `Expected ${actualLength} bytes. Actual: ${expectedLength}`);
|
||
|
|
}
|
||
|
|
const kemMultibaseValue = keyBytesToMultibaseId({
|
||
|
|
keyBytes: publicKeyBytes,
|
||
|
|
multicodecCode: multicodecValue
|
||
|
|
});
|
||
|
|
verificationMethod.id = `${didUri}#${kemMultibaseValue}`;
|
||
|
|
try {
|
||
|
|
new URL(verificationMethod.id);
|
||
|
|
} catch (error) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidUrl, "Verification Method ID is not a valid DID URL.");
|
||
|
|
}
|
||
|
|
if (!(publicKeyFormat in DidKeyVerificationMethodType)) {
|
||
|
|
throw new DidError(DidErrorCode.UnsupportedPublicKeyType, `Unsupported format: ${publicKeyFormat}`);
|
||
|
|
}
|
||
|
|
const StandardPublicKeyTypes = ["Multikey", "JsonWebKey2020", "X25519KeyAgreementKey2020"];
|
||
|
|
if (enableExperimentalPublicKeyTypes === false && !StandardPublicKeyTypes.includes(publicKeyFormat)) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Specified '${publicKeyFormat}' without setting enableExperimentalPublicKeyTypes to true.`);
|
||
|
|
}
|
||
|
|
verificationMethod.type = publicKeyFormat;
|
||
|
|
verificationMethod.controller = didUri;
|
||
|
|
if (publicKeyFormat === "X25519KeyAgreementKey2020") {
|
||
|
|
verificationMethod.publicKeyMultibase = kemMultibaseValue;
|
||
|
|
}
|
||
|
|
if (publicKeyFormat === "JsonWebKey2020") {
|
||
|
|
const { crv: crv2 } = yield DidKeyUtils.multicodecToJwk({ code: multicodecValue });
|
||
|
|
verificationMethod.publicKeyJwk = yield DidKeyUtils.keyConverter(crv2).bytesToPublicKey({ publicKeyBytes });
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Decodes a multibase-encoded multicodec value into a verification method
|
||
|
|
* that is suitable for verifying digital signatures.
|
||
|
|
* @param options - Signature method creation algorithm inputs.
|
||
|
|
* @returns - A verification method.
|
||
|
|
*/
|
||
|
|
static createSignatureMethod(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ didUri, multibaseValue, options }) {
|
||
|
|
const { enableExperimentalPublicKeyTypes, publicKeyFormat } = options;
|
||
|
|
const verificationMethod = { id: "", type: "", controller: "" };
|
||
|
|
const { keyBytes: publicKeyBytes, multicodecCode: multicodecValue, multicodecName } = multibaseIdToKeyBytes({ multibaseKeyId: multibaseValue });
|
||
|
|
const actualLength = publicKeyBytes.byteLength;
|
||
|
|
const expectedLength = DidKeyUtils.MULTICODEC_PUBLIC_KEY_LENGTH[multicodecValue];
|
||
|
|
if (actualLength !== expectedLength) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyLength, `Expected ${actualLength} bytes. Actual: ${expectedLength}`);
|
||
|
|
}
|
||
|
|
let isValid = false;
|
||
|
|
switch (multicodecName) {
|
||
|
|
case "secp256k1-pub":
|
||
|
|
isValid = yield import_crypto7.Secp256k1.validatePublicKey({ publicKeyBytes });
|
||
|
|
break;
|
||
|
|
case "ed25519-pub":
|
||
|
|
isValid = yield import_crypto7.Ed25519.validatePublicKey({ publicKeyBytes });
|
||
|
|
break;
|
||
|
|
case "x25519-pub":
|
||
|
|
isValid = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if (!isValid) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKey, "Invalid public key detected.");
|
||
|
|
}
|
||
|
|
verificationMethod.id = `${didUri}#${multibaseValue}`;
|
||
|
|
try {
|
||
|
|
new URL(verificationMethod.id);
|
||
|
|
} catch (error) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidDidUrl, "Verification Method ID is not a valid DID URL.");
|
||
|
|
}
|
||
|
|
if (!(publicKeyFormat in DidKeyVerificationMethodType)) {
|
||
|
|
throw new DidError(DidErrorCode.UnsupportedPublicKeyType, `Unsupported format: ${publicKeyFormat}`);
|
||
|
|
}
|
||
|
|
const StandardPublicKeyTypes = ["Multikey", "JsonWebKey2020", "Ed25519VerificationKey2020"];
|
||
|
|
if (enableExperimentalPublicKeyTypes === false && !StandardPublicKeyTypes.includes(publicKeyFormat)) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Specified '${publicKeyFormat}' without setting enableExperimentalPublicKeyTypes to true.`);
|
||
|
|
}
|
||
|
|
verificationMethod.type = publicKeyFormat;
|
||
|
|
verificationMethod.controller = didUri;
|
||
|
|
if (publicKeyFormat === "Ed25519VerificationKey2020") {
|
||
|
|
verificationMethod.publicKeyMultibase = multibaseValue;
|
||
|
|
}
|
||
|
|
if (publicKeyFormat === "JsonWebKey2020") {
|
||
|
|
const { crv: crv2 } = yield DidKeyUtils.multicodecToJwk({ code: multicodecValue });
|
||
|
|
verificationMethod.publicKeyJwk = yield DidKeyUtils.keyConverter(crv2).bytesToPublicKey({ publicKeyBytes });
|
||
|
|
}
|
||
|
|
return verificationMethod;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Transform a multibase-encoded multicodec value to public encryption key
|
||
|
|
* components that are suitable for encrypting messages to a receiver. A
|
||
|
|
* mathematical proof elaborating on the safety of performing this operation
|
||
|
|
* is available in:
|
||
|
|
* {@link https://eprint.iacr.org/2021/509.pdf | On using the same key pair for Ed25519 and an X25519 based KEM}
|
||
|
|
*/
|
||
|
|
static deriveEncryptionKey(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ multibaseValue }) {
|
||
|
|
let publicEncryptionKey = {
|
||
|
|
keyBytes: new Uint8Array(),
|
||
|
|
multicodecCode: 0
|
||
|
|
};
|
||
|
|
const { keyBytes: publicKeyBytes, multicodecCode: multicodecValue } = multibaseIdToKeyBytes({ multibaseKeyId: multibaseValue });
|
||
|
|
if (multicodecValue === 237) {
|
||
|
|
const ed25519PublicKey = yield DidKeyUtils.keyConverter("Ed25519").bytesToPublicKey({
|
||
|
|
publicKeyBytes
|
||
|
|
});
|
||
|
|
const generatedPublicEncryptionKey = yield import_crypto7.Ed25519.convertPublicKeyToX25519({
|
||
|
|
publicKey: ed25519PublicKey
|
||
|
|
});
|
||
|
|
const generatedPublicEncryptionKeyBytes = yield DidKeyUtils.keyConverter("Ed25519").publicKeyToBytes({
|
||
|
|
publicKey: generatedPublicEncryptionKey
|
||
|
|
});
|
||
|
|
publicEncryptionKey = {
|
||
|
|
keyBytes: generatedPublicEncryptionKeyBytes,
|
||
|
|
multicodecCode: 236
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return publicEncryptionKey;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Validates the structure and components of a DID URI against the `did:key` method specification.
|
||
|
|
*
|
||
|
|
* @param parsedDid - An object representing the parsed components of a DID URI, including the
|
||
|
|
* scheme, method, and method-specific identifier.
|
||
|
|
* @returns `true` if the DID URI meets the `did:key` method's structural requirements, `false` otherwise.
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
static validateIdentifier(parsedDid) {
|
||
|
|
const { method, id: multibaseValue } = parsedDid;
|
||
|
|
const [scheme] = parsedDid.uri.split(":", 1);
|
||
|
|
const version = "1";
|
||
|
|
return scheme === "did" && method === "key" && Number(version) > 0 && (0, import_common4.universalTypeOf)(multibaseValue) === "String" && multibaseValue.startsWith("z");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidKey.methodName = "key";
|
||
|
|
var DidKeyUtils = class _DidKeyUtils {
|
||
|
|
/**
|
||
|
|
* Converts a JWK (JSON Web Key) to a Multicodec code and name.
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const jwk: Jwk = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
||
|
|
* const { code, name } = await DidKeyUtils.jwkToMulticodec({ jwk });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the conversion.
|
||
|
|
* @param params.jwk - The JSON Web Key to be converted.
|
||
|
|
* @returns A promise that resolves to a Multicodec definition.
|
||
|
|
*/
|
||
|
|
static jwkToMulticodec(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ jwk }) {
|
||
|
|
const params = [];
|
||
|
|
if (jwk.crv) {
|
||
|
|
params.push(jwk.crv);
|
||
|
|
if (jwk.d) {
|
||
|
|
params.push("private");
|
||
|
|
} else {
|
||
|
|
params.push("public");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const lookupKey = params.join(":");
|
||
|
|
const name = _DidKeyUtils.JWK_TO_MULTICODEC[lookupKey];
|
||
|
|
if (name === void 0) {
|
||
|
|
throw new Error(`Unsupported JWK to Multicodec conversion: '${lookupKey}'`);
|
||
|
|
}
|
||
|
|
const code = import_common4.Multicodec.getCodeFromName({ name });
|
||
|
|
return { code, name };
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Returns the appropriate public key compressor for the specified cryptographic curve.
|
||
|
|
*
|
||
|
|
* @param curve - The cryptographic curve to use for the key conversion.
|
||
|
|
* @returns A public key compressor for the specified curve.
|
||
|
|
*/
|
||
|
|
static keyCompressor(curve) {
|
||
|
|
const compressors = {
|
||
|
|
"P-256": import_crypto7.Secp256r1.compressPublicKey,
|
||
|
|
"secp256k1": import_crypto7.Secp256k1.compressPublicKey
|
||
|
|
};
|
||
|
|
const compressor = compressors[curve];
|
||
|
|
if (!compressor)
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);
|
||
|
|
return compressor;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Returns the appropriate key converter for the specified cryptographic curve.
|
||
|
|
*
|
||
|
|
* @param curve - The cryptographic curve to use for the key conversion.
|
||
|
|
* @returns An `AsymmetricKeyConverter` for the specified curve.
|
||
|
|
*/
|
||
|
|
static keyConverter(curve) {
|
||
|
|
const converters = {
|
||
|
|
"Ed25519": import_crypto7.Ed25519,
|
||
|
|
"P-256": import_crypto7.Secp256r1,
|
||
|
|
"secp256k1": import_crypto7.Secp256k1,
|
||
|
|
"X25519": import_crypto7.X25519
|
||
|
|
};
|
||
|
|
const converter = converters[curve];
|
||
|
|
if (!converter)
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);
|
||
|
|
return converter;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a Multicodec code or name to parial JWK (JSON Web Key).
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const partialJwk = await DidKeyUtils.multicodecToJwk({ name: 'ed25519-pub' });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the conversion.
|
||
|
|
* @param params.code - Optional Multicodec code to convert.
|
||
|
|
* @param params.name - Optional Multicodec name to convert.
|
||
|
|
* @returns A promise that resolves to a JOSE format key.
|
||
|
|
*/
|
||
|
|
static multicodecToJwk(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ code, name }) {
|
||
|
|
if (!(name ? !code : code)) {
|
||
|
|
throw new Error(`Either 'name' or 'code' must be defined, but not both.`);
|
||
|
|
}
|
||
|
|
name = name === void 0 ? import_common4.Multicodec.getNameFromCode({ code }) : name;
|
||
|
|
const lookupKey = name;
|
||
|
|
const jose = _DidKeyUtils.MULTICODEC_TO_JWK[lookupKey];
|
||
|
|
if (jose === void 0) {
|
||
|
|
throw new Error(`Unsupported Multicodec to JWK conversion`);
|
||
|
|
}
|
||
|
|
return Object.assign({}, jose);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Converts a public key in JWK (JSON Web Key) format to a multibase identifier.
|
||
|
|
*
|
||
|
|
* @remarks
|
||
|
|
* Note: All secp public keys are converted to compressed point encoding
|
||
|
|
* before the multibase identifier is computed.
|
||
|
|
*
|
||
|
|
* Per {@link https://github.com/multiformats/multicodec/blob/master/table.csv | Multicodec table}:
|
||
|
|
* Public keys for Elliptic Curve cryptography algorithms (e.g., secp256k1,
|
||
|
|
* secp256k1r1, secp384r1, etc.) are always represented with compressed point
|
||
|
|
* encoding (e.g., secp256k1-pub, p256-pub, p384-pub, etc.).
|
||
|
|
*
|
||
|
|
* Per {@link https://datatracker.ietf.org/doc/html/rfc8812#name-jose-and-cose-secp256k1-cur | RFC 8812}:
|
||
|
|
* "As a compressed point encoding representation is not defined for JWK
|
||
|
|
* elliptic curve points, the uncompressed point encoding defined there
|
||
|
|
* MUST be used. The x and y values represented MUST both be exactly
|
||
|
|
* 256 bits, with any leading zeros preserved."
|
||
|
|
*
|
||
|
|
* @example
|
||
|
|
* ```ts
|
||
|
|
* const publicKey = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
||
|
|
* const multibaseId = await DidKeyUtils.publicKeyToMultibaseId({ publicKey });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @param params - The parameters for the conversion.
|
||
|
|
* @param params.publicKey - The public key in JWK format.
|
||
|
|
* @returns A promise that resolves to the multibase identifier.
|
||
|
|
*/
|
||
|
|
static publicKeyToMultibaseId(_a) {
|
||
|
|
return __awaiter10(this, arguments, void 0, function* ({ publicKey }) {
|
||
|
|
var _b;
|
||
|
|
if (!((publicKey === null || publicKey === void 0 ? void 0 : publicKey.crv) && publicKey.crv in AlgorithmToKeyTypeMap3)) {
|
||
|
|
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Public key contains an unsupported key type: ${(_b = publicKey === null || publicKey === void 0 ? void 0 : publicKey.crv) !== null && _b !== void 0 ? _b : "undefined"}`);
|
||
|
|
}
|
||
|
|
let publicKeyBytes = yield _DidKeyUtils.keyConverter(publicKey.crv).publicKeyToBytes({ publicKey });
|
||
|
|
if (/^(secp256k1|P-256|P-384|P-521)$/.test(publicKey.crv)) {
|
||
|
|
publicKeyBytes = yield _DidKeyUtils.keyCompressor(publicKey.crv)({ publicKeyBytes });
|
||
|
|
}
|
||
|
|
const { name: multicodecName } = yield _DidKeyUtils.jwkToMulticodec({ jwk: publicKey });
|
||
|
|
const multibaseId = keyBytesToMultibaseId({
|
||
|
|
keyBytes: publicKeyBytes,
|
||
|
|
multicodecName
|
||
|
|
});
|
||
|
|
return multibaseId;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidKeyUtils.JWK_TO_MULTICODEC = {
|
||
|
|
"Ed25519:public": "ed25519-pub",
|
||
|
|
"Ed25519:private": "ed25519-priv",
|
||
|
|
"secp256k1:public": "secp256k1-pub",
|
||
|
|
"secp256k1:private": "secp256k1-priv",
|
||
|
|
"X25519:public": "x25519-pub",
|
||
|
|
"X25519:private": "x25519-priv"
|
||
|
|
};
|
||
|
|
DidKeyUtils.MULTICODEC_PUBLIC_KEY_LENGTH = {
|
||
|
|
// secp256k1-pub - Secp256k1 public key (compressed) - 33 bytes
|
||
|
|
231: 33,
|
||
|
|
// x25519-pub - Curve25519 public key - 32 bytes
|
||
|
|
236: 32,
|
||
|
|
// ed25519-pub - Ed25519 public key - 32 bytes
|
||
|
|
237: 32
|
||
|
|
};
|
||
|
|
DidKeyUtils.MULTICODEC_TO_JWK = {
|
||
|
|
"ed25519-pub": { crv: "Ed25519", kty: "OKP", x: "" },
|
||
|
|
"ed25519-priv": { crv: "Ed25519", kty: "OKP", x: "", d: "" },
|
||
|
|
"secp256k1-pub": { crv: "secp256k1", kty: "EC", x: "", y: "" },
|
||
|
|
"secp256k1-priv": { crv: "secp256k1", kty: "EC", x: "", y: "", d: "" },
|
||
|
|
"x25519-pub": { crv: "X25519", kty: "OKP", x: "" },
|
||
|
|
"x25519-priv": { crv: "X25519", kty: "OKP", x: "", d: "" }
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/methods/did-web.js
|
||
|
|
var __awaiter11 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidWeb = class _DidWeb extends DidMethod {
|
||
|
|
/**
|
||
|
|
* Resolves a `did:web` identifier to a DID Document.
|
||
|
|
*
|
||
|
|
* @param didUri - The DID to be resolved.
|
||
|
|
* @param _options - Optional parameters for resolving the DID. Unused by this DID method.
|
||
|
|
* @returns A Promise resolving to a {@link DidResolutionResult} object representing the result of the resolution.
|
||
|
|
*/
|
||
|
|
static resolve(didUri, _options) {
|
||
|
|
return __awaiter11(this, void 0, void 0, function* () {
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
if (!parsedDid) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "invalidDid" } });
|
||
|
|
}
|
||
|
|
if (parsedDid.method !== _DidWeb.methodName) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "methodNotSupported" } });
|
||
|
|
}
|
||
|
|
let baseUrl = `https://${parsedDid.id.replace(/:/g, "/")}`;
|
||
|
|
baseUrl = decodeURIComponent(baseUrl);
|
||
|
|
const didDocumentUrl = parsedDid.id.includes(":") ? `${baseUrl}/did.json` : `${baseUrl}/.well-known/did.json`;
|
||
|
|
try {
|
||
|
|
const response = yield fetch(didDocumentUrl);
|
||
|
|
if (!response.ok)
|
||
|
|
throw new Error("HTTP error status code returned");
|
||
|
|
const didDocument = yield response.json();
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didDocument });
|
||
|
|
} catch (error) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: { error: "notFound" } });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
DidWeb.methodName = "web";
|
||
|
|
|
||
|
|
// dist/esm/resolver/resolver-cache-level.js
|
||
|
|
var import_ms = __toESM(require("ms"), 1);
|
||
|
|
var import_level = require("level");
|
||
|
|
var __awaiter12 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var DidResolverCacheLevel = class {
|
||
|
|
constructor({ db, location = "DATA/DID_RESOLVERCACHE", ttl = "15m" } = {}) {
|
||
|
|
this.cache = db !== null && db !== void 0 ? db : new import_level.Level(location);
|
||
|
|
this.ttl = (0, import_ms.default)(ttl);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Retrieves a DID resolution result from the cache.
|
||
|
|
*
|
||
|
|
* If the cached item has exceeded its TTL, it's scheduled for deletion and undefined is returned.
|
||
|
|
*
|
||
|
|
* @param did - The DID string used as the key for retrieving the cached result.
|
||
|
|
* @returns The cached DID resolution result or undefined if not found or expired.
|
||
|
|
*/
|
||
|
|
get(did) {
|
||
|
|
return __awaiter12(this, void 0, void 0, function* () {
|
||
|
|
try {
|
||
|
|
const str3 = yield this.cache.get(did);
|
||
|
|
const cachedDidResolutionResult = JSON.parse(str3);
|
||
|
|
if (Date.now() >= cachedDidResolutionResult.ttlMillis) {
|
||
|
|
this.cache.nextTick(() => this.cache.del(did));
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return cachedDidResolutionResult.value;
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
if (error.notFound) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Stores a DID resolution result in the cache with a TTL.
|
||
|
|
*
|
||
|
|
* @param did - The DID string used as the key for storing the result.
|
||
|
|
* @param value - The DID resolution result to be cached.
|
||
|
|
* @returns A promise that resolves when the operation is complete.
|
||
|
|
*/
|
||
|
|
set(did, value) {
|
||
|
|
const cachedDidResolutionResult = { ttlMillis: Date.now() + this.ttl, value };
|
||
|
|
const str3 = JSON.stringify(cachedDidResolutionResult);
|
||
|
|
return this.cache.put(did, str3);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Deletes a DID resolution result from the cache.
|
||
|
|
*
|
||
|
|
* @param did - The DID string used as the key for deletion.
|
||
|
|
* @returns A promise that resolves when the operation is complete.
|
||
|
|
*/
|
||
|
|
delete(did) {
|
||
|
|
return this.cache.del(did);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Clears all entries from the cache.
|
||
|
|
*
|
||
|
|
* @returns A promise that resolves when the operation is complete.
|
||
|
|
*/
|
||
|
|
clear() {
|
||
|
|
return this.cache.clear();
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Closes the underlying LevelDB store.
|
||
|
|
*
|
||
|
|
* @returns A promise that resolves when the store is closed.
|
||
|
|
*/
|
||
|
|
close() {
|
||
|
|
return this.cache.close();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/resolver/resolver-cache-noop.js
|
||
|
|
var DidResolverCacheNoop = {
|
||
|
|
get: function(_key) {
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
set: function(_key, _value) {
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
delete: function(_key) {
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
clear: function() {
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
close: function() {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// dist/esm/resolver/universal-resolver.js
|
||
|
|
var __awaiter13 = function(thisArg, _arguments, P3, generator) {
|
||
|
|
function adopt(value) {
|
||
|
|
return value instanceof P3 ? value : new P3(function(resolve) {
|
||
|
|
resolve(value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return new (P3 || (P3 = Promise))(function(resolve, reject) {
|
||
|
|
function fulfilled(value) {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function rejected(value) {
|
||
|
|
try {
|
||
|
|
step(generator["throw"](value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function step(result) {
|
||
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||
|
|
}
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
var UniversalResolver = class {
|
||
|
|
/**
|
||
|
|
* Constructs a new `DidResolver`.
|
||
|
|
*
|
||
|
|
* @param params - The parameters for constructing the `DidResolver`.
|
||
|
|
*/
|
||
|
|
constructor({ cache, didResolvers }) {
|
||
|
|
this.didResolvers = /* @__PURE__ */ new Map();
|
||
|
|
this.cache = cache || DidResolverCacheNoop;
|
||
|
|
for (const resolver of didResolvers) {
|
||
|
|
this.didResolvers.set(resolver.methodName, resolver);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Resolves a DID to a DID Resolution Result.
|
||
|
|
*
|
||
|
|
* If the DID Resolution Result is present in the cache, it returns the cached result. Otherwise,
|
||
|
|
* it uses the appropriate method resolver to resolve the DID, stores the resolution result in the
|
||
|
|
* cache, and returns the resolultion result.
|
||
|
|
*
|
||
|
|
* @param didUri - The DID or DID URL to resolve.
|
||
|
|
* @returns A promise that resolves to the DID Resolution Result.
|
||
|
|
*/
|
||
|
|
resolve(didUri, options) {
|
||
|
|
return __awaiter13(this, void 0, void 0, function* () {
|
||
|
|
const parsedDid = Did.parse(didUri);
|
||
|
|
if (!parsedDid) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: {
|
||
|
|
error: DidErrorCode.InvalidDid,
|
||
|
|
errorMessage: `Invalid DID URI: ${didUri}`
|
||
|
|
} });
|
||
|
|
}
|
||
|
|
const resolver = this.didResolvers.get(parsedDid.method);
|
||
|
|
if (!resolver) {
|
||
|
|
return Object.assign(Object.assign({}, EMPTY_DID_RESOLUTION_RESULT), { didResolutionMetadata: {
|
||
|
|
error: DidErrorCode.MethodNotSupported,
|
||
|
|
errorMessage: `Method not supported: ${parsedDid.method}`
|
||
|
|
} });
|
||
|
|
}
|
||
|
|
const cachedResolutionResult = yield this.cache.get(parsedDid.uri);
|
||
|
|
if (cachedResolutionResult) {
|
||
|
|
return cachedResolutionResult;
|
||
|
|
} else {
|
||
|
|
const resolutionResult = yield resolver.resolve(parsedDid.uri, options);
|
||
|
|
if (!resolutionResult.didResolutionMetadata.error) {
|
||
|
|
yield this.cache.set(parsedDid.uri, resolutionResult);
|
||
|
|
}
|
||
|
|
return resolutionResult;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Dereferences a DID (Decentralized Identifier) URL to a corresponding DID resource.
|
||
|
|
*
|
||
|
|
* This method interprets the DID URL's components, which include the DID method, method-specific
|
||
|
|
* identifier, path, query, and fragment, and retrieves the related resource as per the DID Core
|
||
|
|
* specifications.
|
||
|
|
*
|
||
|
|
* The dereferencing process involves resolving the DID contained in the DID URL to a DID document,
|
||
|
|
* and then extracting the specific part of the document identified by the fragment in the DID URL.
|
||
|
|
* If no fragment is specified, the entire DID document is returned.
|
||
|
|
*
|
||
|
|
* This method supports resolution of different components within a DID document such as service
|
||
|
|
* endpoints and verification methods, based on their IDs. It accommodates both full and
|
||
|
|
* DID URLs as specified in the DID Core specification.
|
||
|
|
*
|
||
|
|
* More information on DID URL dereferencing can be found in the
|
||
|
|
* {@link https://www.w3.org/TR/did-core/#did-url-dereferencing | DID Core specification}.
|
||
|
|
*
|
||
|
|
* TODO: This is a partial implementation and does not fully implement DID URL dereferencing. (https://github.com/TBD54566975/web5-js/issues/387)
|
||
|
|
*
|
||
|
|
* @param didUrl - The DID URL string to dereference.
|
||
|
|
* @param [_options] - Input options to the dereference function. Optional.
|
||
|
|
* @returns a {@link DidDereferencingResult}
|
||
|
|
*/
|
||
|
|
dereference(didUrl, _options) {
|
||
|
|
return __awaiter13(this, void 0, void 0, function* () {
|
||
|
|
const parsedDidUrl = Did.parse(didUrl);
|
||
|
|
if (!parsedDidUrl) {
|
||
|
|
return {
|
||
|
|
dereferencingMetadata: { error: DidErrorCode.InvalidDidUrl },
|
||
|
|
contentStream: null,
|
||
|
|
contentMetadata: {}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
const { didDocument, didResolutionMetadata, didDocumentMetadata } = yield this.resolve(parsedDidUrl.uri);
|
||
|
|
if (!didDocument) {
|
||
|
|
return {
|
||
|
|
dereferencingMetadata: { error: didResolutionMetadata.error },
|
||
|
|
contentStream: null,
|
||
|
|
contentMetadata: {}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
if (!parsedDidUrl.fragment || parsedDidUrl.query) {
|
||
|
|
return {
|
||
|
|
dereferencingMetadata: { contentType: "application/did+json" },
|
||
|
|
contentStream: didDocument,
|
||
|
|
contentMetadata: didDocumentMetadata
|
||
|
|
};
|
||
|
|
}
|
||
|
|
const { service = [], verificationMethod = [] } = didDocument;
|
||
|
|
const idSet = /* @__PURE__ */ new Set([didUrl, parsedDidUrl.fragment, `#${parsedDidUrl.fragment}`]);
|
||
|
|
let didResource;
|
||
|
|
for (let vm of verificationMethod) {
|
||
|
|
if (idSet.has(vm.id)) {
|
||
|
|
didResource = vm;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for (let svc of service) {
|
||
|
|
if (idSet.has(svc.id)) {
|
||
|
|
didResource = svc;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (didResource) {
|
||
|
|
return {
|
||
|
|
dereferencingMetadata: { contentType: "application/did+json" },
|
||
|
|
contentStream: didResource,
|
||
|
|
contentMetadata: didResolutionMetadata
|
||
|
|
};
|
||
|
|
} else {
|
||
|
|
return {
|
||
|
|
dereferencingMetadata: { error: DidErrorCode.NotFound },
|
||
|
|
contentStream: null,
|
||
|
|
contentMetadata: {}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
// Annotate the CommonJS export names for ESM import in node:
|
||
|
|
0 && (module.exports = {
|
||
|
|
BearerDid,
|
||
|
|
Did,
|
||
|
|
DidDht,
|
||
|
|
DidDhtDocument,
|
||
|
|
DidDhtRegisteredDidType,
|
||
|
|
DidDhtRegisteredKeyType,
|
||
|
|
DidDhtUtils,
|
||
|
|
DidDhtVerificationRelationship,
|
||
|
|
DidError,
|
||
|
|
DidErrorCode,
|
||
|
|
DidIon,
|
||
|
|
DidIonRegisteredKeyType,
|
||
|
|
DidIonUtils,
|
||
|
|
DidJwk,
|
||
|
|
DidKey,
|
||
|
|
DidKeyRegisteredKeyType,
|
||
|
|
DidKeyUtils,
|
||
|
|
DidKeyVerificationMethodType,
|
||
|
|
DidMethod,
|
||
|
|
DidResolverCacheLevel,
|
||
|
|
DidResolverCacheNoop,
|
||
|
|
DidVerificationRelationship,
|
||
|
|
DidWeb,
|
||
|
|
EMPTY_DID_RESOLUTION_RESULT,
|
||
|
|
UniversalResolver,
|
||
|
|
utils
|
||
|
|
});
|
||
|
|
/*! Bundled license information:
|
||
|
|
|
||
|
|
uri-js/dist/es5/uri.all.js:
|
||
|
|
(** @license URI.js v4.4.1 (c) 2011 Gary Court. License: http://github.com/garycourt/uri-js *)
|
||
|
|
|
||
|
|
uint8-util/util.js:
|
||
|
|
(* Common package for dealing with hex/string/uint8 conversions (and sha1 hashing)
|
||
|
|
*
|
||
|
|
* @author Jimmy Wärting <jimmy@warting.se> (https://jimmy.warting.se/opensource)
|
||
|
|
* @license MIT
|
||
|
|
*)
|
||
|
|
|
||
|
|
@noble/ed25519/index.js:
|
||
|
|
(*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
|
||
|
|
|
||
|
|
@noble/secp256k1/index.js:
|
||
|
|
(*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
|
||
|
|
*/
|
||
|
|
//# sourceMappingURL=index.js.map
|