gamerpc 9.0.0 → 9.0.1

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