UNPKG

digibyte-js

Version:

A pure and powerful JavaScript DigiByte library.

117 lines (97 loc) 4.05 kB
const Hash = require("./crypto/hash"); const Mnemonic = require("./mnemonic"); const HDPrivateKey = require("./hdprivatekey"); const Message = require("./message"); const PrivateKey = require("./privatekey"); const Address = require("./address"); /** * Instances a DigiID object. * @param {*} uri - DigiID url */ function DigiID(uri) { if (uri instanceof DigiID) return uri; if (typeof uri != 'string') throw 'Invalid type'; if (uri.substr(0, 9) !== 'digiid://') throw new Error("Not a DigiID uri"); let params = {}; uri.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) { params[key] = value; }); this.params = params; let paramsStart = uri.indexOf("?"); if (this.params.x === undefined) { var x = (new Date()).getTime().toString(16); uri += (paramsStart === -1) ? '?x=' + x : '&x=' + x; } if (this.params.assetId !== undefined) { this.asset = this.params["assetId"]; } else { this.asset = false; } if (this.params.tos !== undefined) { this.contract = Buffer.from(this.params.tos, 'base64'); } else { this.contract = false; } this.unsafe = this.params.u !== undefined; this.uri = uri; this.callback = (this.unsafe ? 'http://' : 'https://') + uri.substr(9, (paramsStart === -1) ? undefined : paramsStart - 9); this.domain = uri.match(/^digiid\:\/\/([^\/?#]+)(?:[\/?#]|$)/i)[1]; } DigiID.prototype._path = function (index = 0) { var indexBuffer = Buffer.alloc(4); indexBuffer.writeUInt32LE(index, 0); var toHash = Buffer.concat([indexBuffer, Buffer.from(this.callback)]) var hash = Hash.sha256(toHash); var A = hash.slice(0, 4).readUInt32LE() % 0x80000000; var B = hash.slice(4, 8).readUInt32LE() % 0x80000000; var C = hash.slice(8, 12).readUInt32LE() % 0x80000000; var D = hash.slice(12, 16).readUInt32LE() % 0x80000000; return `m/13'/${A}'/${B}'/${C}'/${D}'`; } DigiID.prototype.sign = function (secret, index = 0, address, assetAddress, assetKey) { if (typeof secret == 'string') { if (Mnemonic.isValid(secret)) var hdPrivateKey = (new Mnemonic(secret)).toHDPrivateKey(); else if (secret.startsWith('xprv')) var hdPrivateKey = HDPrivateKey.fromString(secret); else if (PrivateKey.isValid(secret)) var privateKey = new PrivateKey(secret); } else if (secret instanceof HDPrivateKey) var hdPrivateKey = secret; else if (secret instanceof PrivateKey) var privateKey = secret; if (!hdPrivateKey && !privateKey) throw 'Invalid secret'; if (hdPrivateKey) { var path = this._path(index); var privateKey = hdPrivateKey.deriveChild(path).privateKey; } if (!Address.isValid(address)) address = privateKey.toAddress().toString(); var signature = new Message(this.uri).sign(privateKey); var result = { uri: this.uri, address, signature }; if (this.asset.dual) { if (!Address.isValid(assetAddress)) throw "Invalid asset address"; if (!PrivateKey.isValid(assetKey)) throw "Invalid asset private key"; result.assetaddress = assetAddress; result.assetsignature = new Message(this.uri).sign(new PrivateKey(assetKey)); } return result; } DigiID.prototype.login = async function (secret, index = 0, address, assetAddress, assetKey) { try { var data = await fetch(this.callback, { method: "POST", body: JSON.stringify(this.sign(secret, index = 0, address, assetAddress, assetKey)), headers: { "Content-type": "application/json; charset=UTF-8" } }); return data.status === 200; } catch { return { error: 'Invalid response' }; } } DigiID.verify = function ({ uri, address, signature }) { return new Message(uri).verify(address, signature); } module.exports = DigiID;