UNPKG

keystore_wdc

Version:

``` npm i keystore_wdc; const KeyStore = require('keystore_wdc'); const ks = new KeyStore(); ``` #### 生成keystore ``` async function create(){ const keystore = await ks.Create("your password"); } ``` * 返回keystore,密码格式不正确返回-1。

417 lines 15.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RPC = void 0; var types_1 = require("./types"); var utils_1 = require("./utils"); var rlp_1 = require("./rlp"); var contract_1 = require("./contract"); var rlp = require("./rlp"); var BN = require("../bn"); var RPC = /** @class */ (function () { /** * * @param host 主机名 * @param port 端口号 * @param timeout 超时时间,单位是秒,默认15秒 */ function RPC(host, port, timeout) { this.host = host || 'localhost'; this.port = (port || 80).toString(); this.timeout = timeout || 15; this.callbacks = new Map(); // id -> function this.id2key = new Map(); // id -> address:event this.id2hash = new Map(); // id -> txhash this.eventHandlers = new Map(); // address:event -> [id] this.txObservers = new Map(); // hash -> [id] this.cid = 0; this.rpcCallbacks = new Map(); // nonce -> cb this.nonce = 0; } RPC.prototype.tryConnect = function () { var _this = this; var WS; if (typeof WebSocket === 'function') WS = WebSocket; else WS = require('ws'); if (this.ws && this.ws.readyState === this.ws.OPEN) { return Promise.resolve(); } if (this.ws && this.ws.readyState === this.ws.CONNECTING) { var fn_1 = this.ws.onopen || (function (e) { }); var _rj_1 = this.ws.onerror || (function (e) { }); var p_1 = new Promise(function (rs, rj) { _this.ws.onopen = function (e) { fn_1.call(_this.ws, e); rs(); }; _this.ws.onerror = function (e) { _rj_1.call(_this.ws, e); rj(e); }; }); return p_1; } this.uuid = utils_1.uuidv4(); this.ws = new WS("ws://" + this.host + ":" + (this.port || 80) + "/websocket/" + this.uuid); this.ws.onerror = console.error; this.ws.onmessage = function (e) { if (typeof WebSocket !== 'function') { _this.handleData(e.data); return; } var reader = new FileReader(); reader.onload = function () { var arrayBuffer = reader.result; _this.handleData(new Uint8Array(arrayBuffer)); }; reader.readAsArrayBuffer(e.data); }; var p = new Promise(function (rs, rj) { _this.ws.onopen = rs; _this.ws.onerror = rj; }); return p; }; RPC.prototype.parse = function (data) { var decoded = rlp.decode(data); var nonce = rlp_1.byteArrayToInt(decoded[0]); var code = rlp_1.byteArrayToInt(decoded[1]); var body = decoded[2]; var r = { code: code, nonce: nonce, body: body }; switch (code) { case types_1.WS_CODES.TRANSACTION_EMIT: { var h = utils_1.bin2hex(body[0]); var s = rlp_1.byteArrayToInt(body[1]); var ret = r; ret.hash = h; ret.status = s; if (s === types_1.TX_STATUS.DROPPED) { ret.reason = utils_1.bin2str(body[2]); } if (s === types_1.TX_STATUS.INCLUDED) { var arr = body[2]; ret.blockHeight = utils_1.toSafeInt(arr[0]); ret.blockHash = utils_1.bin2hex(arr[1]); ret.gasUsed = utils_1.toSafeInt(arr[2]); ret.result = arr[3]; ret.events = arr[4]; } return ret; } case types_1.WS_CODES.EVENT_EMIT: { var ret = r; ret.addr = utils_1.bin2hex(body[0]); ret.name = utils_1.bin2str(body[1]); ret.fields = body[2]; return ret; } } return r; }; RPC.prototype.handleData = function (data) { var _this = this; var r = this.parse(data); switch (r.code) { case types_1.WS_CODES.TRANSACTION_EMIT: { var t_1 = r; var funcIds = this.txObservers.get(t_1.hash) || []; funcIds.forEach(function (id) { var func = _this.callbacks.get(id); func(t_1); }); return; } case types_1.WS_CODES.EVENT_EMIT: { var e_1 = r; var funcIds = this.eventHandlers.get(e_1.addr + ":" + e_1.name) || []; funcIds.forEach(function (id) { var func = _this.callbacks.get(id); func(e_1); }); return; } } if (r.nonce) { var fn = this.rpcCallbacks.get(r.nonce); if (fn) fn(r); this.rpcCallbacks.delete(r.nonce); } }; /** * 监听合约事件 */ RPC.prototype.__listen = function (contract, event, func) { var addr = utils_1.normalizeAddress(contract.address); var addrHex = utils_1.bin2hex(addr); this.wsRpc(types_1.WS_CODES.EVENT_SUBSCRIBE, addr); var id = ++this.cid; var key = addrHex + ":" + event; this.id2key.set(id, key); var fn = function (e) { var abiDecoded = contract.abiDecode(event, e.fields, 'event'); func(abiDecoded); }; if (!this.eventHandlers.has(key)) this.eventHandlers.set(key, new Set()); this.eventHandlers.get(key).add(id); this.callbacks.set(id, fn); return id; }; RPC.prototype.listen = function (contract, event, func) { var _this = this; if (func === undefined) { return new Promise(function (rs, rj) { _this.__listen(contract, event, rs); }); } utils_1.assert(typeof func === 'function', 'callback should be function'); this.__listen(contract, event, func); }; /** * 移除监听器 * @param {number} id 监听器的 id */ RPC.prototype.removeListener = function (id) { var key = this.id2key.get(id); var h = this.id2hash.get(id); this.callbacks.delete(id); this.id2key.delete(id); this.id2hash.delete(id); if (key) { var set = this.eventHandlers.get(key); set && set.delete(id); if (set && set.size === 0) this.eventHandlers.delete(key); } if (h) { var set = this.txObservers.get(h); set && set.delete(id); if (set && set.size === 0) this.txObservers.delete(h); } }; RPC.prototype.listenOnce = function (contract, event, func) { var _this = this; var id = this.cid + 1; if (func === undefined) return this.listen(contract, event).then(function (r) { _this.removeListener(id); return r; }); return this.listen(contract, event, function (p) { func(p); _this.removeListener(id); }); }; /** * 添加事务观察者,如果事务最终被确认或者异常终止,观察者会被移除 */ RPC.prototype.__observe = function (_hash, cb) { var _this = this; var hash = utils_1.bin2hex(_hash); var id = ++this.cid; hash = hash.toLowerCase(); if (!this.txObservers.has(hash)) this.txObservers.set(hash, new Set()); this.id2hash.set(id, hash); this.txObservers.get(hash).add(id); var fn = function (r) { cb(r); switch (r.status) { case types_1.TX_STATUS.DROPPED: case types_1.TX_STATUS.CONFIRMED: _this.removeListener(id); break; } }; this.callbacks.set(id, fn); return id; }; /** * 查看合约方法 */ RPC.prototype.viewContract = function (contract, method, parameters) { if (!(contract instanceof contract_1.Contract)) throw new Error('create a instanceof Contract by new tool.Contract(addr, abi)'); var normalized = contract_1.normalizeParams(parameters); var addr = contract.address; var params = contract.abiEncode(method, normalized); return this.wsRpc(types_1.WS_CODES.CONTRACT_QUERY, [ utils_1.normalizeAddress(addr), method, params ]).then(function (r) { return contract.abiDecode(method, rlp.decode(r.body)); }); }; /** * 通过 websocket 发送事务 * @param tx 事务 */ RPC.prototype.sendTransaction = function (tx) { return this.wsRpc(types_1.WS_CODES.TRANSACTION_SEND, [Array.isArray(tx), tx]) .then(function () { return Promise.resolve(); }); }; RPC.prototype.observe = function (tx, status, timeout) { var _this = this; status = status === undefined ? types_1.TX_STATUS.CONFIRMED : status; return new Promise(function (resolve, reject) { var success = false; if (timeout) setTimeout(function () { if (success) return; reject({ reason: 'timeout' }); }, timeout); var ret = {}; var confirmed = false; var included = false; var finished = false; _this.__observe(tx.getHash(), function (resp) { if (finished) return; if (resp.status === types_1.TX_STATUS.PENDING && status === types_1.TX_STATUS.PENDING) { finished = true; resolve({ transactionHash: resp.hash }); return; } if (resp.status === types_1.TX_STATUS.DROPPED) { finished = true; var e = { hash: resp.hash, reason: resp.reason }; reject(e); return; } if (resp.status === types_1.TX_STATUS.CONFIRMED) { if (status === types_1.TX_STATUS.INCLUDED) return; confirmed = true; if (included) { success = true; resolve(ret); return; } } if (resp.status === types_1.TX_STATUS.INCLUDED) { included = true; ret.blockHeight = resp.blockHeight; ret.blockHash = resp.blockHash; ret.gasUsed = resp.gasUsed; if (resp.result && resp.result.length && tx.__abi && tx.isDeployOrCall()) { var decoded = (new contract_1.Contract('', tx.__abi)).abiDecode(tx.getMethod(), resp.result); ret.result = decoded; } if (resp.events && resp.events.length && tx.__abi) { var events = []; for (var _i = 0, _a = resp.events; _i < _a.length; _i++) { var e = _a[_i]; var name_1 = utils_1.bin2str(e[0]); var decoded = (new contract_1.Contract('', tx.__abi)).abiDecode(name_1, e[1], 'event'); events.push({ name: name_1, data: decoded }); } ret.events = events; } ret.transactionHash = utils_1.bin2hex(tx.getHash()); ret.fee = utils_1.toSafeInt((new BN(tx.gasPrice).mul(new BN(ret.gasUsed)))); if (tx.isDeployOrCall()) { ret.method = tx.getMethod(); ret.inputs = tx.__inputs; } if (status === types_1.TX_STATUS.INCLUDED) { success = true; resolve(ret); return; } if (confirmed) { success = true; resolve(ret); } } }); }); }; RPC.prototype.wsRpc = function (code, data) { var _this = this; this.nonce++; var n = this.nonce; var tm = null; var ret = new Promise(function (rs, rj) { tm = setTimeout(function () { rj('websocket rpc timeout'); _this.rpcCallbacks.delete(n); }, _this.timeout * 1000); _this.rpcCallbacks.set(n, function (r) { if (tm) clearTimeout(tm); rs(r); }); }); this.tryConnect() .then(function () { var encoded = rlp.encode([n, code, data]); _this.ws.send(encoded); }); return ret; }; /** * 发送事务的同时监听事务的状态 */ RPC.prototype.sendAndObserve = function (tx, status, timeout) { var _this = this; var ret; var sub; if (Array.isArray(tx)) { var arr = []; sub = this.wsRpc(types_1.WS_CODES.TRANSACTION_SUBSCRIBE, tx.map(function (t) { return utils_1.hex2bin(t.getHash()); })); for (var _i = 0, tx_1 = tx; _i < tx_1.length; _i++) { var t = tx_1[_i]; arr.push(this.observe(t, status, timeout)); } ret = Promise.all(arr); } else { sub = this.wsRpc(types_1.WS_CODES.TRANSACTION_SUBSCRIBE, utils_1.hex2bin(tx.getHash())); ret = this.observe(tx, status, timeout); } return sub .then(function () { return _this.sendTransaction(tx); }) .then(function () { return ret; }); }; /** * 获取 nonce */ RPC.prototype.getNonce = function (_pkOrAddress) { var pkOrAddress = utils_1.normalizeAddress(_pkOrAddress); return this.wsRpc(types_1.WS_CODES.ACCOUNT_QUERY, pkOrAddress) .then(function (resp) { return utils_1.toSafeInt(new BN(resp.body[0][2])); }); }; /** * 获取 账户余额 */ RPC.prototype.getBalance = function (_pkOrAddress) { var pkOrAddress = utils_1.normalizeAddress(_pkOrAddress); return this.wsRpc(types_1.WS_CODES.ACCOUNT_QUERY, pkOrAddress) .then(function (resp) { return utils_1.toSafeInt(new BN(resp.body[0][3])); }); }; RPC.prototype.close = function () { if (this.ws) { var ws = this.ws; this.ws = null; ws.close(); } }; return RPC; }()); exports.RPC = RPC; //# sourceMappingURL=rpc.js.map