gamerpc 9.0.0 → 9.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/authConn.js CHANGED
@@ -1,396 +1,578 @@
1
1
  /**
2
- * authConn - 授权式连接器 (V7.1.2)
3
- *
4
- * 完整封装了客户端通过授权模式访问远程全节点的方法。
5
- * 可直接用于 node 环境下的服务端程序,通过合适的打包也可用于浏览器环境。
6
- *
7
- * 核心功能:
8
- * - setup() 配置网络类型和连接参数
9
- * - execute() 执行钱包 RPC 命令
10
- * - login() WS 模式下的 token 认证登录
11
- * - watch() 监听推送消息
12
- * - 支持 WS / HTTP GET / HTTP POST 三种通讯模式
2
+ * authConn - 授权式连接器
3
+ *
4
+ * 完整封装了客户端通过授权模式访问远程全节点的方法,仅仅依赖 create-hmac
5
+ * 可以直接用于 node 环境下的服务端程序,来访问远程全节点丰富的API接口
6
+ * 通过合适的打包程序,也可以用于浏览器环境
13
7
  */
14
- const assert = require('./utils/assert');
15
- const { io, Base64, now, CommStatus, ReturnCode, CommMode, NotifyType, stringify } = require('./utils/util');
16
- const { sha1, hash160, hash256, verifyData, generateKey, signObj, verifyObj, verifyAddress } = require('./utils/verifyData');
17
- const Secret = require('./utils/secret');
18
- const createHmac = require('create-hmac/browser');
8
+
9
+ const assert = require('./utils/assert')
10
+ const io = require('socket.io-client');
11
+ const {signHMAC, Base64, now, CommStatus, createHmac, ReturnCode, CommMode, NotifyType, encrypt, decrypt, stringify} = require('./utils/util');
12
+ let {sha1, hash160, hash256, verifyData, generateKey, signObj, verifyObj, verifyAddress} = require('./utils/verifyData');
13
+ const Secret = require('./utils/secret')
19
14
 
20
15
  /**
21
- * 利用 HMAC 算法,基于令牌固定量和令牌随机量计算访问令牌
22
- * @param {String} token 令牌固定量
23
- * @param {String} random 令牌随机量(从服务端获取)
24
- * @returns {String} HMAC 签名(hex)
16
+ * 终端配置管理
25
17
  */
26
- function signHMAC(token, random) {
27
- var hmac = createHmac('sha256', random);
28
- let sig = hmac.update(token).digest('hex');
29
- return sig;
30
- }
31
18
 
