@tchain/tcabci-read-js-client 2.8.3 → 2.8.5

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/bytea.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /** Present PostgreSQL bytea JSON returned by the read node. */
2
+ export interface ByteaJSON {
3
+ readonly Bytes: string
4
+ readonly Status: 2
5
+ }
6
+
1
7
  export declare class Bytea {
2
8
  constructor(bytes: Uint8Array, status: number)
3
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tchain/tcabci-read-js-client",
3
- "version": "2.8.3",
3
+ "version": "2.8.5",
4
4
  "description": "TransferChain Fastest Read Network WebSocket Client",
5
5
  "homepage": "https://github.com/TransferChain/tcabci-read-js-client#readme",
6
6
  "bugs": {
@@ -21,6 +21,7 @@
21
21
  "client.js",
22
22
  "errors.js",
23
23
  "message.js",
24
+ "passKey.js",
24
25
  "transaction.js",
25
26
  "util.js",
26
27
  "websocket.js",
@@ -38,9 +39,9 @@
38
39
  "lint:check": "oxfmt --check ./ && oxlint ./",
39
40
  "test": "pnpm run test:unit && pnpm run test:security && pnpm run test:types",
40
41
  "test:all": "pnpm test",
41
- "test:coverage": "node --experimental-test-coverage --test test/security.test.js",
42
+ "test:coverage": "node --experimental-test-coverage --test test/security.test.js test/transaction.test.js",
42
43
  "test:unit": "mocha --timeout 5000 test/errors_test.js test/websocketOptions_test.js test/websocket_test.js",
43
- "test:security": "node --test test/security.test.js",
44
+ "test:security": "node --test test/security.test.js test/transaction.test.js",
44
45
  "test:types": "tsc --noEmit --strict --module NodeNext --moduleResolution NodeNext --target ES2022 test/consumer.ts",
45
46
  "test:integration": "mocha --timeout 7000 test/client_test.js"
46
47
  },
package/passKey.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * SHA-512 of four concatenated lowercase UUID-v4 ASCII identifiers, matching
3
+ * SDK passKey defaults. Uses WebCrypto without a dependency on the SDK.
4
+ * Owned entropy, ASCII and digest bytes are cleared on success and failure.
5
+ * Immutable returned hex and runtime/native copies cannot be explicitly erased.
6
+ * @param {(Uint8Array) => Uint8Array} randomizer
7
+ * @returns {Promise<string>} 128 lowercase hex characters; not an auth credential.
8
+ */
9
+ export async function passKey(randomizer = null) {
10
+ const entropy = new Uint8Array(64),
11
+ ascii = new Uint8Array(144)
12
+ let digest
13
+
14
+ try {
15
+ if (!randomizer) globalThis.crypto.getRandomValues(entropy)
16
+ else randomizer(entropy)
17
+
18
+ let offset = 0
19
+
20
+ for (let uuid = 0; uuid < 4; uuid++) {
21
+ const start = uuid * 16
22
+
23
+ entropy[start + 6] = (entropy[start + 6] & 15) | 64
24
+ entropy[start + 8] = (entropy[start + 8] & 63) | 128
25
+
26
+ for (let index = 0; index < 16; index++) {
27
+ if ([4, 6, 8, 10].includes(index)) ascii[offset++] = 45
28
+
29
+ const value = entropy[start + index]
30
+
31
+ for (const nibble of [value >>> 4, value & 15])
32
+ ascii[offset++] = nibble < 10 ? 48 + nibble : 87 + nibble
33
+ }
34
+ }
35
+
36
+ digest = new Uint8Array(
37
+ await globalThis.crypto.subtle.digest('SHA-512', ascii)
38
+ )
39
+
40
+ return Array.from(digest, (byte) =>
41
+ byte.toString(16).padStart(2, '0')
42
+ ).join('')
43
+ } finally {
44
+ entropy.fill(0)
45
+ ascii.fill(0)
46
+ digest?.fill(0)
47
+ }
48
+ }
package/transaction.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { JSONValue, ParseResult } from './types.js'
2
+ import { ByteaJSON } from './bytea.js'
2
3
 
3
4
  export type TXType =
4
5
  | 'initial_storage'
@@ -126,7 +127,7 @@ export interface TransactionInput {
126
127
  sender_addr: string
127
128
  recipient_addr: string
128
129
  data: JSONValue
129
- sign: string
130
+ sign: string | ByteaJSON
130
131
  fee: number
131
132
  hash?: string
132
133
  /** Date text/RFC3339Nano, Unix milliseconds or a caller-owned Date. */
@@ -161,7 +162,7 @@ export declare class Transaction {
161
162
 
162
163
  get CipherData(): JSONValue | undefined
163
164
 
164
- get Sign(): string
165
+ get Sign(): string | ByteaJSON
165
166
 
166
167
  get Fee(): number
167
168
 
package/transaction.js CHANGED
@@ -146,7 +146,7 @@ export class Transaction {
146
146
  * @param {string} sender_addr
147
147
  * @param {string} recipient_addr
148
148
  * @param {string} data
149
- * @param {string} sign
149
+ * @param {string|import('./bytea.js').ByteaJSON} sign
150
150
  * @param {number} fee
151
151
  * @param {string} hash
152
152
  * @param {string|number|Date} [inserted_at] Date text/RFC3339Nano, Unix milliseconds or Date.
@@ -240,6 +240,7 @@ export class Transaction {
240
240
  return this._cipherData
241
241
  }
242
242
 
243
+ /** @returns {string|import('./bytea.js').ByteaJSON} Factory signatures are detached and frozen. */
243
244
  get Sign() {
244
245
  return this._sign
245
246
  }
@@ -310,7 +311,7 @@ export class Transaction {
310
311
  if (typeof obj.cipher_data !== 'undefined')
311
312
  tx._cipherData = cloneAndFreeze(obj.cipher_data)
312
313
 
313
- tx._sign = obj.sign
314
+ tx._sign = cloneAndFreeze(obj.sign)
314
315
  tx._fee = obj.fee
315
316
  tx._hash = obj.hash
316
317
 
@@ -435,7 +436,18 @@ export class Transaction {
435
436
  if (typeof this._data === 'undefined')
436
437
  throw new Error(INVALID_ARGUMENT_WITH_CS('data'))
437
438
 
438
- if (typeof this._sign !== 'string' || !this._sign.length)
439
+ if (
440
+ !(typeof this._sign === 'string' && this._sign.length > 0) &&
441
+ !(
442
+ this._sign &&
443
+ typeof this._sign === 'object' &&
444
+ !Array.isArray(this._sign) &&
445
+ [Object.prototype, null].includes(Object.getPrototypeOf(this._sign)) &&
446
+ typeof this._sign.Bytes === 'string' &&
447
+ this._sign.Bytes.length > 0 &&
448
+ this._sign.Status === 2
449
+ )
450
+ )
439
451
  throw new Error(INVALID_ARGUMENT_WITH_CS('sign'))
440
452
 
441
453
  if (!Number.isFinite(this._fee) || this._fee < 0)