UNPKG

stellar-keystore

Version:

A library to aid in the generation of stellar keystore files

185 lines (140 loc) 6.78 kB
'use strict'; exports.__esModule = true; exports.StellarKeystore = undefined; var _stellarSdk = require('stellar-sdk'); var StellarSdk = _interopRequireWildcard(_stellarSdk); var _tweetnacl = require('tweetnacl'); var _tweetnacl2 = _interopRequireDefault(_tweetnacl); var _tweetnaclUtil = require('tweetnacl-util'); var _tweetnaclUtil2 = _interopRequireDefault(_tweetnaclUtil); var _scryptAsync = require('scrypt-async'); var _scryptAsync2 = _interopRequireDefault(_scryptAsync); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var version = 'stellarport-1-20-2018'; var latestScryptOptions = { N: 16384, r: 8, p: 1, dkLen: _tweetnacl2.default.secretbox.keyLength, encoding: 'binary' }; var StellarKeystore = exports.StellarKeystore = function () { function StellarKeystore() { _classCallCheck(this, StellarKeystore); } /** * Retrieves a public key from a keystore file or json object. * @param keystore<Blob|Object> * @returns {Promise<StellarSdk.Keypair>} */ StellarKeystore.prototype.publicKey = function publicKey(keystore) { return this._fileContents(keystore).then(function (keystoreData) { return keystoreData.address; }); }; /** * Retrieves a stellar keypair from a keystore file or json object. * @param keystore<Blob|Object> * @param password<string> * @returns {Promise<StellarSdk.Keypair>} */ StellarKeystore.prototype.keypair = function keypair(keystore, password) { var _this = this; var keystoreData = void 0; return this._fileContents(keystore).then(function (_keystoreData) { keystoreData = _keystoreData; return _this._keyFromPassword(password, _tweetnaclUtil2.default.decodeBase64(keystoreData.crypto.salt), keystoreData.crypto.scryptOptions); }).then(function (key) { var secretKey = _tweetnacl2.default.secretbox.open(_tweetnaclUtil2.default.decodeBase64(keystoreData.crypto.ciphertext), _tweetnaclUtil2.default.decodeBase64(keystoreData.crypto.nonce), key); if (!secretKey) { throw new Error('Decryption failed. The file or password supplied is invalid.'); } var keypair = StellarSdk.Keypair.fromSecret(_tweetnaclUtil2.default.encodeUTF8(secretKey)); if (keypair.publicKey() !== keystoreData.address) { throw new Error('The supplied keystore file inconsistent - public key does not match secret key.'); } return keypair; }); }; /** * Creates a keystore file (using the provided keypair or a random keypair) and downloads it. * @deprecated * @param password * @param filename * @param [keypair] * @returns {Promise<StellarSdk.Keypair>} */ StellarKeystore.prototype.createAndDownload = function createAndDownload(password, filename, keypair) { var _this2 = this; return this.create(password, keypair).then(function (createdData) { _this2._download(filename, JSON.stringify(createdData.walletData)); return createdData.keypair; }); }; /** * Creates a keystore file's contents using a provided password and the provided keypair or random keypair. Returns a json object representing the keypair file. * @param password * @param [keypair] * @returns {Promise<{keypair: StellarSdk.Keypair, fileData: {}}>} */ StellarKeystore.prototype.create = function create(password, keypair) { var _this3 = this; var newKeypair = keypair || StellarSdk.Keypair.random(); var salt = _tweetnacl2.default.randomBytes(32); return this._keyFromPassword(password, salt, latestScryptOptions).then(function (key) { var nonce = _this3._randomNonce(); var ciphertext = _tweetnacl2.default.secretbox(_tweetnaclUtil2.default.decodeUTF8(newKeypair.secret()), nonce, key); return { keypair: newKeypair, walletData: { version: version, address: newKeypair.publicKey(), crypto: { ciphertext: _tweetnaclUtil2.default.encodeBase64(ciphertext), nonce: _tweetnaclUtil2.default.encodeBase64(nonce), salt: _tweetnaclUtil2.default.encodeBase64(salt), scryptOptions: latestScryptOptions } } }; }); }; StellarKeystore.prototype._download = function _download(filename, text) { var element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename + '.strz'); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); }; StellarKeystore.prototype._fileContents = function _fileContents(file) { // Check if this is a blob (for browser use). if (!file.size || isNaN(parseInt(file.size))) { return Promise.resolve(file); } var fileReader = new FileReader(); fileReader.readAsText(file); return new Promise(function (resolve, reject) { fileReader.onload = function (event) { try { resolve(JSON.parse(event.target.result)); } catch (e) { reject(new Error('Decryption failed. The file is not a valid keystore file.')); } }; }); }; StellarKeystore.prototype._keyFromPassword = function _keyFromPassword(password, salt) { var scryptOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : latestScryptOptions; return new Promise(function (resolve, reject) { (0, _scryptAsync2.default)(password, salt, scryptOptions, resolve); }); }; StellarKeystore.prototype._randomNonce = function _randomNonce() { return _tweetnacl2.default.randomBytes(_tweetnacl2.default.secretbox.nonceLength); }; return StellarKeystore; }();