@tchain/tcabci-read-js-client 2.6.6 → 2.7.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/block.d.ts +13 -0
- package/block.js +110 -0
- package/breaker.d.ts +3 -0
- package/breaker.js +50 -0
- package/callback.d.ts +6 -1
- package/client.js +126 -138
- package/constants.d.ts +1 -7
- package/errors.js +18 -0
- package/http.d.ts +9 -0
- package/http.js +81 -0
- package/message.d.ts +41 -8
- package/message.js +136 -23
- package/package.json +5 -1
- package/transaction.js +6 -3
- package/websocketOptions.js +1 -1
package/block.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Transaction } from './transaction'
|
|
2
|
+
|
|
3
|
+
export declare class Block {
|
|
4
|
+
get Height(): number
|
|
5
|
+
get TXS(): number
|
|
6
|
+
get Hash(): string|null
|
|
7
|
+
get Transactions(): Transaction[]
|
|
8
|
+
get ChainName(): string
|
|
9
|
+
get ChainVersion(): string
|
|
10
|
+
|
|
11
|
+
static FromJSON(value: string): { block?: Block, error?: Error }
|
|
12
|
+
static FromObject(obj: Record<string, any>): { block?: Block, error?: Error }
|
|
13
|
+
}
|
package/block.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Transaction } from './transaction.js'
|
|
2
|
+
|
|
3
|
+
export class Block {
|
|
4
|
+
_height
|
|
5
|
+
_txs
|
|
6
|
+
_hash
|
|
7
|
+
_transactions
|
|
8
|
+
_chainName
|
|
9
|
+
_chainVersion
|
|
10
|
+
|
|
11
|
+
get Height() {
|
|
12
|
+
return this._height
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get TXS() {
|
|
16
|
+
return this._txs
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get Hash() {
|
|
20
|
+
return this._hash
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get Transactions() {
|
|
24
|
+
return this._transactions
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get ChainName() {
|
|
28
|
+
return this._chainName
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get ChainVersion() {
|
|
32
|
+
return this._chainVersion
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} value
|
|
37
|
+
* @return {{block: ?Block, error: ?Error}}
|
|
38
|
+
* @constructor
|
|
39
|
+
*/
|
|
40
|
+
static FromJSON(value) {
|
|
41
|
+
try {
|
|
42
|
+
const bl = new Block(),
|
|
43
|
+
parsed = JSON.parse(value)
|
|
44
|
+
|
|
45
|
+
bl._transactions = []
|
|
46
|
+
|
|
47
|
+
if (typeof parsed.height !== 'undefined') bl._height = parsed.height
|
|
48
|
+
if (typeof parsed.txs !== 'undefined') bl._txs = parsed.txs
|
|
49
|
+
if (typeof parsed.hash !== 'undefined') bl._hash = parsed.hash
|
|
50
|
+
if (typeof parsed.chain_name !== 'undefined')
|
|
51
|
+
bl._chainName = parsed.chain_name
|
|
52
|
+
if (typeof parsed.chain_version !== 'undefined')
|
|
53
|
+
bl._chainVersion = parsed.chain_version
|
|
54
|
+
|
|
55
|
+
if (typeof parsed.transactions !== 'undefined') {
|
|
56
|
+
for (let i = 0; i < parsed.transactions.length; i++) {
|
|
57
|
+
const { transaction, error } = Transaction.FromObject(
|
|
58
|
+
parsed.transactions[i],
|
|
59
|
+
)
|
|
60
|
+
if (error) {
|
|
61
|
+
return { block: null, error: error }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
bl._transactions.push(transaction)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { block: bl, error: null }
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return { block: null, error: e }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {object} obj
|
|
76
|
+
* @return {{block: ?Block, error: ?Error}}
|
|
77
|
+
* @constructor
|
|
78
|
+
*/
|
|
79
|
+
static FromObject(obj) {
|
|
80
|
+
try {
|
|
81
|
+
const bl = new Block()
|
|
82
|
+
|
|
83
|
+
bl._transactions = []
|
|
84
|
+
|
|
85
|
+
if (typeof obj.height !== 'undefined') bl._height = obj.height
|
|
86
|
+
if (typeof obj.txs !== 'undefined') bl._txs = obj.txs
|
|
87
|
+
if (typeof obj.hash !== 'undefined') bl._hash = obj.hash
|
|
88
|
+
if (typeof obj.chain_name !== 'undefined') bl._chainName = obj.chain_name
|
|
89
|
+
if (typeof obj.chain_version !== 'undefined')
|
|
90
|
+
bl._chainVersion = obj.chain_version
|
|
91
|
+
|
|
92
|
+
if (typeof obj.transactions !== 'undefined') {
|
|
93
|
+
for (let i = 0; i < obj.transactions.length; i++) {
|
|
94
|
+
const { transaction, error } = Transaction.FromObject(
|
|
95
|
+
obj.transactions[i],
|
|
96
|
+
)
|
|
97
|
+
if (error) {
|
|
98
|
+
return { block: null, error: error }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
bl._transactions.push(transaction)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { block: bl, error: null }
|
|
106
|
+
} catch (e) {
|
|
107
|
+
return { block: null, error: e }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
package/breaker.d.ts
ADDED
package/breaker.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConsecutiveBreaker,
|
|
3
|
+
ExponentialBackoff,
|
|
4
|
+
retry,
|
|
5
|
+
handleType,
|
|
6
|
+
circuitBreaker,
|
|
7
|
+
wrap,
|
|
8
|
+
} from 'cockatiel'
|
|
9
|
+
import { FetchError } from './errors.js'
|
|
10
|
+
|
|
11
|
+
export class Breaker {
|
|
12
|
+
_options = {
|
|
13
|
+
halfOpenAfter: 10 * 1000,
|
|
14
|
+
breaker: new ConsecutiveBreaker(10),
|
|
15
|
+
}
|
|
16
|
+
_retryPolicy = retry(
|
|
17
|
+
handleType(FetchError, (err) =>
|
|
18
|
+
[502, 503, 504].includes(err.status),
|
|
19
|
+
).orType(Error, (err) => {
|
|
20
|
+
return err.message.toLowerCase().search('failed to fetch') > -1
|
|
21
|
+
}),
|
|
22
|
+
{
|
|
23
|
+
maxAttempts: 10,
|
|
24
|
+
backoff: new ExponentialBackoff({
|
|
25
|
+
initialDelay: 500,
|
|
26
|
+
maxDelay: 15000,
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
)
|
|
30
|
+
_circuitBreakerPolicy = circuitBreaker(
|
|
31
|
+
handleType(FetchError, (err) =>
|
|
32
|
+
[502, 503, 504].includes(err.status),
|
|
33
|
+
).orType(Error, (err) => {
|
|
34
|
+
return err.message.toLowerCase().search('failed to fetch') > -1
|
|
35
|
+
}),
|
|
36
|
+
this._options,
|
|
37
|
+
)
|
|
38
|
+
_retryWithBreaker = wrap(this._retryPolicy, this._circuitBreakerPolicy)
|
|
39
|
+
constructor() {}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {function} fn
|
|
43
|
+
* @return {Promise<*>}
|
|
44
|
+
*/
|
|
45
|
+
execute(fn) {
|
|
46
|
+
return this._retryWithBreaker.execute(fn).catch((err) => {
|
|
47
|
+
return Promise.reject(err)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
}
|
package/callback.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { Transaction } from './transaction'
|
|
2
|
+
import { Block } from './block'
|
|
2
3
|
|
|
3
4
|
export declare type SuccessCallback = (event: Event) => void
|
|
4
5
|
export declare type ErrorCallback = (event: Event) => void
|
|
5
6
|
export declare type CloseCallback = (event: Event) => void
|
|
6
|
-
export declare type ListenCallback = (
|
|
7
|
+
export declare type ListenCallback = (
|
|
8
|
+
block: Block | null,
|
|
9
|
+
tx: Transaction | null,
|
|
10
|
+
msg: any | null,
|
|
11
|
+
) => void
|
package/client.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
FetchError,
|
|
3
2
|
ALREADY_CONNECTED,
|
|
4
3
|
BLOCK_NOT_FOUND,
|
|
5
|
-
ERR_NETWORK,
|
|
6
4
|
INVALID_ARGUMENT_WITH_CS,
|
|
7
5
|
INVALID_ARGUMENTS,
|
|
8
6
|
NOT_CONNECTED,
|
|
@@ -11,10 +9,19 @@ import {
|
|
|
11
9
|
TRANSACTION_TYPE_NOT_VALID,
|
|
12
10
|
} from './errors.js'
|
|
13
11
|
import { READ_NODE_ADDRESS, READ_NODE_WS_ADDRESS } from './constants.js'
|
|
14
|
-
import Message, {
|
|
12
|
+
import Message, {
|
|
13
|
+
Block as MBlock,
|
|
14
|
+
Transaction as MTransaction,
|
|
15
|
+
SUBSCRIBEMessage,
|
|
16
|
+
UNSUBSCRIBEMessage,
|
|
17
|
+
Subscription,
|
|
18
|
+
OK,
|
|
19
|
+
} from './message.js'
|
|
15
20
|
import { Options } from './websocketOptions.js'
|
|
16
21
|
import { TWebSocket } from './websocket.js'
|
|
17
22
|
import { Transaction, TX_TYPE_LIST } from './transaction.js'
|
|
23
|
+
import { Block } from './block.js'
|
|
24
|
+
import { HTTP } from './http.js'
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
27
|
* @callback SuccessCallback
|
|
@@ -36,18 +43,21 @@ import { Transaction, TX_TYPE_LIST } from './transaction.js'
|
|
|
36
43
|
|
|
37
44
|
/**
|
|
38
45
|
* @callback ListenCallback
|
|
39
|
-
* @param {
|
|
46
|
+
* @param {?Block} block
|
|
47
|
+
* @param {?Transaction} transaction
|
|
48
|
+
* @param {?*} msg
|
|
40
49
|
* @return void
|
|
41
50
|
*/
|
|
42
51
|
|
|
43
52
|
export default class TCaBCIClient {
|
|
53
|
+
_httpClient = new HTTP()
|
|
44
54
|
_subscribed = false
|
|
45
55
|
_subscribedAddresses = []
|
|
46
56
|
_SubscribedSignedData = {}
|
|
47
57
|
_connected = false
|
|
48
58
|
_chainName = 'transferchain'
|
|
49
59
|
_chainVersion = 'v1'
|
|
50
|
-
_version = `v2.
|
|
60
|
+
_version = `v2.7.1`
|
|
51
61
|
/**
|
|
52
62
|
* @type {?SuccessCallback}
|
|
53
63
|
*/
|
|
@@ -100,6 +110,7 @@ export default class TCaBCIClient {
|
|
|
100
110
|
|
|
101
111
|
this._readNodeAddress = readNodeAddresses[0]
|
|
102
112
|
this._readNodeWSAddress = readNodeAddresses[1]
|
|
113
|
+
this._httpClient.setBaseURL(readNodeAddresses[0])
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
this._options = new Options(this._readNodeWSAddress)
|
|
@@ -258,18 +269,16 @@ export default class TCaBCIClient {
|
|
|
258
269
|
addrs.push(...newAddress)
|
|
259
270
|
}
|
|
260
271
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
272
|
+
this._ws.send(
|
|
273
|
+
new Message({
|
|
274
|
+
isWeb: true,
|
|
275
|
+
type: SUBSCRIBEMessage,
|
|
276
|
+
addrs: addrs,
|
|
277
|
+
signedData: _signedData,
|
|
278
|
+
txTypes,
|
|
279
|
+
}).ToJSON(),
|
|
267
280
|
)
|
|
268
|
-
|
|
269
|
-
this._ws.send(message.ToJSON())
|
|
270
|
-
this._setSubscribeAddresses(addrs, true)
|
|
271
|
-
._setSubscribeSignedData(signedData)
|
|
272
|
-
._setSubscribed(true)
|
|
281
|
+
this._setSubscribeAddresses(addrs, true)._setSubscribeSignedData(signedData)
|
|
273
282
|
|
|
274
283
|
return this
|
|
275
284
|
}
|
|
@@ -282,7 +291,11 @@ export default class TCaBCIClient {
|
|
|
282
291
|
throw new Error(NOT_SUBSCRIBED)
|
|
283
292
|
}
|
|
284
293
|
this._ws.send(
|
|
285
|
-
new Message(
|
|
294
|
+
new Message({
|
|
295
|
+
isWeb: true,
|
|
296
|
+
type: UNSUBSCRIBEMessage,
|
|
297
|
+
addrs: this.SubscribeAddresses,
|
|
298
|
+
}).ToJSON(),
|
|
286
299
|
)
|
|
287
300
|
this._setSubscribed(false)
|
|
288
301
|
this._setSubscribeAddresses([])
|
|
@@ -297,12 +310,13 @@ export default class TCaBCIClient {
|
|
|
297
310
|
* @return {Promise<{blocks: Transaction[], total_count: number}>}
|
|
298
311
|
*/
|
|
299
312
|
LastBlock(chainName = null, chainVersion = null) {
|
|
300
|
-
return this._httpClient
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
313
|
+
return this._httpClient
|
|
314
|
+
.request(
|
|
315
|
+
`/v1/blocks?chain_name=${chainName ?? this._chainName}&chain_version=${chainVersion ?? this._chainVersion}&limit=1&offset=0`,
|
|
316
|
+
{
|
|
317
|
+
method: 'GET',
|
|
318
|
+
},
|
|
319
|
+
)
|
|
306
320
|
.then((res) => {
|
|
307
321
|
const data = []
|
|
308
322
|
|
|
@@ -314,7 +328,7 @@ export default class TCaBCIClient {
|
|
|
314
328
|
|
|
315
329
|
return { blocks: data, total_count: res.total_count }
|
|
316
330
|
})
|
|
317
|
-
.catch((e) => this.
|
|
331
|
+
.catch((e) => this._httpClient.handleError(e, new Error(BLOCK_NOT_FOUND)))
|
|
318
332
|
}
|
|
319
333
|
|
|
320
334
|
/**
|
|
@@ -327,17 +341,18 @@ export default class TCaBCIClient {
|
|
|
327
341
|
return Promise.reject(new Error(INVALID_ARGUMENTS))
|
|
328
342
|
}
|
|
329
343
|
|
|
330
|
-
return this._httpClient
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
344
|
+
return this._httpClient
|
|
345
|
+
.request(`/v1/tx/${id}`, {
|
|
346
|
+
method: 'GET',
|
|
347
|
+
headers: { 'X-Signature': signature },
|
|
348
|
+
})
|
|
334
349
|
.then((res) => {
|
|
335
350
|
const { transaction, error } = Transaction.FromObject(res.data)
|
|
336
351
|
if (error) return Promise.reject(error)
|
|
337
352
|
|
|
338
353
|
return { tx: transaction }
|
|
339
354
|
})
|
|
340
|
-
.catch((e) => this.
|
|
355
|
+
.catch((e) => this._httpClient.handleError(e))
|
|
341
356
|
}
|
|
342
357
|
|
|
343
358
|
/**
|
|
@@ -371,17 +386,18 @@ export default class TCaBCIClient {
|
|
|
371
386
|
return Promise.reject(new Error(INVALID_ARGUMENTS))
|
|
372
387
|
}
|
|
373
388
|
|
|
374
|
-
return this._httpClient
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
389
|
+
return this._httpClient
|
|
390
|
+
.request('/v1/tx_summary', {
|
|
391
|
+
method: 'POST',
|
|
392
|
+
body: JSON.stringify({
|
|
393
|
+
chain_name: chainName ?? this._chainName,
|
|
394
|
+
chain_version: chainVersion ?? this._chainVersion,
|
|
395
|
+
recipient_addrs: recipientAddrs,
|
|
396
|
+
sender_addrs: senderAddrs,
|
|
397
|
+
signed_addrs: signedData,
|
|
398
|
+
...(types ? { types: types } : { typ: typ }),
|
|
399
|
+
}),
|
|
400
|
+
})
|
|
385
401
|
.then((res) => {
|
|
386
402
|
let firstTransaction, lastTransaction
|
|
387
403
|
|
|
@@ -411,7 +427,7 @@ export default class TCaBCIClient {
|
|
|
411
427
|
total_count: res.total_count,
|
|
412
428
|
}
|
|
413
429
|
})
|
|
414
|
-
.catch((e) => this.
|
|
430
|
+
.catch((e) => this._httpClient.handleError(e))
|
|
415
431
|
}
|
|
416
432
|
|
|
417
433
|
/**
|
|
@@ -451,25 +467,26 @@ export default class TCaBCIClient {
|
|
|
451
467
|
chainName = null,
|
|
452
468
|
chainVersion = null,
|
|
453
469
|
}) {
|
|
454
|
-
return this._httpClient
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
470
|
+
return this._httpClient
|
|
471
|
+
.request('/v1/tx_search/p', {
|
|
472
|
+
method: 'POST',
|
|
473
|
+
body: JSON.stringify({
|
|
474
|
+
chain_name: chainName ?? this._chainName,
|
|
475
|
+
chain_version: chainVersion ?? this._chainVersion,
|
|
476
|
+
height: `${heightOperator} ${height}`,
|
|
477
|
+
...(maxHeight ? { max_height: maxHeight } : {}),
|
|
478
|
+
...(lastOrder ? { last_order: lastOrder } : {}),
|
|
479
|
+
...(recipientAddrs ? { recipient_addrs: recipientAddrs } : {}),
|
|
480
|
+
...(senderAddrs ? { sender_addrs: senderAddrs } : {}),
|
|
481
|
+
...(signedData ? { signed_addrs: signedData } : {}),
|
|
482
|
+
...(hashes ? { hashes: hashes } : {}),
|
|
483
|
+
...(limit ? { limit: limit } : {}),
|
|
484
|
+
...(offset ? { offset: offset } : {}),
|
|
485
|
+
...(orderField ? { order_field: orderField } : {}),
|
|
486
|
+
...(orderBy ? { order_by: orderBy } : {}),
|
|
487
|
+
...(types ? { types: types } : typ ? { typ: typ } : {}),
|
|
488
|
+
}),
|
|
489
|
+
})
|
|
473
490
|
.then((res) => {
|
|
474
491
|
const data = []
|
|
475
492
|
|
|
@@ -484,7 +501,7 @@ export default class TCaBCIClient {
|
|
|
484
501
|
total_count: res.total_count,
|
|
485
502
|
}
|
|
486
503
|
})
|
|
487
|
-
.catch((e) => this.
|
|
504
|
+
.catch((e) => this._httpClient.handleError(e))
|
|
488
505
|
}
|
|
489
506
|
|
|
490
507
|
/**
|
|
@@ -630,9 +647,8 @@ export default class TCaBCIClient {
|
|
|
630
647
|
throw new Error(TRANSACTION_TYPE_NOT_VALID)
|
|
631
648
|
}
|
|
632
649
|
|
|
633
|
-
return this._httpClient
|
|
634
|
-
commit ? '/v1/tx/commit' : sync ? '/v1/tx/sync' : '/v1/tx',
|
|
635
|
-
{
|
|
650
|
+
return this._httpClient
|
|
651
|
+
.request(commit ? '/v1/tx/commit' : sync ? '/v1/tx/sync' : '/v1/tx', {
|
|
636
652
|
method: 'POST',
|
|
637
653
|
body: JSON.stringify({
|
|
638
654
|
id,
|
|
@@ -646,13 +662,14 @@ export default class TCaBCIClient {
|
|
|
646
662
|
sign,
|
|
647
663
|
fee,
|
|
648
664
|
}),
|
|
649
|
-
}
|
|
650
|
-
)
|
|
665
|
+
})
|
|
651
666
|
.then((res) => {
|
|
652
667
|
return { data: res.data }
|
|
653
668
|
})
|
|
654
669
|
.catch((e) =>
|
|
655
|
-
this.
|
|
670
|
+
this._httpClient.handleError(e, {
|
|
671
|
+
400: new Error(TRANSACTION_NOT_BROADCAST),
|
|
672
|
+
}),
|
|
656
673
|
)
|
|
657
674
|
}
|
|
658
675
|
|
|
@@ -672,7 +689,7 @@ export default class TCaBCIClient {
|
|
|
672
689
|
chainName = null,
|
|
673
690
|
chainVersion = null,
|
|
674
691
|
) {
|
|
675
|
-
return this._httpClient('/v1/bulk_tx', {
|
|
692
|
+
return this._httpClient.request('/v1/bulk_tx', {
|
|
676
693
|
method: 'POST',
|
|
677
694
|
body: JSON.stringify({
|
|
678
695
|
chain_name: chainName ?? this._chainName,
|
|
@@ -708,10 +725,6 @@ export default class TCaBCIClient {
|
|
|
708
725
|
})
|
|
709
726
|
|
|
710
727
|
this._ws.addMessageListener((message) => {
|
|
711
|
-
if (message.data === 'OK' && message.data.length < 10) {
|
|
712
|
-
return { status: message.data }
|
|
713
|
-
}
|
|
714
|
-
|
|
715
728
|
this._callListenCallback(message.data)
|
|
716
729
|
})
|
|
717
730
|
|
|
@@ -788,73 +801,48 @@ export default class TCaBCIClient {
|
|
|
788
801
|
}
|
|
789
802
|
|
|
790
803
|
_callListenCallback(message) {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
*/
|
|
801
|
-
_httpClient(uri, req) {
|
|
802
|
-
req.cache = 'no-cache'
|
|
803
|
-
req.headers = {
|
|
804
|
-
Client: `tcabaci-read-js-client/${this._version}`,
|
|
805
|
-
}
|
|
806
|
-
req.priority = 'high'
|
|
807
|
-
|
|
808
|
-
return fetch(this._readNodeAddress + uri, req).then((response) =>
|
|
809
|
-
this._handleRestResponse(response),
|
|
810
|
-
)
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* @param {Response} response
|
|
815
|
-
* @return {Promise<*>}
|
|
816
|
-
*/
|
|
817
|
-
async _handleRestResponse(response) {
|
|
818
|
-
if (response.status >= 200 && response.status < 400) {
|
|
819
|
-
return response.json()
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
try {
|
|
823
|
-
const data = JSON.parse(await response.text())
|
|
824
|
-
|
|
825
|
-
return Promise.reject(
|
|
826
|
-
new FetchError(data.message)
|
|
827
|
-
.setStatus(response.status)
|
|
828
|
-
.setResponse(data),
|
|
829
|
-
)
|
|
830
|
-
} catch (e) {
|
|
831
|
-
return Promise.reject(
|
|
832
|
-
new FetchError(response.statusText).setOriginError(e),
|
|
833
|
-
)
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
/**
|
|
838
|
-
* @param {Error} err
|
|
839
|
-
* @param {?Object|Error} custom
|
|
840
|
-
* @throws Error
|
|
841
|
-
*/
|
|
842
|
-
_handleRestError(err, custom = null) {
|
|
843
|
-
const code = err.code
|
|
844
|
-
|
|
845
|
-
if (custom && typeof custom === 'object' && custom[code]) {
|
|
846
|
-
throw custom[code]
|
|
847
|
-
} else if (custom instanceof Error) {
|
|
848
|
-
throw custom
|
|
849
|
-
}
|
|
804
|
+
let msg
|
|
805
|
+
|
|
806
|
+
const { transaction, error: e1 } = Transaction.FromJSON(message)
|
|
807
|
+
if (e1) {
|
|
808
|
+
const { message: _msg, error: e2 } = Message.FromJSON(message)
|
|
809
|
+
if (e2) {
|
|
810
|
+
this._callErrorCallback(e2)
|
|
811
|
+
return
|
|
812
|
+
}
|
|
850
813
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
814
|
+
switch (_msg.type) {
|
|
815
|
+
case MBlock:
|
|
816
|
+
msg = Block.FromObject(_msg.data)
|
|
817
|
+
if (msg.error) {
|
|
818
|
+
this._callErrorCallback(msg.error)
|
|
819
|
+
return
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
if (this._listenCb) this._listenCb(msg.block, null, null)
|
|
823
|
+
break
|
|
824
|
+
case MTransaction:
|
|
825
|
+
msg = Transaction.FromObject(_msg.data)
|
|
826
|
+
if (msg.error) {
|
|
827
|
+
this._callErrorCallback(msg.error)
|
|
828
|
+
return
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (this._listenCb) this._listenCb(null, msg.transaction, null)
|
|
832
|
+
break
|
|
833
|
+
case Subscription:
|
|
834
|
+
if (message.state === OK) {
|
|
835
|
+
this._setSubscribed(true)
|
|
836
|
+
} else {
|
|
837
|
+
this._setSubscribed(false)
|
|
838
|
+
}
|
|
839
|
+
break
|
|
840
|
+
default:
|
|
841
|
+
if (this._listenCb) this._listenCb(null, null, _msg)
|
|
842
|
+
break
|
|
843
|
+
}
|
|
844
|
+
} else {
|
|
845
|
+
if (this._listenCb) this._listenCb(null, transaction, null)
|
|
858
846
|
}
|
|
859
847
|
}
|
|
860
848
|
}
|
package/constants.d.ts
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
|
|
3
|
-
export declare const SUBSCRIBEMessage: MessageType,
|
|
4
|
-
UNSUBSCRIBEMessage: MessageType
|
|
5
|
-
|
|
6
|
-
export declare const CHARACTERS: string,
|
|
7
|
-
READ_NODE_ADDRESS: string,
|
|
1
|
+
export declare const READ_NODE_ADDRESS: string,
|
|
8
2
|
READ_NODE_WS_ADDRESS: string
|
package/errors.js
CHANGED
|
@@ -12,6 +12,24 @@ export const ALREADY_CONNECTED = 'Already connected',
|
|
|
12
12
|
TRANSACTION_TYPE_NOT_VALID = 'Transaction type is not valid',
|
|
13
13
|
TRANSACTION_NOT_BROADCAST = 'Transaction can not be broadcast'
|
|
14
14
|
|
|
15
|
+
export class CopiedError extends Error {
|
|
16
|
+
originName
|
|
17
|
+
originError
|
|
18
|
+
originStack
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Error} err
|
|
22
|
+
*/
|
|
23
|
+
constructor(err) {
|
|
24
|
+
super(err.message)
|
|
25
|
+
this.name = 'CopiedError'
|
|
26
|
+
this.originName = err.name
|
|
27
|
+
this.originError = err
|
|
28
|
+
this.stack = err.stack
|
|
29
|
+
this.originStack = err.stack
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
export class FetchError extends Error {
|
|
16
34
|
status = -1
|
|
17
35
|
response
|
package/http.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Request } from 'express'
|
|
2
|
+
|
|
3
|
+
export declare class HTTP {
|
|
4
|
+
constructor(baseURL: string)
|
|
5
|
+
setBaseURL(baseURL: string): HTTP
|
|
6
|
+
request(uri: string, req: Request): Promise<Record<string, any>>
|
|
7
|
+
handleResponse(response: Response): Promise<any>
|
|
8
|
+
handleError(err: Error, custom: Record<string, any>|Error): Promise<any>
|
|
9
|
+
}
|
package/http.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ERR_NETWORK, FetchError, INVALID_ARGUMENTS } from './errors.js'
|
|
2
|
+
import { Breaker } from './breaker.js'
|
|
3
|
+
|
|
4
|
+
export class HTTP {
|
|
5
|
+
_baseURL
|
|
6
|
+
_version = 'v2.7.1'
|
|
7
|
+
_breaker = new Breaker()
|
|
8
|
+
constructor(baseURL = null) {
|
|
9
|
+
this._baseURL = baseURL
|
|
10
|
+
}
|
|
11
|
+
setBaseURL(baseURL) {
|
|
12
|
+
this._baseURL = baseURL
|
|
13
|
+
return this
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} uri
|
|
17
|
+
* @param {RequestInit} req
|
|
18
|
+
* @return {Promise<Record<string, any>>}
|
|
19
|
+
*/
|
|
20
|
+
async request(uri, req) {
|
|
21
|
+
req.cache = 'no-cache'
|
|
22
|
+
req.headers = {
|
|
23
|
+
Client: `tcabaci-read-js-client/${this._version}`,
|
|
24
|
+
}
|
|
25
|
+
req.priority = 'high'
|
|
26
|
+
|
|
27
|
+
return this._breaker
|
|
28
|
+
.execute(() => {
|
|
29
|
+
return fetch(this._baseURL + uri, req)
|
|
30
|
+
})
|
|
31
|
+
.then((response) => this.handleResponse(response))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {Response} response
|
|
36
|
+
* @return {Promise<*>}
|
|
37
|
+
*/
|
|
38
|
+
async handleResponse(response) {
|
|
39
|
+
if (response.status >= 200 && response.status < 400) {
|
|
40
|
+
return response.json()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const data = JSON.parse(await response.text())
|
|
45
|
+
|
|
46
|
+
return Promise.reject(
|
|
47
|
+
new FetchError(data.message)
|
|
48
|
+
.setStatus(response.status)
|
|
49
|
+
.setResponse(data),
|
|
50
|
+
)
|
|
51
|
+
} catch (e) {
|
|
52
|
+
return Promise.reject(
|
|
53
|
+
new FetchError(response.statusText).setOriginError(e),
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Error} err
|
|
60
|
+
* @param {?Object|Error} custom
|
|
61
|
+
* @return {Promise<Error>}
|
|
62
|
+
*/
|
|
63
|
+
async handleError(err, custom = null) {
|
|
64
|
+
const code = err.code
|
|
65
|
+
|
|
66
|
+
if (custom && typeof custom === 'object' && custom[code]) {
|
|
67
|
+
return Promise.reject(custom[code])
|
|
68
|
+
} else if (custom instanceof Error) {
|
|
69
|
+
return Promise.reject(custom)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
switch (code) {
|
|
73
|
+
case 400:
|
|
74
|
+
return Promise.reject(new Error(INVALID_ARGUMENTS))
|
|
75
|
+
case 'ERR_NETWORK':
|
|
76
|
+
return Promise.reject(new Error(ERR_NETWORK))
|
|
77
|
+
default:
|
|
78
|
+
return Promise.reject(err)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
package/message.d.ts
CHANGED
|
@@ -1,13 +1,46 @@
|
|
|
1
|
-
import { MessageType } from './constants'
|
|
2
1
|
import { TXType } from './transaction'
|
|
3
2
|
|
|
3
|
+
export declare type MessageType = string
|
|
4
|
+
|
|
5
|
+
export declare const SUBSCRIBEMessage: MessageType,
|
|
6
|
+
UNSUBSCRIBEMessage: MessageType
|
|
7
|
+
|
|
8
|
+
export declare type MType = number
|
|
9
|
+
|
|
10
|
+
export declare const Block: MessageType,
|
|
11
|
+
Transaction: MessageType,
|
|
12
|
+
Subscription: MessageType,
|
|
13
|
+
Listen: MessageType,
|
|
14
|
+
MSG: MessageType
|
|
15
|
+
|
|
16
|
+
export declare type MState = number
|
|
17
|
+
|
|
18
|
+
export declare const OK: MState,
|
|
19
|
+
FAIL: MState
|
|
20
|
+
|
|
4
21
|
export declare class Message {
|
|
5
|
-
constructor(
|
|
6
|
-
isWeb
|
|
7
|
-
type
|
|
8
|
-
addrs
|
|
9
|
-
signedData
|
|
10
|
-
txTypes
|
|
11
|
-
|
|
22
|
+
constructor({
|
|
23
|
+
isWeb,
|
|
24
|
+
type,
|
|
25
|
+
addrs,
|
|
26
|
+
signedData,
|
|
27
|
+
txTypes,
|
|
28
|
+
}?: {
|
|
29
|
+
isWeb: boolean
|
|
30
|
+
type: MessageType
|
|
31
|
+
addrs: string[]
|
|
32
|
+
signedData?: Record<string, string>
|
|
33
|
+
txTypes?: TXType[]
|
|
34
|
+
})
|
|
35
|
+
get IsWeb(): boolean
|
|
36
|
+
get Type(): MessageType
|
|
37
|
+
get Addresses(): string[] | null
|
|
38
|
+
get SignedAddresses(): Record<string, string> | null
|
|
39
|
+
get TXTypes(): TXType[] | null
|
|
40
|
+
get Data(): any | null
|
|
41
|
+
get State(): MState | null
|
|
42
|
+
|
|
43
|
+
static FromJSON(value: string): { message?: Message; error?: Error }
|
|
44
|
+
static FromObject(obj: Record<string, any>): { message?: Message; error?: Error }
|
|
12
45
|
ToJSON(): string
|
|
13
46
|
}
|
package/message.js
CHANGED
|
@@ -1,29 +1,115 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { INVALID_ARGUMENT_WITH_CS } from './errors.js'
|
|
2
2
|
import { TX_TYPE_LIST } from './transaction.js'
|
|
3
3
|
|
|
4
4
|
export const SUBSCRIBEMessage = 'subscribe',
|
|
5
5
|
UNSUBSCRIBEMessage = 'unsubscribe'
|
|
6
6
|
|
|
7
|
+
export const Block = 0,
|
|
8
|
+
Transaction = 1,
|
|
9
|
+
Subscription = 2,
|
|
10
|
+
Listen = 3,
|
|
11
|
+
MSG = 4
|
|
12
|
+
|
|
13
|
+
export const OK = 1,
|
|
14
|
+
FAIL = 2
|
|
15
|
+
|
|
7
16
|
export default class Message {
|
|
8
17
|
_is_web = false
|
|
9
|
-
_type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
_txTypes
|
|
18
|
+
_type
|
|
19
|
+
_addresses
|
|
20
|
+
_signedAddresses
|
|
21
|
+
_txTypes
|
|
22
|
+
_data
|
|
23
|
+
_state
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
26
|
* @param {boolean} isWeb
|
|
16
|
-
* @param {string} type
|
|
27
|
+
* @param {string|number} type
|
|
17
28
|
* @param {Array<string>} addrs
|
|
18
29
|
* @param {?Object} signedData
|
|
19
30
|
* @param {?Array<string>} txTypes
|
|
31
|
+
* @param {*} data
|
|
20
32
|
*/
|
|
21
|
-
constructor(
|
|
33
|
+
constructor({
|
|
34
|
+
isWeb,
|
|
35
|
+
type,
|
|
36
|
+
addrs,
|
|
37
|
+
signedData = null,
|
|
38
|
+
txTypes = null,
|
|
39
|
+
data = null,
|
|
40
|
+
} = {}) {
|
|
22
41
|
this._is_web = isWeb
|
|
23
42
|
this._type = type
|
|
24
|
-
if (addrs && Array.isArray(addrs)) this.
|
|
25
|
-
if (typeof signedData === 'object') this.
|
|
43
|
+
if (addrs && Array.isArray(addrs)) this._addresses = addrs
|
|
44
|
+
if (typeof signedData === 'object') this._signedAddresses = signedData
|
|
26
45
|
if (txTypes && Array.isArray(txTypes)) this._txTypes = txTypes
|
|
46
|
+
if (data) this._data = data
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get IsWeb() {
|
|
50
|
+
return this._is_web
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get Type() {
|
|
54
|
+
return this._type
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get Addresses() {
|
|
58
|
+
return this._addresses
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get SignedAddresses() {
|
|
62
|
+
return this._signedAddresses
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get Data() {
|
|
66
|
+
return this._data
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get State() {
|
|
70
|
+
return this._state
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static FromJSON(value) {
|
|
74
|
+
try {
|
|
75
|
+
const msg = new Message(),
|
|
76
|
+
parsed = JSON.parse(value)
|
|
77
|
+
|
|
78
|
+
msg._type = parsed.type
|
|
79
|
+
if (typeof parsed.addresses !== 'undefined')
|
|
80
|
+
msg._addresses = parsed.addresses
|
|
81
|
+
if (typeof parsed.signed_addresses !== 'undefined')
|
|
82
|
+
msg._signedAddresses = parsed.signed_addresses
|
|
83
|
+
if (typeof parsed.data !== 'undefined') msg._data = parsed.data
|
|
84
|
+
if (typeof parsed.tx_types !== 'undefined') msg._txTypes = parsed.tx_types
|
|
85
|
+
if (typeof parsed.state !== 'undefined') msg._state = parsed.state
|
|
86
|
+
|
|
87
|
+
msg._validate()
|
|
88
|
+
|
|
89
|
+
return { message: this, error: null }
|
|
90
|
+
} catch (e) {
|
|
91
|
+
return { message: null, error: e }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static FromObject(obj) {
|
|
96
|
+
try {
|
|
97
|
+
const msg = new Message()
|
|
98
|
+
|
|
99
|
+
msg._type = obj.type
|
|
100
|
+
if (typeof obj.addresses !== 'undefined') msg._addresses = obj.addresses
|
|
101
|
+
if (typeof obj.signed_addresses !== 'undefined')
|
|
102
|
+
msg._signedAddresses = obj.signed_addresses
|
|
103
|
+
if (typeof obj.data !== 'undefined') msg._data = obj.data
|
|
104
|
+
if (typeof obj.tx_types !== 'undefined') msg._txTypes = obj.tx_types
|
|
105
|
+
if (typeof obj.state !== 'undefined') msg._state = obj.state
|
|
106
|
+
|
|
107
|
+
msg._validate()
|
|
108
|
+
|
|
109
|
+
return { message: this, error: null }
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return { message: null, error: e }
|
|
112
|
+
}
|
|
27
113
|
}
|
|
28
114
|
|
|
29
115
|
ToJSON() {
|
|
@@ -32,39 +118,66 @@ export default class Message {
|
|
|
32
118
|
return JSON.stringify({
|
|
33
119
|
is_web: this._is_web,
|
|
34
120
|
type: this._type,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
121
|
+
...(this._addresses ? { addresses: this._addresses } : {}),
|
|
122
|
+
...(this._signedAddresses
|
|
123
|
+
? { signed_addresses: this._signedAddresses }
|
|
124
|
+
: {}),
|
|
125
|
+
...(this._txTypes ? { tx_types: this._txTypes } : {}),
|
|
126
|
+
...(this._data ? { data: this._data } : {}),
|
|
38
127
|
})
|
|
39
128
|
}
|
|
40
129
|
|
|
41
130
|
_validate() {
|
|
42
|
-
if (
|
|
131
|
+
if (
|
|
132
|
+
typeof this._is_web !== 'undefined' &&
|
|
133
|
+
typeof this._is_web !== 'boolean'
|
|
134
|
+
) {
|
|
43
135
|
throw new Error(INVALID_ARGUMENT_WITH_CS('is_web'))
|
|
44
136
|
}
|
|
45
137
|
|
|
46
|
-
if (typeof this._type
|
|
138
|
+
if (typeof this._type === 'undefined') {
|
|
47
139
|
throw new Error(INVALID_ARGUMENT_WITH_CS('type'))
|
|
140
|
+
} else {
|
|
141
|
+
if (
|
|
142
|
+
typeof this._type === 'string' &&
|
|
143
|
+
![SUBSCRIBEMessage, UNSUBSCRIBEMessage].includes(this._type)
|
|
144
|
+
) {
|
|
145
|
+
throw new Error(INVALID_ARGUMENT_WITH_CS('type'))
|
|
146
|
+
} else if (
|
|
147
|
+
typeof this._type === 'number' &&
|
|
148
|
+
![Block, Transaction, Subscription, Listen, MSG].includes(this._type)
|
|
149
|
+
) {
|
|
150
|
+
throw new Error(INVALID_ARGUMENT_WITH_CS('type'))
|
|
151
|
+
}
|
|
48
152
|
}
|
|
49
153
|
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
throw new Error(INVALID_ARGUMENT_WITH_CS('signedData'))
|
|
154
|
+
if (
|
|
155
|
+
typeof this._addresses !== 'undefined' &&
|
|
156
|
+
!Array.isArray(this._addresses)
|
|
157
|
+
) {
|
|
158
|
+
throw new Error(INVALID_ARGUMENT_WITH_CS('addresses'))
|
|
56
159
|
}
|
|
57
160
|
|
|
58
|
-
if (
|
|
59
|
-
|
|
161
|
+
if (
|
|
162
|
+
typeof this._signedAddresses !== 'undefined' &&
|
|
163
|
+
typeof this._signedAddresses !== 'object'
|
|
164
|
+
) {
|
|
165
|
+
throw new Error(INVALID_ARGUMENT_WITH_CS('signedAddresses'))
|
|
60
166
|
}
|
|
61
167
|
|
|
62
|
-
if (this._txTypes.length) {
|
|
168
|
+
if (typeof this._txTypes !== 'undefined' && this._txTypes.length) {
|
|
63
169
|
for (let i = 0; i < this._txTypes.length; i++) {
|
|
64
170
|
if (!TX_TYPE_LIST.includes(this._txTypes[i])) {
|
|
65
171
|
throw new Error(INVALID_ARGUMENT_WITH_CS('tx_types'))
|
|
66
172
|
}
|
|
67
173
|
}
|
|
68
174
|
}
|
|
175
|
+
|
|
176
|
+
if (
|
|
177
|
+
typeof this._state !== 'undefined' &&
|
|
178
|
+
![OK, FAIL].includes(this._state)
|
|
179
|
+
) {
|
|
180
|
+
throw new Error(INVALID_ARGUMENT_WITH_CS('state'))
|
|
181
|
+
}
|
|
69
182
|
}
|
|
70
183
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tchain/tcabci-read-js-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"description": "TransferChain Fastest Read Network WebSocket Client",
|
|
5
5
|
"main": "client.js",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"*.d.ts",
|
|
13
13
|
"constants.js",
|
|
14
|
+
"breaker.js",
|
|
15
|
+
"http.js",
|
|
16
|
+
"block.js",
|
|
14
17
|
"client.js",
|
|
15
18
|
"errors.js",
|
|
16
19
|
"message.js",
|
|
@@ -42,6 +45,7 @@
|
|
|
42
45
|
"ws": "^8.20.0"
|
|
43
46
|
},
|
|
44
47
|
"dependencies": {
|
|
48
|
+
"cockatiel": "^3.2.1",
|
|
45
49
|
"reconnecting-websocket": "^4.4.0"
|
|
46
50
|
},
|
|
47
51
|
"scripts": {
|
package/transaction.js
CHANGED
|
@@ -275,6 +275,8 @@ export class Transaction {
|
|
|
275
275
|
if (typeof parsed.chain_version !== 'undefined')
|
|
276
276
|
this._chainVersion = parsed.chain_version
|
|
277
277
|
|
|
278
|
+
tx.Validate()
|
|
279
|
+
|
|
278
280
|
return { transaction: tx, error: null }
|
|
279
281
|
} catch (e) {
|
|
280
282
|
return { transaction: null, error: e }
|
|
@@ -309,10 +311,11 @@ export class Transaction {
|
|
|
309
311
|
tx._hash = obj.hash
|
|
310
312
|
if (typeof obj.inserted_at !== 'undefined')
|
|
311
313
|
tx._inserted_at = new Date(obj.inserted_at)
|
|
312
|
-
if (typeof obj.chain_name !== 'undefined')
|
|
313
|
-
this._chainName = obj.chain_name
|
|
314
|
+
if (typeof obj.chain_name !== 'undefined') tx._chainName = obj.chain_name
|
|
314
315
|
if (typeof obj.chain_version !== 'undefined')
|
|
315
|
-
|
|
316
|
+
tx._chainVersion = obj.chain_version
|
|
317
|
+
|
|
318
|
+
tx.Validate()
|
|
316
319
|
|
|
317
320
|
return { transaction: tx, error: null }
|
|
318
321
|
} catch (e) {
|
package/websocketOptions.js
CHANGED