UNPKG

@aeternity/aepp-sdk

Version:
285 lines (251 loc) 9.77 kB
import _typeof from "@babel/runtime-corejs3/helpers/typeof"; import _toConsumableArray from "@babel/runtime-corejs3/helpers/toConsumableArray"; import _slicedToArray from "@babel/runtime-corejs3/helpers/slicedToArray"; import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys"; import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat"; import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign"; import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter"; import _Promise from "@babel/runtime-corejs3/core-js-stable/promise"; /** * RpcClient module * * @module @aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client * @export { RpcClient, RpcClients } * @example import RpcClient from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client' */ import stampit from '@stamp/it'; import { METHODS, RPC_STATUS, SUBSCRIPTION_TYPES } from '../schema'; import { sendMessage, message, isValidAccounts } from '../helpers'; /** * Contain functionality for using RPC conection * @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/rpc-client * @function * @rtype Stamp * @param {Object} param Init params object * @param {String} param.name Client name * @param {Object} param.connection Connection object * @param {Function[]} param.handlers Arrays with two function for handling messages ([ onMessage: Function, onDisconnect: Function]) * @return {Object} */ export default stampit({ init: function init(_ref) { var _this = this; var id = _ref.id, name = _ref.name, networkId = _ref.networkId, icons = _ref.icons, connection = _ref.connection, _ref$handlers = _slicedToArray(_ref.handlers, 2), onMessage = _ref$handlers[0], onDisconnect = _ref$handlers[1]; this.id = id; this.connection = connection; this.info = { name: name, networkId: networkId, icons: icons }; // { // [msg.id]: { resolve, reject } // } this.callbacks = {}; // ['connected', 'current'] this.addressSubscription = []; // { // connected: { [pub]: {...meta} }, // current: { [pub]: {...meta} } // } this.accounts = {}; this.sendMessage = sendMessage(this.connection); var handleMessage = function handleMessage(msg, origin) { if (!msg || !msg.jsonrpc || msg.jsonrpc !== '2.0' || !msg.method) { throw new Error("Received invalid message: ".concat(msg)); } onMessage(msg, origin); }; var disconnect = function disconnect(aepp, connection) { _this.disconnect(true); typeof onDisconnect === 'function' && onDisconnect(connection, _this); }; connection.connect(handleMessage, disconnect); }, propertyDescriptors: { currentAccount: { enumerable: true, configurable: false, get: function get() { return this.isHasAccounts() ? _Object$keys(this.accounts.current)[0] : undefined; } }, addresses: { enumerable: true, configurable: false, get: function get() { var _context; return this.isHasAccounts() ? _concatInstanceProperty(_context = []).call(_context, _toConsumableArray(_Object$keys(this.accounts.current)), _toConsumableArray(_Object$keys(this.accounts.connected))) : []; } }, origin: { enumerable: true, configurable: false, get: function get() { return this.connection; } } }, methods: { /** * Update info * @function updateInfo * @instance * @rtype (info: Object) => void * @param {Object} info Info to update (will be merged with current info object) * @return {void} */ updateInfo: function updateInfo(info) { _Object$assign(this.info, info); }, isHasAccounts: function isHasAccounts() { return _typeof(this.accounts) === 'object' && _typeof(this.accounts.connected) === 'object' && _typeof(this.accounts.current) === 'object'; }, isSubscribed: function isSubscribed() { return this.addressSubscription.length && this.isHasAccounts(); }, /** * Check if aepp has access to account * @function hasAccessToAccount * @instance * @rtype (address: String) => Boolean * @param {String} address Account address * @return {Boolean} is connected */ hasAccessToAccount: function hasAccessToAccount(address) { var _context2; return !!address && _findInstanceProperty(_context2 = this.addresses).call(_context2, function (a) { return a === address; }); }, /** * Check if is connected * @function isConnected * @instance * @rtype () => Boolean * @return {Boolean} is connected */ isConnected: function isConnected() { return this.connection.isConnected() && this.info.status === RPC_STATUS.CONNECTED; }, /** * Get selected account * @function getCurrentAccount * @instance * @rtype ({ onAccount } = {}) => String * @param {Object} options Options * @return {String} */ getCurrentAccount: function getCurrentAccount() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, onAccount = _ref2.onAccount; return onAccount || _Object$keys(this.accounts.current)[0]; }, /** * Disconnect * @function disconnect * @instance * @rtype () => void * @return {void} */ disconnect: function disconnect() { var forceConnectionClose = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; this.info.status = RPC_STATUS.DISCONNECTED; this.addressSubscription = []; this.accounts = {}; forceConnectionClose || this.connection.disconnect(); }, /** * Update accounts and sent `update.address` notification to AEPP * @param {{ current: Object, connected: Object }} accounts Object with current and connected accounts * @param {{ forceNotification: Boolean }} [options={ forceNotification: false }] Don not sent update notification to AEPP */ setAccounts: function setAccounts(accounts) { var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref3$forceNotificati = _ref3.forceNotification, forceNotification = _ref3$forceNotificati === void 0 ? false : _ref3$forceNotificati; if (!isValidAccounts(accounts)) { throw new Error('Invalid accounts object. Should be object like: `{ connected: {}, selected: {} }`'); } this.accounts = accounts; if (!forceNotification) { // Sent notification about account updates this.sendMessage(message(METHODS.wallet.updateAddress, this.accounts), true); } }, /** * Update subscription * @function updateSubscription * @instance * @rtype (type: String, value: String) => void * @param {String} type Subscription type * @param {String} value Subscription value * @return {String[]} */ updateSubscription: function updateSubscription(type, value) { var _context3, _context4; if (type === SUBSCRIPTION_TYPES.subscribe && !_includesInstanceProperty(_context3 = this.addressSubscription).call(_context3, value)) { this.addressSubscription.push(value); } if (type === SUBSCRIPTION_TYPES.unsubscribe && _includesInstanceProperty(_context4 = this.addressSubscription).call(_context4, value)) { var _context5; this.addressSubscription = _filterInstanceProperty(_context5 = this.addressSubscription).call(_context5, function (s) { return s !== value; }); } return this.addressSubscription; }, /** * Make a request * @function request * @instance * @rtype (name: String, params: Object) => Promise * @param {String} name Method name * @param {Object} params Method params * @return {Promise} Promise which will be resolved after receiving response message */ request: function request(name, params) { var _this2 = this; var msgId = this.sendMessage(message(name, params)); if (Object.prototype.hasOwnProperty.call(this.callbacks, msgId)) throw new Error('Callback Already exist'); return new _Promise(function (resolve, reject) { _this2.callbacks[msgId] = { resolve: resolve, reject: reject }; }); }, /** * Process response message * @function processResponse * @instance * @rtype (msg: Object, transformResult: Function) => void * @param {Object} msg Message object * @param {Function=} transformResult Optional parser function for message * @return {void} */ processResponse: function processResponse(_ref4, transformResult) { var id = _ref4.id, error = _ref4.error, result = _ref4.result; if (!this.callbacks[id]) throw new Error("Can't find callback for this messageId ".concat(id)); if (result) { var _this$callbacks$id; (_this$callbacks$id = this.callbacks[id]).resolve.apply(_this$callbacks$id, _toConsumableArray(typeof transformResult === 'function' ? transformResult({ id: id, result: result }) : [result])); } else { this.callbacks[id].reject(error); } delete this.callbacks[id]; } } }); //# sourceMappingURL=rpc-client.js.map