@wishknish/knishio-client-js 0.9.0 → 0.9.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/dist/client.cjs.js +29 -29
- package/dist/client.cjs.js.map +1 -1
- package/dist/client.es.mjs +738 -721
- package/dist/client.es.mjs.map +1 -1
- package/dist/client.iife.js +29 -29
- package/dist/client.iife.js.map +1 -1
- package/package.json +9 -13
- package/src/Wallet.js +26 -1
- package/src/libraries/array.js +6 -4
- package/src/libraries/strings.js +33 -7
- package/src/types/index.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wishknish/knishio-client-js",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"productName": "Knish.IO Javascript SDK Client",
|
|
6
6
|
"description": "JavaScript implementation of the Knish.IO SDK to consume Knish.IO GraphQL APIs.",
|
|
@@ -65,22 +65,18 @@
|
|
|
65
65
|
"wonka": "^6.3.5"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@jest/globals": "^
|
|
68
|
+
"@jest/globals": "^30.4.1",
|
|
69
69
|
"@rollup/plugin-babel": "^6.1.0",
|
|
70
70
|
"@rollup/plugin-commonjs": "^28.0.9",
|
|
71
71
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
72
|
+
"@swc/core": "^1.15.43",
|
|
73
|
+
"@swc/jest": "^0.2.39",
|
|
72
74
|
"buffer": "^6.0.3",
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"eslint-plugin-import": "^2.32.0",
|
|
77
|
-
"eslint-plugin-n": "^16.6.2",
|
|
78
|
-
"eslint-plugin-promise": "^6.6.0",
|
|
79
|
-
"eslint-plugin-vue": "^9.33.0",
|
|
80
|
-
"esmock": "^2.7.3",
|
|
81
|
-
"jest": "^29.7.0",
|
|
75
|
+
"eslint": "^9.39.0",
|
|
76
|
+
"jest": "^30.4.2",
|
|
77
|
+
"neostandard": "^0.13.0",
|
|
82
78
|
"rollup": "^4.57.1",
|
|
83
|
-
"vite": "^
|
|
79
|
+
"vite": "^7.3.5"
|
|
84
80
|
},
|
|
85
81
|
"browserslist": [
|
|
86
82
|
"> 1%",
|
|
@@ -89,7 +85,7 @@
|
|
|
89
85
|
],
|
|
90
86
|
"scripts": {
|
|
91
87
|
"build": "vite build --config build/vite.config.mjs",
|
|
92
|
-
"lint": "eslint
|
|
88
|
+
"lint": "eslint src",
|
|
93
89
|
"test": "jest",
|
|
94
90
|
"test:coverage": "jest --coverage",
|
|
95
91
|
"selftest": "npm run build && node tests/scripts/self-test.js",
|
package/src/Wallet.js
CHANGED
|
@@ -300,10 +300,23 @@ export default class Wallet {
|
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
serializeKey (key) {
|
|
303
|
-
|
|
303
|
+
if (typeof Buffer !== 'undefined') {
|
|
304
|
+
return Buffer.from(key).toString('base64')
|
|
305
|
+
}
|
|
306
|
+
// String.fromCharCode.apply(null, key) overflows the call stack once the
|
|
307
|
+
// payload exceeds the engine's argument limit (~64K), so convert in chunks.
|
|
308
|
+
let binary = ''
|
|
309
|
+
const CHUNK_SIZE = 0x8000
|
|
310
|
+
for (let i = 0; i < key.length; i += CHUNK_SIZE) {
|
|
311
|
+
binary += String.fromCharCode(...key.subarray(i, i + CHUNK_SIZE))
|
|
312
|
+
}
|
|
313
|
+
return btoa(binary)
|
|
304
314
|
}
|
|
305
315
|
|
|
306
316
|
deserializeKey (serializedKey) {
|
|
317
|
+
if (typeof Buffer !== 'undefined') {
|
|
318
|
+
return new Uint8Array(Buffer.from(serializedKey, 'base64'))
|
|
319
|
+
}
|
|
307
320
|
const binaryString = atob(serializedKey)
|
|
308
321
|
return new Uint8Array(binaryString.length).map((_, i) => binaryString.charCodeAt(i))
|
|
309
322
|
}
|
|
@@ -486,6 +499,18 @@ export default class Wallet {
|
|
|
486
499
|
const messageString = JSON.stringify(message)
|
|
487
500
|
const messageUint8 = new TextEncoder().encode(messageString)
|
|
488
501
|
const deserializedPubkey = this.deserializeKey(recipientPubkey)
|
|
502
|
+
// ML-KEM-768 public keys are exactly 1184 bytes. A wrong-length key here almost always means the
|
|
503
|
+
// node did not advertise an ML-KEM public key in its auth `key` field (e.g. a validator predating
|
|
504
|
+
// the PQ-transport build). Fail with an actionable message rather than the crypto lib's cryptic
|
|
505
|
+
// `"publicKey" expected Uint8Array of length 1184, got length=N` assertion.
|
|
506
|
+
const ML_KEM_768_PUBLIC_KEY_BYTES = 1184
|
|
507
|
+
if (deserializedPubkey.length !== ML_KEM_768_PUBLIC_KEY_BYTES) {
|
|
508
|
+
throw new Error(
|
|
509
|
+
`KnishIO: cannot ML-KEM-encrypt — recipient public key is ${deserializedPubkey.length} bytes, ` +
|
|
510
|
+
`expected ${ML_KEM_768_PUBLIC_KEY_BYTES} (ML-KEM-768). The node likely did not advertise an ML-KEM ` +
|
|
511
|
+
'public key (upgrade the validator to a PQ-transport build), or authenticate with { encrypt: false }.'
|
|
512
|
+
)
|
|
513
|
+
}
|
|
489
514
|
const { cipherText, sharedSecret } = MlKEM768.encapsulate(deserializedPubkey)
|
|
490
515
|
const encryptedMessage = await this.encryptWithSharedSecret(messageUint8, sharedSecret)
|
|
491
516
|
return {
|
package/src/libraries/array.js
CHANGED
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
* @return {array}
|
|
7
7
|
*/
|
|
8
8
|
export function chunkArray (arr, size) {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Iterative: the previous recursive form (`concat` + `slice(size)` per level) blew
|
|
10
|
+
// the call stack and allocated O(n^2) once arr grew past a few thousand elements.
|
|
11
|
+
const chunks = []
|
|
12
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
13
|
+
chunks.push(arr.slice(i, i + size))
|
|
11
14
|
}
|
|
12
|
-
|
|
13
|
-
return [arr.slice(0, size)].concat(chunkArray(arr.slice(size), size))
|
|
15
|
+
return chunks
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export function deepCloning (
|
package/src/libraries/strings.js
CHANGED
|
@@ -45,13 +45,18 @@ export function chunkSubstr (str, size) {
|
|
|
45
45
|
* @return {string}
|
|
46
46
|
*/
|
|
47
47
|
export function randomString (length = 256, alphabet = 'abcdef0123456789') {
|
|
48
|
-
|
|
48
|
+
const array = new Uint8Array(length)
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
crypto.getRandomValues(array)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
// Build in a loop: String.fromCharCode.apply(null, array) spread every byte as a
|
|
53
|
+
// function argument and overflowed the call stack for a large caller-supplied length.
|
|
54
|
+
// `alphabet.charAt(x % len)` is the same mapping as the old fromCharCode(charCodeAt).
|
|
55
|
+
let result = ''
|
|
56
|
+
for (let i = 0; i < length; i++) {
|
|
57
|
+
result += alphabet.charAt(array[i] % alphabet.length)
|
|
58
|
+
}
|
|
59
|
+
return result
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
/**
|
|
@@ -120,7 +125,19 @@ export function hexStringToBuffer (hexString) {
|
|
|
120
125
|
*/
|
|
121
126
|
export function hexToBase64 (string) {
|
|
122
127
|
const bytes = hexStringToBuffer(string)
|
|
123
|
-
|
|
128
|
+
// Buffer fast path (Node). Byte-identical to the btoa encoding below.
|
|
129
|
+
if (typeof Buffer !== 'undefined') {
|
|
130
|
+
return Buffer.from(bytes).toString('base64')
|
|
131
|
+
}
|
|
132
|
+
// Browser fallback: String.fromCharCode.apply(null, bytes) spreads every byte as a
|
|
133
|
+
// function argument and overflows the call stack past the engine's argument limit
|
|
134
|
+
// (~64K), so convert in chunks.
|
|
135
|
+
let binary = ''
|
|
136
|
+
const CHUNK_SIZE = 0x8000
|
|
137
|
+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
138
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK_SIZE))
|
|
139
|
+
}
|
|
140
|
+
return btoa(binary)
|
|
124
141
|
}
|
|
125
142
|
|
|
126
143
|
/**
|
|
@@ -130,7 +147,16 @@ export function hexToBase64 (string) {
|
|
|
130
147
|
* @return {string}
|
|
131
148
|
*/
|
|
132
149
|
export function base64ToHex (string) {
|
|
133
|
-
|
|
150
|
+
// Buffer fast path (Node); index loop otherwise. The old `atob(string).split('')`
|
|
151
|
+
// allocated one single-char string per byte — prohibitive for multi-MB payloads.
|
|
152
|
+
if (typeof Buffer !== 'undefined') {
|
|
153
|
+
return bufferToHexString(new Uint8Array(Buffer.from(string, 'base64')))
|
|
154
|
+
}
|
|
155
|
+
const binary = atob(string)
|
|
156
|
+
const bytes = new Uint8Array(binary.length)
|
|
157
|
+
for (let i = 0; i < binary.length; i++) {
|
|
158
|
+
bytes[i] = binary.charCodeAt(i)
|
|
159
|
+
}
|
|
134
160
|
return bufferToHexString(bytes)
|
|
135
161
|
}
|
|
136
162
|
|
package/src/types/index.js
DELETED