UNPKG

eosplayer

Version:

eosplayer is the glue layer of eosjs, which is packaged based on eosjs and provides better usability for the application layer. It can be used on browsers already installed scatter or in Dapp wallets.

416 lines 20.4 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var libs_1 = require("../../types/libs"); var db_1 = require("./db"); var player_1 = require("../../player"); var wait_1 = require("../../utils/wait"); var log_1 = require("../../utils/log"); var scatterjs_core_1 = require("scatterjs-core"); var scatterjs_plugin_eosjs_1 = require("scatterjs-plugin-eosjs"); // Don't forget to tell ScatterJS which plugins you are using. scatterjs_core_1.default.plugins(new scatterjs_plugin_eosjs_1.default()); var log = log_1.createLogger('scatterPlayer'); /** * Event names supported in scatter player * @type {{ERR_GET_SCATTER_FAILED: string, ERR_GET_IDENTITY_FAILED: string}} */ var EVENT_NAMES = { ERR_GET_SCATTER_FAILED: 'ERR_GET_SCATTER_FAILED', ERR_GET_IDENTITY_FAILED: 'ERR_GET_IDENTITY_FAILED', ERR_LOGOUT_FAILED: 'ERR_LOGOUT_FAILED', ERR_CONF_NOT_FOUND: 'ERR_CONF_NOT_FOUND', }; /** * Player on browser (need scatter) * @author kinghand@foxmail.com */ var ScatterPlayer = /** @class */ (function (_super) { __extends(ScatterPlayer, _super); function ScatterPlayer(_networks) { var _this = _super.call(this) || this; _this._networks = _networks; _this.identityReceiver = []; _this.storage = new db_1.default({ network_name: 'dev', lang: 'ch', }); _this.events.enableEvents(EVENT_NAMES); log.info("eos player created: \n" + _this.netName + " \n" + JSON.stringify(_this.netConf, null, 2)); return _this; } /** * switch to an network with name * @param key */ ScatterPlayer.prototype.switchNetwork = function (key) { if (key in this._networks) { this.storage.set('network_name', key); this._eosClient = undefined; log.info("network changed to " + this.netName + " " + this.netConf + "."); } else { log.warning("network " + key + " cannot find."); } }; /** * add net config to table at runtime * @param netName * @param conf */ ScatterPlayer.prototype.setNetConf = function (netName, conf) { this._networks[netName] = conf; }; Object.defineProperty(ScatterPlayer.prototype, "netName", { /** * get network name in use */ get: function () { return this.storage.get('network_name'); }, enumerable: true, configurable: true }); Object.defineProperty(ScatterPlayer.prototype, "netConf", { /** * get network config of cur netName */ get: function () { var conf = this._networks[this.netName]; if (!conf) { this.events.emitEvent(EVENT_NAMES.ERR_CONF_NOT_FOUND, new Error("cannot find config of " + this.netName)); } return conf; }, enumerable: true, configurable: true }); Object.defineProperty(ScatterPlayer.prototype, "scatter", { /** * try get scatter * @see https://get-scatter.com/docs/examples-interaction-flow * @return {Scatter} */ get: function () { var scatter = window.scatter; if (!scatter) { var err = new Error('scatter cannot found'); this.events.emitEvent(EVENT_NAMES.ERR_GET_SCATTER_FAILED, err); // throw err; } return scatter; }, enumerable: true, configurable: true }); /** * try get scatter async - if not find * @see https://get-scatter.com/docs/examples-interaction-flow * @return {Scatter} */ ScatterPlayer.prototype.getScatterAsync = function (maxTry) { if (maxTry === void 0) { maxTry = 100; } return __awaiter(this, void 0, void 0, function () { var _a, err; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!(!window.scatter && maxTry--)) return [3 /*break*/, 3]; log.verbose('get scatter failed, retry :', maxTry); _a = window; return [4 /*yield*/, this.getPCScatter()]; case 1: _a.scatter = _b.sent(); return [4 /*yield*/, wait_1.forMs(100)]; case 2: _b.sent(); return [3 /*break*/, 0]; case 3: if (!window.scatter) { err = new Error('scatter cannot found'); this.events.emitEvent(EVENT_NAMES.ERR_GET_SCATTER_FAILED, err); } return [2 /*return*/, window.scatter]; } }); }); }; ScatterPlayer.prototype.getPCScatter = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve) { scatterjs_core_1.default.scatter.connect('CryptoThrone').then(function (connected) { if (!connected) return false; resolve(scatterjs_core_1.default.scatter); }); })]; }); }); }; /** * login - require account identity from scatter * @return {Promise<{Identity}>} */ ScatterPlayer.prototype.login = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getIdentity()]; }); }); }; /** * logout * @return {Promise<void>} */ ScatterPlayer.prototype.logout = function () { return __awaiter(this, void 0, void 0, function () { var ret, err_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, , 4]); return [4 /*yield*/, this.getScatterAsync()]; case 1: return [4 /*yield*/, (_a.sent()).forgetIdentity()]; case 2: ret = _a.sent(); log.info("log out from " + this.storage.get('latest_chain_id')); return [2 /*return*/, ret]; case 3: err_1 = _a.sent(); this.events.emitEvent(EVENT_NAMES.ERR_LOGOUT_FAILED, err_1); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; Object.defineProperty(ScatterPlayer.prototype, "eosClient", { /** * get or create scatter * @return {eosAPI} */ get: function () { if (!this._eosClient) { var conf = this.netConf; console.log('this.scatter', this.scatter); console.log('this.scatter.eos', this.scatter.eos); // console.log('Eos', Eos) var firstColon = conf.httpEndpoint.indexOf(':'); var nextColon = conf.httpEndpoint.indexOf(':', firstColon + 1); var protocol = conf.httpEndpoint.substr(0, firstColon); var host = nextColon < 0 ? conf.httpEndpoint.substr(firstColon + 3) : conf.httpEndpoint.substr(firstColon + 3, nextColon - firstColon - 3); var port = nextColon < 0 ? (protocol === 'https' ? '443' : '80') : conf.httpEndpoint.substr(nextColon + 1); console.log('protocol', protocol, host, port); conf.host = host; conf.port = port; console.log('conf', conf); this._eosClient = this.scatter.eos(conf, libs_1.Eos, {}, protocol); } if (!this._eosClient) { throw new Error('cannot create _eosClient'); } return this._eosClient; }, enumerable: true, configurable: true }); /** * getIdentity of cur scatter user * @attention When there are multiple concurrent getIdentity requests, scatter will only return the first one. * @return {Promise<{Identity}>} */ ScatterPlayer.prototype.getIdentity = function () { return __awaiter(this, void 0, void 0, function () { function receiveInstanceOrError(_identity) { identity = _identity; } var _scatter, originChainID, chainID, identity; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getScatterAsync()]; case 1: _scatter = _a.sent(); originChainID = this.storage.get('latest_chain_id'); chainID = this.netConf.chainId; if (!((!!originChainID) && chainID !== originChainID)) return [3 /*break*/, 3]; log.info("a changing of chain_id detected: " + originChainID + " -> " + chainID + " "); return [4 /*yield*/, this.logout()]; case 2: _a.sent(); _a.label = 3; case 3: this.storage.set('latest_chain_id', chainID); this.identityReceiver.push(receiveInstanceOrError); if (this.identityReceiver.length <= 1) { _scatter.getIdentity({ accounts: [this.netConf], }).then(function () { _this.identityReceiver.forEach(function (receiver) { return receiver(_scatter.identity ? _scatter.identity.accounts.find(function (acc) { return acc.blockchain === 'eos'; }) : undefined); }); _this.identityReceiver = []; }).catch(function (err) { _this.identityReceiver.forEach(function (receiver) { return receiver(err); }); _this.identityReceiver = []; }); } return [4 /*yield*/, wait_1.forCondition(function () { return !!identity; })]; case 4: _a.sent(); // using undefined to block operation, using null to handle error if (identity instanceof Error || (identity.isError)) { this.events.emitEvent(EVENT_NAMES.ERR_GET_IDENTITY_FAILED, identity); throw identity; } return [2 /*return*/, identity]; } }); }); }; /** * sign a message with current identity * @param {string} message - message to sign * @param {... ISignPlugin[]} signPlugins - signer map's list * @return {Promise<void>} - signed data * @constructor */ ScatterPlayer.prototype.sign = function (message) { var signPlugins = []; for (var _i = 1; _i < arguments.length; _i++) { signPlugins[_i - 1] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var identity, account, permissions, perm, _a, accounts, keys, pubKeys, _loop_1, i, ret, i, ex_1; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.getIdentity()]; case 1: identity = _b.sent(); account = identity.name; return [4 /*yield*/, this.getAccountInfo(account)]; case 2: permissions = (_b.sent()).permissions; if (!permissions) { log.warning("permissions of account " + account + " are not found."); return [2 /*return*/]; } perm = permissions.find(function (p) { return p.perm_name === identity.authority; }); log.info("perm : " + JSON.stringify(perm)); _a = perm.required_auth, accounts = _a.accounts, keys = _a.keys; pubKeys = keys || []; _loop_1 = function (i) { var signPlugin, converted; return __generator(this, function (_a) { switch (_a.label) { case 0: signPlugin = signPlugins[i]; if (!signPlugin) { throw new Error("Sign Plugin Error : cannot parse the " + i + "'th plugin"); } return [4 /*yield*/, Promise.all(accounts .map(function (acc) { return acc.permission.actor + "@" + acc.permission.permission; }) .map(function (accStr) { return signPlugin.signKeyProvider[accStr]; }) .filter(function (_) { return _; }) .map(function (signKeyProvider) { return Promise.resolve(signKeyProvider(account, _this.chain)); }))]; case 1: converted = _a.sent(); pubKeys = pubKeys.concat(converted.map(function (key) { return ({ key: key }); })); return [2 /*return*/]; } }); }; i = 0; _b.label = 3; case 3: if (!(signPlugins && i < signPlugins.length)) return [3 /*break*/, 6]; return [5 /*yield**/, _loop_1(i)]; case 4: _b.sent(); _b.label = 5; case 5: i++; return [3 /*break*/, 3]; case 6: ret = ''; i = 0; _b.label = 7; case 7: if (!(i < pubKeys.length)) return [3 /*break*/, 12]; _b.label = 8; case 8: _b.trys.push([8, 10, , 11]); log.info("try sign (" + JSON.stringify(pubKeys[i]) + ") : " + message); return [4 /*yield*/, this.scatter.getArbitrarySignature(pubKeys[i].key, message)]; case 9: ret = _b.sent(); return [3 /*break*/, 12]; case 10: ex_1 = _b.sent(); log.warning("try pub key failed " + pubKeys[i]); return [3 /*break*/, 11]; case 11: i++; return [3 /*break*/, 7]; case 12: return [2 /*return*/, ret]; } }); }); }; ScatterPlayer.prototype.help = function () { return _super.prototype.help.call(this) + "\n\n## Usage of eosplayer (for broswer)\n\n### Events\n\nERR_GET_SCATTER_FAILED\nERR_GET_IDENTITY_FAILED\nERR_LOGOUT_FAILED\n\n### APIs\n\n```js\n{void} eosplayer.switchNetwork(val) // switch network\n{void} eosplayer.setNetConf(network_name, conf) // add a network config at runtime\n\nget {Scatter} eosplayer.scatter // get scatter instance\nget {Scatter} async getScatterAsync(maxTry = 100) // get scatter instance\n\nget {string} eosplayer.netName // get current network name\nget {string} eosplayer.netConf // get current network config\n\nasync {Identity} eosplayer.login() // let user allow you using identity\nasync {void} eosplayer.logout() // return back the identity\n\nasync {string} sign(message) // sign a message with current identity\n```\n\n## Imported libs\n\n```js\nwindow.eosjs = Eos; /** the eosjs lib @see {@url https://www.npmjs.com/package/eosjs} */\nwindow.env = env; /** {isPc} */\nwindow.idb = idb; /** idb lib for browser storage @see {@url https://www.npmjs.com/package/idb } */\nwindow.BigNumber = BigNumber; /** big number @see {@url https://www.npmjs.com/package/bignumber.js} */\n\nwindow.kh.eos.Player\nwindow.kh.eos.ScatterPlayer\nwindow.eosplayer = new ScatterPlayer(networks);\n```\n"; }; return ScatterPlayer; }(player_1.Player)); exports.ScatterPlayer = ScatterPlayer; //# sourceMappingURL=scatterPlayer.js.map