UNPKG

@ngraveio/ur-coin-identity

Version:

Provides BC UR type that uniquely identifies a crypto coin.

245 lines (240 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CoinIdentity = exports.ComparisonMethod = exports.EllipticCurve = void 0; const bc_ur_1 = require("@ngraveio/bc-ur"); /** * Elliptic curve types defined by the IANA registry * * https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves * https://www.rfc-editor.org/rfc/rfc9053.html#name-elliptic-curve-keys * * P256=1 ; NIST P-256 also known as secp256r1 * P384=2 ; NIST P-384 also known as secp384r1 * P521=3 ; EC2 NIST P-521 also known as secp521r1 * X25519=4 ; X25519 for use w/ ECDH only * X448=5 ; X448 for use w/ ECDH only * Ed25519=6 ; Ed25519 for use w/ EdDSA only * Ed448=7 ; Ed448 for use w/ EdDSA only * secp256k1=8 ; SECG secp256k1 curve IESG * */ var EllipticCurve; (function (EllipticCurve) { EllipticCurve[EllipticCurve["P256"] = 1] = "P256"; EllipticCurve[EllipticCurve["P384"] = 2] = "P384"; EllipticCurve[EllipticCurve["P521"] = 3] = "P521"; EllipticCurve[EllipticCurve["X25519"] = 4] = "X25519"; EllipticCurve[EllipticCurve["X448"] = 5] = "X448"; EllipticCurve[EllipticCurve["Ed25519"] = 6] = "Ed25519"; EllipticCurve[EllipticCurve["Ed448"] = 7] = "Ed448"; EllipticCurve[EllipticCurve["secp256k1"] = 8] = "secp256k1"; })(EllipticCurve || (exports.EllipticCurve = EllipticCurve = {})); var ComparisonMethod; (function (ComparisonMethod) { ComparisonMethod["ExactMatch"] = "=="; ComparisonMethod["Parent"] = ">"; ComparisonMethod["Child"] = "<"; ComparisonMethod["NotEqual"] = "!="; ComparisonMethod["LessThanOrEqual"] = "<="; ComparisonMethod["GreaterThanOrEqual"] = ">="; })(ComparisonMethod || (exports.ComparisonMethod = ComparisonMethod = {})); const CoinIdentityBase = (0, bc_ur_1.registryItemFactory)({ tag: 41401, URType: 'coin-identity', keyMap: { curve: 1, type: 2, subtype: 3, }, CDDL: ` ; Table should always be updated according to IANA registry ; https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves ; https://www.rfc-editor.org/rfc/rfc9053.html#name-elliptic-curve-keys P256=1 ; NIST P-256 also known as secp256r1 P384=2 ; NIST P-384 also known as secp384r1 P521=3 ; EC2 NIST P-521 also known as secp521r1 X25519=4 ; X25519 for use w/ ECDH only X448=5 ; X448 for use w/ ECDH only Ed25519=6 ; Ed25519 for use w/ EdDSA only Ed448=7 ; Ed448 for use w/ EdDSA only secp256k1=8 ; SECG secp256k1 curve IESG elliptic_curve = P256 / P384 / P521 / X25519 / X448 / Ed25519 / Ed448 / secp256k1 ; Subtypes specific to some coins (e.g. ChainId for EVM chains) hex_string = #6.263(bstr) ; byte string is a hexadecimal string no need for decoding sub_type_exp = uint32 / str / hex_string coin-identity = { curve: elliptic_curve, type: uint31, ; values from [SLIP44] with high bit turned off, ? subtype: [ sub_type_exp + ] ; Compatible with the definition of several subtypes if necessary } curve = 1 type = 2 subtype = 3 `, }); /** CDDL * * ; Table should always be updated according to IANA registry * ; https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves * ; https://www.rfc-editor.org/rfc/rfc9053.html#name-elliptic-curve-keys * * P256=1 ; NIST P-256 also known as secp256r1 * P384=2 ; NIST P-384 also known as secp384r1 * P521=3 ; EC2 NIST P-521 also known as secp521r1 * X25519=4 ; X25519 for use w/ ECDH only * X448=5 ; X448 for use w/ ECDH only * Ed25519=6 ; Ed25519 for use w/ EdDSA only * Ed448=7 ; Ed448 for use w/ EdDSA only * secp256k1=8 ; SECG secp256k1 curve IESG * * elliptic_curve = P256 / P384 / P521 / X25519 / X448 / Ed25519 / Ed448 / secp256k1 * * ; Subtypes specific to some coins (e.g. ChainId for EVM chains) * hex_string = #6.263(bstr) ; byte string is a hexadecimal string no need for decoding * sub_type_exp = uint32 / str / hex_string * * coin-identity = { * curve: elliptic_curve, * type: uint31, ; values from [SLIP44] with high bit turned off, * ? subtype: [ sub_type_exp + ] ; Compatible with the definition of several subtypes if necessary * } * * curve = 1 * type = 2 * subtype = 3 */ class CoinIdentity extends CoinIdentityBase { constructor(curve, type, subtype) { super({ curve, type, subtype }, CoinIdentityBase.keyMap); this.getCurve = () => this.data.curve; this.getType = () => this.data.type; this.getSubType = () => this.data.subtype || []; /** * Get the parent CoinIdentity of the current CoinIdentity * @returns {CoinIdentity} a new instance of CoinIdentity for the parent if it exists or null if it does not. */ this.getParent = () => { // If we dont have any subtypes, return null if (!this.data.subtype?.length) return null; // Otherwise remove the last subtype and return a new CoinIdentity const subtypes = this.data.subtype.slice(1, this.data.subtype.length); return new CoinIdentity(this.data.curve, this.data.type, subtypes); }; /** * Create a url from ths CoinIdentity. The subtypes should be in the correct order. * @returns {string} url representation of the CoinIdentity */ this.toURL = () => { const curve = Object.values(EllipticCurve)[this.data.curve - 1]; const type = this.data.type; const subtype = this.data.subtype; const subtypes = subtype?.join('.'); if (subtypes?.length) { return `bc-coin://${subtypes}.${curve}/${type}`; } return `bc-coin://${curve}/${type}`; }; /** * Compare the current id to a given id * @param coinIdentity CoinIdentity to compare the current one with * @param comparison comparison method to check * @returns boolean indicating if the comparison is valid */ this.compare = (coinIdentity, comparison) => { const url = this.toURL().replace('bc-coin://', ''); const urlToCompare = coinIdentity.toURL().replace('bc-coin://', ''); return CoinIdentity.compareCoinIds(url, urlToCompare, comparison); }; this.data = { curve, type, subtype }; } /** * Static method to create an instance from CBOR data. * It processes the raw CBOR data if needed and returns a new instance of the class. */ static fromCBORData(val, tagged) { // Do some post processing data coming from the cbor decoder const data = this.postCBOR(val); const { curve, type, subtype } = data; // Return an instance of the generated class return new this(curve, type, subtype); } /** * Create an Iterator that returns all the parents of this CoinIdentity * @returns {Iterable<CoinIdentity>} An iterator for all the parent CoinIdentities of the current CoinIdentity */ getAllParents() { let currentParent = this.getParent(); const parentIterator = { [Symbol.iterator]() { return { next() { if (currentParent) { const returnParent = new CoinIdentity(currentParent.getCurve(), currentParent.getType(), currentParent.getSubType()); currentParent = currentParent.getParent(); return { value: returnParent, done: false, }; } return { value: undefined, done: true }; }, }; }, }; return parentIterator; } /** * Compare a coin url, generated with '.toUrl()' method, with a different one * @param coinUrl1 first coinIdentity as a url. * @param coinUrl2 second coinIdentity as a url. * @param comparison comparison method. * @returns boolean indicating if the comparison is valid */ static compareCoinIds(coinUrl1, coinUrl2, comparison) { const dict = CoinIdentity.compareCoinIdsDict(coinUrl1, coinUrl2); return dict[comparison]; } /** * Creates a dictionary for all comparison methods for two given coin urls, generated with '.toUrl()'. * @param coinUrl1 first coinIdentity as a url. * @param coinUrl2 second coinIdentity as a url. * @returns dictionary indicating which comparison methods are true | false. */ static compareCoinIdsDict(coinUrl1, coinUrl2) { const url = coinUrl1.replace('bc-coin://', ''); const urlToCompare = coinUrl2.replace('bc-coin://', ''); const isEqual = url === urlToCompare; const isChild = url.includes(urlToCompare); const isParent = urlToCompare.includes(url); const isNotEqual = url !== urlToCompare; return { [ComparisonMethod.ExactMatch]: isEqual, [ComparisonMethod.Child]: isChild, [ComparisonMethod.Parent]: isParent, [ComparisonMethod.NotEqual]: isNotEqual, [ComparisonMethod.LessThanOrEqual]: isEqual || isChild, [ComparisonMethod.GreaterThanOrEqual]: isEqual || isParent, }; } } exports.CoinIdentity = CoinIdentity; /** * Convert a url into a CoinIdentity * @param url url representation of a CoinIdentity * @returns {CoinIdentity} created from the passed url. */ CoinIdentity.fromUrl = (url) => { const parts = url.split('://')[1].split('/'); const subtypeParts = parts[0].split('.'); if (subtypeParts.length > 1) { const curve = subtypeParts[subtypeParts.length - 1]; const type = +parts[1]; const subTypes = subtypeParts.slice(0, subtypeParts.length - 1); return new CoinIdentity(curve, type, subTypes); } const curve = parts[0]; const type = +parts[1]; return new CoinIdentity(curve, type); }; //# sourceMappingURL=CoinIdentity.js.map