32
- class AuthConn {
33
- constructor() {
34
- this.defaultNetworkType = 'testnet';
35
- this.AuthConnConfig = {
36
- 'main': {
37
- type: 'main',
38
- ip: '127.0.0.1',
39
- port: 2002,
40
- head: 'http',
41
- id: 'primary',
42
- apiKey: '',
43
- cid: '',
44
- token: '',
45
- },
46
- 'testnet': {
47
- type: 'testnet',
48
- ip: '127.0.0.1',
49
- port: 2102,
50
- head: 'http',
51
- id: 'primary',
52
- apiKey: '',
53
- cid: '',
54
- token: '',
55
- },
56
- };
57
-
58
- this.socketEvents = {};
59
- this.mode = CommMode.post;
60
- this.socket = null;
61
- this.$params = {
62
- random: null,
63
- randomTime: null,
64
- };
19
+ class AuthConn
20
+ {
21
+ constructor() {
22
+ this.defaultNetworkType = 'testnet';
23
+ this.AuthConnConfig = {
24
+ 'main': {
25
+ type: 'main',
26
+ ip: '127.0.0.1', //远程服务器地址
27
+ port: 2002, //RPC端口
28
+ head: 'http', //远程服务器通讯协议,分为 http 和 https
29
+ id: 'primary', //默认访问的钱包编号
30
+ apiKey: '', //远程服务器基本校验密码
31
+ cid: '', //授权节点编号,用于访问远程钱包时的认证
32
+ token: '', //授权节点令牌固定量,用于访问远程钱包时的认证
33
+ },
34
+ 'testnet': {
35
+ type: 'testnet',
36
+ ip: '127.0.0.1', //远程服务器地址
37
+ port: 2102, //RPC端口
38
+ head: 'http', //远程服务器通讯协议,分为 http 和 https
39
+ id: 'primary', //默认访问的钱包编号
40
+ apiKey: '', //远程服务器基本校验密码
41
+ cid: '', //授权节点编号,用于访问远程钱包时的认证
42
+ token: '', //授权节点令牌固定量,用于访问远程钱包时的认证
43
+ },
65
44
  }
66
-
67
- /**
68
- * 设置通讯模式
69
- * @param {String} mode 通讯模式
70
- * @param {Function} cb 连接建立时的回调
71
- */
72
- setmode(mode, cb) {
73
- this.mode = mode;
74
- if (this.mode == CommMode.ws) {
75
- this.socketEvents['connect'] = async () => {
76
- await this.login();
77
- await this.join();
78
- if (typeof cb == 'function') {
79
- await cb();
80
- }
81
- };
45
+
46
+ this.socketEvents = {};
47
+ this.mode = CommMode.post;
48
+ this.socket = null;
49
+ this.$params = {
50
+ random: null,
51
+ randomTime: null,
52
+ };
53
+ }
54
+
55
+ /**
56
+ * 设置通讯模式
57
+ * @param {*} mode 通讯模式
58
+ * @param {*} cb 连接建立时的回调
59
+ */
60
+ setmode(mode, cb) {
61
+ this.mode = mode;
62
+ if(this.mode == CommMode.ws) {
63
+ this.socketEvents['connect'] = async () => {
64
+ await this.login();
65
+ await this.join();
66
+ if(typeof cb == 'function') {
67
+ await cb();
82
68
  }
83
- return this;
69
+ };
84
70
  }
85
-
86
- /**
87
- * 生成带 HMAC 签名的访问令牌参数
88
- * 流程:
89
- * 1. 切换到 WS 模式
90
- * 2. 调用 token.random 从服务端获取随机量
91
- * 3. 用 HMAC-SHA256 计算签名
92
- */
93
- async retoken() {
94
- let params = this.getTerminalConfig();
95
- let msg = await this.setmode(CommMode.ws).execute('token.random', [params.cid]);
96
- if (!!params.structured) {
97
- msg = msg.result;
98
- }
99
- const hmac = createHmac('sha256', msg);
100
- params.calc = hmac.update(params.token).digest('hex');
101
- return params;
71
+ return this;
72
+ }
73
+
74
+ async retoken() {
75
+ let params = this.getTerminalConfig();
76
+ let msg = await this.setmode(CommMode.ws).execute('token.random', [params.cid]);
77
+ if(!!params.structured) {
78
+ msg = msg.result;
102
79
  }
103
-
104
- /**
105
- * WS 模式下的登录流程
106
- * 调用 wallet.auth 进行钱包授权认证
107
- */
108
- async login() {
109
- let params = await this.retoken();
110
- return await this.execute('wallet.auth', [
111
- params.id,
112
- {
113
- username: params.cid,
114
- password: params.calc,
115
- },
116
- ]);
80
+ const hmac = this.createHmac('sha256', msg);
81
+ params.calc = hmac.update(params.token).digest('hex'); //计算并附加访问令牌
82
+
83
+ return params;
84
+ }
85
+
86
+ /**
87
+ * WS模式下的登录流程
88
+ * @param {*} params
89
+ * @param {*} callback
90
+ */
91
+ async login() {
92
+ let params = await this.retoken();
93
+
94
+ return await this.execute('wallet.auth', [
95
+ params.apiKey,
96
+ params.type,
97
+ params.id,
98
+ params.cid,
99
+ params.calc,
100
+ ]);
101
+ }
102
+
103
+ /**
104
+ * Listen for events on wallet id.
105
+ * @returns {Promise}
106
+ */
107
+
108
+ async join() {
109
+ let conf = this.getTerminalConfig();
110
+
111
+ let params = await this.retoken();
112
+ params = [params.id, params.cid, params.calc];
113
+ let sig = signObj({
114
+ method: 'wallet.join',
115
+ params: params,
116
+ cid: conf.cid,
117
+ wid: conf.id,
118
+ }, hash256(Buffer.from(conf.token)));
119
+
120
+ return new Promise((resolve, reject) => {
121
+ this.socket.emit('request', 'wallet.join', params, sig, (err) => {
122
+ if (!!err) {
123
+ console.log(err);
124
+ reject(new Error(err.message));
125
+ return;
126
+ }
127
+ resolve();
128
+ });
129
+ });
130
+ };
131
+
132
+ /**
133
+ * Unlisten for events on wallet id.
134
+ */
135
+ async leave() {
136
+ let conf = this.getTerminalConfig();
137
+
138
+ let params = [conf.id];
139
+ let sig = signObj({
140
+ method: 'wallet.leave',
141
+ params: params,
142
+ cid: conf.cid,
143
+ wid: conf.id,
144
+ }, hash256(Buffer.from(conf.token)));
145
+
146
+ return new Promise((resolve, reject) => {
147
+ this.socket.emit('request', 'wallet.leave', params, sig, (err) => {
148
+ if (err) {
149
+ reject(new Error(err.message));
150
+ return;
151
+ }
152
+ resolve();
153
+ });
154
+ });
155
+ };
156
+
157
+ /**
158
+ * 以 GET 方式,访问开放式API
159
+ * @param {*} url
160
+ */
161
+ async get(url) {
162
+ const newOptions = { json: true };
163
+
164
+ let conf = this.getTerminalConfig();
165
+ let _head = !!conf.head ? conf.head : 'http';
166
+ url = `${_head}://${conf.ip}:${conf.port}/public/${url}`;
167
+
168
+ newOptions.headers = {
169
+ Accept: 'application/json',
170
+ 'Content-Type': 'application/json; charset=utf-8',
171
+ };
172
+
173
+ try {
174
+ let ret = null;
175
+ if(this.fetch) {
176
+ ret = await this.fetch(url, newOptions);
177
+ }
178
+ else {
179
+ ret = await fetch(url, newOptions);
180
+ }
181
+ let json = await ret.json();
182
+
183
+ if(!conf.structured) {
184
+ if(json.error) {
185
+ return json;
186
+ } else {
187
+ return json.result; //脱去外围数据结构
188
+ }
189
+ } else {
190
+ return json; //保留外围数据结构
191
+ }
117
192
  }
118
-
119
- /**
120
- * WS 模式下的加入钱包操作
121
- */
122
- async join() {
123
- let params = this.getTerminalConfig();
124
- return await this.execute('wallet.join', [params.cid, params.id]);
193
+ catch(e) {
194
+ console.error(e);
125
195
  }
126
-
127
- /**
128
- * 创建 WebSocket 连接
129
- */
130
- async createSocket() {
131
- let params = this.getTerminalConfig();
132
- this.close();
133
-
134
- this.socket = io(`${params.head}://${params.ip}:${params.port}`, {
135
- 'force new connection': true,
136
- });
137
-
138
- // 注册预存的事件监听
139
- for (let event in this.socketEvents) {
140
- this.socket.on(event, this.socketEvents[event]);
196
+ }
197
+
198
+ async post(url, options) {
199
+ const newOptions = { json: true, method: 'POST', body: JSON.stringify(options) };
200
+
201
+ let conf = this.getTerminalConfig();
202
+ let _head = !!conf.head ? conf.head : 'http';
203
+ url = `${_head}://${conf.ip}:${conf.port}/public/${url}`;
204
+
205
+ newOptions.headers = {
206
+ Accept: 'application/json',
207
+ 'Content-Type': 'application/json; charset=utf-8',
208
+ };
209
+
210
+ try {
211
+ let ret = null;
212
+ if(this.fetch) {
213
+ ret = await this.fetch(url, newOptions);
214
+ }
215
+ else {
216
+ ret = await fetch(url, newOptions);
217
+ }
218
+ let json = await ret.json();
219
+
220
+ if(!conf.structured) {
221
+ if(json.error) {
222
+ return json;
223
+ } else {
224
+ return json.result; //脱去外围数据结构
141
225
  }
142
-
143
- this.socket.on('disconnect', () => {
144
- this.socket.needConnect = true;
145
- setTimeout(() => {
146
- if (!!this.socket.needConnect) {
147
- this.socket.needConnect = false;
148
- this.socket.connect();
149
- }
150
- }, 1500);
151
- });
152
-
153
- return new Promise(resolve => {
154
- this.socket.on('connect', () => {
155
- resolve();
156
- });
157
- });
226
+ } else {
227
+ return json; //保留外围数据结构
228
+ }
229
+ }
230
+ catch(e) {
231
+ console.error(e);
158
232
  }
233
+ }
234
+
235
+ /**
236
+ * 执行RPC调用
237
+ * @param {*} method
238
+ * @param {*} params
239
+ */
240
+ async execute(method, params) {
241
+ params = params || [];
242
+
243
+ let conf = this.getTerminalConfig();
244
+ switch(this.mode) {
245
+ case CommMode.ws: {
246
+ if(!this.socket) {
247
+ await this.createSocket();
248
+ }
159
249
 
160
- /**
161
- * 执行 RPC 命令(统一入口)
162
- * @param {String} command 命令名称(如 'balance.all')
163
- * @param {Array} args 命令参数
164
- */
165
- async execute(command, args) {
166
- let params = this.getTerminalConfig();
250
+ let key = generateKey(hash256(Buffer.from(conf.token)));
167
251
  let obj = {
168
- func: command,
169
- oemInfo: {
170
- cid: params.cid,
171
- token: params.token,
172
- id: params.id,
173
- },
252
+ method: method,
253
+ params: params,
254
+ cid: conf.cid,
255
+ wid: conf.id,
174
256
  };
257
+ let sig = signObj(obj, key.private);
175
258
 
176
- if (args) {
177
- obj.args = args;
178
- }
179
-
180
- switch (this.mode) {
181
- case CommMode.ws:
182
- if (!this.socket) {
183
- await this.createSocket();
259
+ return new Promise((resolve, reject) => {
260
+ this.socket.emit('request', method, params, sig, (err, msg) => {
261
+ if(!!err) {
262
+ reject(err);
263
+ }
264
+ if(!conf.structured) {
265
+ if(!!msg) {
266
+ if(msg.error) {
267
+ resolve(msg);
268
+ } else {
269
+ resolve(msg.result);
184
270
  }
185
- return new Promise(resolve => {
186
- this.socket.emit('req', obj, msg => {
187
- resolve(msg);
188
- });
189
- });
190
-
191
- case CommMode.get:
192
- return this.getRequest(obj);
193
-
194
- case CommMode.post:
195
- return this.postRequest(obj);
196
- }
197
-
198
- return Promise.reject(new Error('Unknown mode'));
199
- }
200
-
201
- /**
202
- * 以 GET 方式访问远程 API
203
- */
204
- async get(url) {
205
- const options = {
206
- json: true,
207
- method: 'GET',
208
- mode: 'cors',
209
- headers: {
210
- Accept: 'application/json',
211
- 'Content-Type': 'application/json; charset=utf-8',
212
- },
213
- };
214
-
215
- // 添加 API Key 认证
216
- let params = this.getTerminalConfig();
217
- if (params.apiKey) {
218
- let auth = Buffer.from('x:' + params.apiKey).toString('base64');
219
- options.headers['Authorization'] = 'Basic ' + auth;
220
- }
221
-
222
- try {
223
- if (this.fetch) {
224
- let ret = await this.fetch(url, options);
225
- return await ret.json();
271
+ } else {
272
+ resolve(null);
273
+ }
226
274
  } else {
227
- let ret = await fetch(url, options);
228
- return await ret.json();
275
+ resolve(msg);
229
276
  }
230
- } catch (e) {
231
- console.error(e);
232
- return null;
233
- }
234
- }
277
+ });
278
+ });
279
+ }
280
+
281
+ default: {
282
+ await this.queryToken();
283
+
284
+ let opt = this.fillOptions({
285
+ method: 'POST',
286
+ body: {
287
+ method: method,
288
+ params: params,
289
+ },
290
+ });
235
291
 
236
- /**
237
- * 以 POST 方式访问远程 API
238
- */
239
- async post(url, body) {
240
- const options = {
241
- json: true,
242
- method: 'POST',
243
- mode: 'cors',
244
- body: JSON.stringify(body),
245
- headers: {
246
- Accept: 'application/json',
247
- 'Content-Type': 'application/json; charset=utf-8',
248
- },
249
- };
292
+ let rt = await this.request(
293
+ opt,
294
+ this.getTerminalConfig(),
295
+ );
296
+
297
+ if(!rt) {
298
+ return { error:-1, };
299
+ }
250
300
 
251
- let params = this.getTerminalConfig();
252
- if (params.apiKey) {
253
- let auth = Buffer.from('x:' + params.apiKey).toString('base64');
254
- options.headers['Authorization'] = 'Basic ' + auth;
301
+ if(!!rt.error) {
255
302
  }
256
303
 
257
- try {
258
- if (this.fetch) {
259
- let ret = await this.fetch(url, options);
260
- return await ret.json();
261
- } else {
262
- let ret = await fetch(url, options);
263
- return await ret.json();
264
- }
265
- } catch (e) {
266
- console.error(e);
267
- return null;
304
+ if(!conf.structured) {
305
+ if(rt.error) {
306
+ return rt;
307
+ } else {
308
+ return rt.result;
309
+ }
310
+ } else {
311
+ return rt;
268
312
  }
313
+ }
269
314
  }
270
-
271
- /**
272
- * GET 方式发起 RPC 请求
273
- */
274
- async getRequest(params) {
275
- let config = this.getTerminalConfig();
276
- let url = `${config.head}://${config.ip}:${config.port}/index.html`;
277
-
278
- url += '?' + Object.keys(params).reduce((ret, next) => {
279
- if (ret != '') ret += '&';
280
- return (
281
- ret +
282
- next +
283
- '=' +
284
- (typeof params[next] == 'object'
285
- ? encodeURIComponent(JSON.stringify(params[next]))
286
- : encodeURIComponent(params[next]))
287
- );
288
- }, '');
289
-
290
- return this.get(url);
315
+ }
316
+
317
+ /**
318
+ * 计算并返回用于对称加密的密钥
319
+ */
320
+ getAes() {
321
+ let buf = hash256(Buffer.from(this.getTerminalConfig().token));
322
+ let aeskey = buf.toString('base64').slice(0, 32);
323
+ buf = hash256(buf);
324
+ let aesiv = buf.toString('base64').slice(0, 16);
325
+
326
+ return {aeskey, aesiv};
327
+ }
328
+
329
+ getRandom() {
330
+ let _t = (now() / 120) | 0;
331
+ this.$params.randomTime = this.$params.randomTime || _t;
332
+ if (_t > this.$params.randomTime) {
333
+ //有效期检测
334
+ this.$params.random = null;
291
335
  }
292
-
293
- /**
294
- * POST 方式发起 RPC 请求
295
- */
296
- async postRequest(params) {
297
- let config = this.getTerminalConfig();
298
- let url = `${config.head}://${config.ip}:${config.port}/index.html`;
299
- return this.post(url, params);
336
+
337
+ return this.$params.random;
338
+ }
339
+
340
+ setRandom(val) {
341
+ this.$params.random = val;
342
+ if (!!val) {
343
+ this.$params.randomTime = (now() / 120) | 0; //设置有效期
300
344
  }
301
-
302
- /**
303
- * 关闭 WebSocket 连接
304
- */
305
- close() {
306
- if (this.socket) {
307
- this.socket.removeAllListeners();
308
- this.socket.disconnect();
309
- this.socket = null;
310
- }
311
- return this;
345
+ }
346
+
347
+ fillOptions(options) {
348
+ if (!options) {
349
+ options = {};
312
350
  }
313
-
314
- /**
315
- * 监听推送消息
316
- * @param {Function} cb 回调
317
- * @param {String} etype 事件类型
318
- */
319
- watch(cb, etype) {
320
- if (this.socket) {
321
- this.socket.on(etype, cb);
322
- } else {
323
- this.socketEvents[etype] = cb;
324
- }
325
- return this;
351
+ if (!options.body) {
352
+ options.body = {};
326
353
  }
327
-
328
- /**
329
- * 获取终端配置
330
- * @param {String} networkType 网络类型 'main' / 'testnet'
331
- */
332
- getTerminalConfig(networkType) {
333
- networkType = networkType || this.defaultNetworkType;
334
-
335
- if (!this.AuthConnConfig[networkType]) {
336
- this.AuthConnConfig[networkType] = {};
337
- }
338
-
339
- return this.AuthConnConfig[networkType];
354
+ if (!options.headers) {
355
+ options.headers = {};
340
356
  }
341
357
 
342
- /**
343
- * 等待指定时长
344
- * @param {Number} time 等待时长(毫秒)
345
- */
346
- async wait(time) {
347
- await (async time => {
348
- return new Promise(resolve => {
349
- setTimeout(resolve, time);
350
- });
351
- })(time);
358
+ let rnd = this.getRandom();
359
+ let _token = this.getTerminalConfig().token;
360
+ if (_token && rnd) {
361
+ options.body.token = signHMAC(_token, rnd);
362
+ }
363
+ options.body.wid = this.getTerminalConfig().id; //附加默认钱包编号
364
+ options.body.cid = this.getTerminalConfig().cid; //附加客户端编号
365
+
366
+ //对上行数据添加签名, 使用原始 token 作为私钥源
367
+ options.body.sig = signObj({
368
+ method: options.body.method,
369
+ params: options.body.params,
370
+ cid: options.body.cid,
371
+ wid: options.body.wid,
372
+ }, hash256(Buffer.from(_token)));
373
+
374
+ options.body = JSON.stringify(options.body);
375
+
376
+ let auth = {
377
+ username: 'gamerpc',
378
+ password: this.getTerminalConfig().apiKey || '',
379
+ };
380
+ var base = new Base64();
381
+ var result = base.encode(`${auth.username}:${auth.password}`);
382
+ options.headers.Authorization = `Basic ${result}`;
383
+ return options;
384
+ }
385
+
386
+ async queryToken() {
387
+ let ret = this.getRandom();
388
+ if (!ret) {
389
+ ret = await this.request(
390
+ this.fillOptions({
391
+ method: 'POST',
392
+ body: {
393
+ method: 'token.random',
394
+ params: [this.getTerminalConfig().cid],
395
+ },
396
+ }),
397
+ this.getTerminalConfig()
398
+ );
399
+ if(!ret || !!ret.error) {
400
+ console.error(`HMAC请求错误`);
401
+ } else {
402
+ this.setRandom(ret.result); //获取令牌随机量
403
+ }
404
+ }
405
+ }
406
+
407
+ /**
408
+ * 创建通讯连接组件
409
+ * @param {*} ip
410
+ * @param {*} port
411
+ */
412
+ async createSocket(){
413
+ this.close();
414
+
415
+ let uri = ``;
416
+ let conf = this.getTerminalConfig();
417
+ let _head = !!conf.head ? conf.head : 'http';
418
+ uri = `${_head}://${conf.ip}:${conf.port}/`;
419
+
420
+ this.socket = io(uri, {'force new connection': true})
421
+ .on('disconnect', ()=>{//断线重连
422
+ this.socket.needConnect = true;
423
+ setTimeout(()=>{
424
+ if(!!this.socket.needConnect) {
425
+ this.socket.needConnect = false;
426
+ this.socket.connect();
427
+ }
428
+ }, 1500);
429
+ })
430
+
431
+ Object.keys(this.socketEvents).map(key=>{
432
+ this.socket.on(key, this.socketEvents[key]);
433
+ });
434
+
435
+ await (async function(time){return new Promise(resolve =>{setTimeout(resolve, time);});})(2000);
436
+ }
437
+
438
+ /**
439
+ * 关闭长连接
440
+ */
441
+ close() {
442
+ if(!!this.socket) {
443
+ this.socket.removeAllListeners();
444
+ this.socket.disconnect();
445
+ this.socket = null;
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Requests a URL, returning a promise.
451
+ *
452
+ * @param {object} [options] The options we want to pass to "fetch"
453
+ * @return {object} An object containing either "data" or "err"
454
+ */
455
+ async request(options, conf) {
456
+ const defaultOptions = {
457
+ //credentials: 'include',
458
+ };
459
+
460
+ const newOptions = { ...defaultOptions, ...options };
461
+ newOptions.json = true;
462
+
463
+ let _head = !!conf.head ? conf.head : 'http';
464
+
465
+ newOptions.uri = `${_head}://${conf.ip}:${conf.port}/`;
466
+
467
+ if (
468
+ newOptions.method === 'POST' ||
469
+ newOptions.method === 'PUT' ||
470
+ newOptions.method === 'DELETE'
471
+ ) {
472
+ newOptions.headers = {
473
+ Accept: 'application/json',
474
+ 'Content-Type': 'application/json; charset=utf-8',
475
+ ...newOptions.headers,
476
+ };
352
477
  }
353
478
 
354
- /**
355
- * 设置终端配置
356
- * @param {Object} info { type, ip, port, apiKey, id, cid, token }
357
- */
358
- setup(info) {
359
- if (!!info && info.type) {
360
- if (!this.AuthConnConfig[info.type]) {
361
- this.AuthConnConfig[info.type] = {};
362
- }
363
-
364
- this.defaultNetworkType = info.type;
365
-
366
- for (let k of Object.keys(info)) {
367
- this.AuthConnConfig[info.type][k] = info[k];
368
- }
369
-
370
- if (this.mode == CommMode.ws) {
371
- this.close();
372
- }
373
- }
374
-
375
- return this;
479
+ try {
480
+ if(this.fetch) {
481
+ let ret = await this.fetch(newOptions.uri, newOptions);
482
+ return await ret.json();
483
+ }
484
+ else {
485
+ let ret = await fetch(newOptions.uri, newOptions);
486
+ return await ret.json();
487
+ }
488
+ }
489
+ catch(e) {
490
+ console.error(e);
491
+ }
492
+ }
493
+
494
+
495
+ /**
496
+ * 设置服务端推送报文的监控句柄,支持链式调用
497
+ * @param cb 回调
498
+ * @param etype 事件类型
499
+ * @returns {Remote}
500
+ */
501
+ watch(cb, etype) {
502
+ if(this.socket) {
503
+ this.socket.on(etype, cb);
504
+ } else {
505
+ this.socketEvents[etype] = cb;
506
+ }
507
+ return this;
508
+ }
509
+
510
+ /**
511
+ * 获取终端配置
512
+ * @param {*} networkType
513
+ */
514
+ getTerminalConfig(networkType) {
515
+ networkType = networkType || this.defaultNetworkType;
516
+
517
+ if(!this.AuthConnConfig[networkType]) {
518
+ this.AuthConnConfig[networkType] = {}; // Fix: was `info.type` in V7.1.2
376
519
  }
377
520
 
378
- /**
379
- * 为了提供 node 下的兼容性而添加的 fetch 函数
380
- * @param {Function} fn node-fetch 或其他兼容 fetch 函数
381
- */
382
- setFetch(fn) {
383
- this.fetch = fn;
384
- return this;
521
+ return this.AuthConnConfig[networkType];
522
+ }
523
+
524
+ /**
525
+ * 等待指定时长
526
+ * @param {Number} time 等待时长(毫秒)
527
+ */
528
+ async wait (time) {
529
+ await (async (time) => {return new Promise(resolve => {setTimeout(resolve, time);});})(time);
530
+ }
531
+
532
+ /**
533
+ * 设置终端配置
534
+ * @param {*} networkType
535
+ * @param {*} info
536
+ */
537
+ setup(info) {
538
+ if(!!info && info.type) {
539
+ if(!this.AuthConnConfig[info.type]) {
540
+ this.AuthConnConfig[info.type] = {};
541
+ }
542
+
543
+ //设置默认网络类型
544
+ this.defaultNetworkType = info.type;
545
+
546
+ for(let k of Object.keys(info)) {
547
+ //设置默认网络类型的参数 - 逐项设置
548
+ this.AuthConnConfig[info.type][k] = info[k];
549
+ }
550
+
551
+ if(this.mode == CommMode.ws) {
552
+ //断开后自动重连,以便刷新接口参数如目标钱包编号等
553
+ this.close();
554
+ }
385
555
  }
556
+
557
+ return this;
558
+ }
559
+
560
+ /**
561
+ * 为了提供node下的兼容性而添加的属性设定函数
562
+ * @param {*} fn
563
+ */
564
+ setFetch(fn) {
565
+ this.fetch = fn;
566
+ return this;
567
+ }
386
568
  }
387
569
 
388
- // 挂载静态工具函数到原型,方便实例使用
389
570
  AuthConn.prototype.CommMode = CommMode;
390
571
  AuthConn.prototype.createHmac = createHmac;
391
- AuthConn.prototype.signHMAC = signHMAC;
392
572
  AuthConn.prototype.assert = assert;
393
573
  AuthConn.prototype.stringify = stringify;
574
+ AuthConn.prototype.encrypt = encrypt;
575
+ AuthConn.prototype.decrypt = decrypt;
394
576
  AuthConn.prototype.verifyData = verifyData;
395
577
  AuthConn.prototype.generateKey = generateKey;
396
578
  AuthConn.prototype.signObj = signObj;
@@ -404,4 +586,7 @@ AuthConn.prototype.hash256 = hash256;
404
586
  AuthConn.prototype.hash160 = hash160;
405
587
  AuthConn.prototype.sha1 = sha1;
406
588
 
589
+ /**
590
+ * 访问全节点的远程调用函数
591
+ */
407
592
  module.exports = AuthConn;