@bsv/sdk 1.9.19 → 1.9.22

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.
Files changed (55) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/certificates/MasterCertificate.js +9 -2
  3. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  4. package/dist/cjs/src/primitives/DRBG.js +12 -1
  5. package/dist/cjs/src/primitives/DRBG.js.map +1 -1
  6. package/dist/cjs/src/primitives/Hash.js +6 -5
  7. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  8. package/dist/cjs/src/primitives/hex.js +33 -0
  9. package/dist/cjs/src/primitives/hex.js.map +1 -0
  10. package/dist/cjs/src/primitives/index.js +1 -3
  11. package/dist/cjs/src/primitives/index.js.map +1 -1
  12. package/dist/cjs/src/primitives/utils.js +69 -59
  13. package/dist/cjs/src/primitives/utils.js.map +1 -1
  14. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  15. package/dist/esm/src/auth/certificates/MasterCertificate.js +9 -2
  16. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  17. package/dist/esm/src/primitives/DRBG.js +12 -1
  18. package/dist/esm/src/primitives/DRBG.js.map +1 -1
  19. package/dist/esm/src/primitives/Hash.js +6 -5
  20. package/dist/esm/src/primitives/Hash.js.map +1 -1
  21. package/dist/esm/src/primitives/hex.js +29 -0
  22. package/dist/esm/src/primitives/hex.js.map +1 -0
  23. package/dist/esm/src/primitives/index.js +0 -1
  24. package/dist/esm/src/primitives/index.js.map +1 -1
  25. package/dist/esm/src/primitives/utils.js +69 -59
  26. package/dist/esm/src/primitives/utils.js.map +1 -1
  27. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  28. package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
  29. package/dist/types/src/primitives/DRBG.d.ts +12 -1
  30. package/dist/types/src/primitives/DRBG.d.ts.map +1 -1
  31. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  32. package/dist/types/src/primitives/hex.d.ts +3 -0
  33. package/dist/types/src/primitives/hex.d.ts.map +1 -0
  34. package/dist/types/src/primitives/index.d.ts +0 -1
  35. package/dist/types/src/primitives/index.d.ts.map +1 -1
  36. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  37. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  38. package/dist/umd/bundle.js +3 -3
  39. package/dist/umd/bundle.js.map +1 -1
  40. package/docs/reference/auth.md +2 -2
  41. package/docs/reference/primitives.md +90 -31
  42. package/package.json +1 -1
  43. package/src/auth/__tests/Peer.test.ts +2 -1
  44. package/src/auth/certificates/MasterCertificate.ts +9 -2
  45. package/src/auth/certificates/__tests/MasterCertificate.test.ts +46 -9
  46. package/src/primitives/DRBG.ts +12 -1
  47. package/src/primitives/Hash.ts +9 -6
  48. package/src/primitives/__tests/HMAC.test.ts +13 -2
  49. package/src/primitives/__tests/Hash.test.ts +24 -0
  50. package/src/primitives/__tests/hex.test.ts +57 -0
  51. package/src/primitives/__tests/utils.test.ts +39 -0
  52. package/src/primitives/hex.ts +35 -0
  53. package/src/primitives/index.ts +0 -1
  54. package/src/primitives/utils.ts +71 -65
  55. package/src/script/__tests/Script.test.ts +1 -1
@@ -1,11 +1,11 @@
1
1
  import BigNumber from './BigNumber.js'
2
2
  import { hash256 } from './Hash.js'
3
+ import { assertValidHex } from './hex.js'
3
4
 
4
5
  const BufferCtor =
5
6
  typeof globalThis !== 'undefined' ? (globalThis as any).Buffer : undefined
6
7
  const CAN_USE_BUFFER =
7
8
  BufferCtor != null && typeof BufferCtor.from === 'function'
8
- const PURE_HEX_REGEX = /^[0-9a-fA-F]+$/
9
9
 
10
10
  /**
11
11
  * Prepends a '0' to an odd character length word to ensure it has an even number of characters.
@@ -80,28 +80,19 @@ for (let i = 0; i < 6; i++) {
80
80
  }
81
81
 
82
82
  const hexToArray = (msg: string): number[] => {
83
- if (CAN_USE_BUFFER && PURE_HEX_REGEX.test(msg)) {
84
- const normalized = msg.length % 2 === 0 ? msg : '0' + msg
83
+ assertValidHex(msg)
84
+ const normalized = msg.length % 2 === 0 ? msg : '0' + msg
85
+ if (CAN_USE_BUFFER) {
85
86
  return Array.from(BufferCtor.from(normalized, 'hex'))
86
87
  }
87
- const res: number[] = new Array(Math.ceil(msg.length / 2))
88
- let nibble = -1
89
- let size = 0
90
- for (let i = 0; i < msg.length; i++) {
91
- const value = HEX_CHAR_TO_VALUE[msg.charCodeAt(i)]
92
- if (value === -1) continue
93
- if (nibble === -1) {
94
- nibble = value
95
- } else {
96
- res[size++] = (nibble << 4) | value
97
- nibble = -1
98
- }
99
- }
100
- if (nibble !== -1) {
101
- res[size++] = nibble
88
+ const out = new Array(normalized.length / 2)
89
+ let o = 0
90
+ for (let i = 0; i < normalized.length; i += 2) {
91
+ const hi = HEX_CHAR_TO_VALUE[normalized.charCodeAt(i)]
92
+ const lo = HEX_CHAR_TO_VALUE[normalized.charCodeAt(i + 1)]
93
+ out[o++] = (hi << 4) | lo
102
94
  }
103
- if (size !== res.length) res.length = size
104
- return res
95
+ return out
105
96
  }
106
97
 
107
98
  export function base64ToArray (msg: string): number[] {
@@ -233,69 +224,84 @@ function utf8ToArray (str: string): number[] {
233
224
  */
234
225
  export const toUTF8 = (arr: number[]): string => {
235
226
  let result = ''
236
- let skip = 0
237
-
227
+ const replacementChar = '\uFFFD'
238
228
  for (let i = 0; i < arr.length; i++) {
239
- const byte = arr[i]
240
- // this byte is part of a multi-byte sequence, skip it
241
- // added to avoid modifying i within the loop which is considered unsafe.
242
- if (skip > 0) {
243
- skip--
229
+ const byte1 = arr[i]
230
+ if (byte1 <= 0x7f) {
231
+ result += String.fromCharCode(byte1)
244
232
  continue
245
233
  }
246
-
247
- // 1-byte sequence (0xxxxxxx)
248
- if (byte <= 0x7f) {
249
- result += String.fromCharCode(byte)
250
- continue
234
+ const emitReplacement = (): void => {
235
+ result += replacementChar
251
236
  }
252
-
253
- // 2-byte sequence (110xxxxx 10xxxxxx)
254
- if (byte >= 0xc0 && byte <= 0xdf) {
255
- const avail = arr.length - (i + 1)
256
- const byte2 = avail >= 1 ? arr[i + 1] : 0
257
- skip = Math.min(1, avail)
258
-
259
- const codePoint = ((byte & 0x1f) << 6) | (byte2 & 0x3f)
237
+ if (byte1 >= 0xc0 && byte1 <= 0xdf) {
238
+ if (i + 1 >= arr.length) {
239
+ emitReplacement()
240
+ continue
241
+ }
242
+ const byte2 = arr[i + 1]
243
+ if ((byte2 & 0xc0) !== 0x80) {
244
+ emitReplacement()
245
+ i += 1
246
+ continue
247
+ }
248
+ const codePoint = ((byte1 & 0x1f) << 6) | (byte2 & 0x3f)
260
249
  result += String.fromCharCode(codePoint)
250
+ i += 1
261
251
  continue
262
252
  }
263
-
264
- // 3-byte sequence (1110xxxx 10xxxxxx 10xxxxxx)
265
- if (byte >= 0xe0 && byte <= 0xef) {
266
- const avail = arr.length - (i + 1)
267
- const byte2 = avail >= 1 ? arr[i + 1] : 0
268
- const byte3 = avail >= 2 ? arr[i + 2] : 0
269
- skip = Math.min(2, avail)
270
-
253
+ if (byte1 >= 0xe0 && byte1 <= 0xef) {
254
+ if (i + 2 >= arr.length) {
255
+ emitReplacement()
256
+ continue
257
+ }
258
+ const byte2 = arr[i + 1]
259
+ const byte3 = arr[i + 2]
260
+ if ((byte2 & 0xc0) !== 0x80 || (byte3 & 0xc0) !== 0x80) {
261
+ emitReplacement()
262
+ i += 2
263
+ continue
264
+ }
271
265
  const codePoint =
272
- ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f)
266
+ ((byte1 & 0x0f) << 12) |
267
+ ((byte2 & 0x3f) << 6) |
268
+ (byte3 & 0x3f)
269
+
273
270
  result += String.fromCharCode(codePoint)
271
+ i += 2
274
272
  continue
275
273
  }
276
-
277
- // 4-byte sequence (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
278
- if (byte >= 0xf0 && byte <= 0xf7) {
279
- const avail = arr.length - (i + 1)
280
- const byte2 = avail >= 1 ? arr[i + 1] : 0
281
- const byte3 = avail >= 2 ? arr[i + 2] : 0
282
- const byte4 = avail >= 3 ? arr[i + 3] : 0
283
- skip = Math.min(3, avail)
284
-
274
+ if (byte1 >= 0xf0 && byte1 <= 0xf7) {
275
+ if (i + 3 >= arr.length) {
276
+ emitReplacement()
277
+ continue
278
+ }
279
+ const byte2 = arr[i + 1]
280
+ const byte3 = arr[i + 2]
281
+ const byte4 = arr[i + 3]
282
+ if (
283
+ (byte2 & 0xc0) !== 0x80 ||
284
+ (byte3 & 0xc0) !== 0x80 ||
285
+ (byte4 & 0xc0) !== 0x80
286
+ ) {
287
+ emitReplacement()
288
+ i += 3
289
+ continue
290
+ }
285
291
  const codePoint =
286
- ((byte & 0x07) << 18) |
292
+ ((byte1 & 0x07) << 18) |
287
293
  ((byte2 & 0x3f) << 12) |
288
294
  ((byte3 & 0x3f) << 6) |
289
295
  (byte4 & 0x3f)
290
-
291
- // Convert to UTF-16 surrogate pair
292
- const surrogate1 = 0xd800 + ((codePoint - 0x10000) >> 10)
293
- const surrogate2 = 0xdc00 + ((codePoint - 0x10000) & 0x3ff)
294
- result += String.fromCharCode(surrogate1, surrogate2)
296
+ const offset = codePoint - 0x10000
297
+ const highSurrogate = 0xd800 + (offset >> 10)
298
+ const lowSurrogate = 0xdc00 + (offset & 0x3ff)
299
+ result += String.fromCharCode(highSurrogate, lowSurrogate)
300
+ i += 3
295
301
  continue
296
302
  }
303
+ emitReplacement()
297
304
  }
298
-
299
305
  return result
300
306
  }
301
307
 
@@ -286,7 +286,7 @@ describe('Script', () => {
286
286
  }
287
287
 
288
288
  // Expect the function to throw an error with the specified message
289
- expect(createScript).toThrow('invalid hex string in script')
289
+ expect(createScript).toThrow('Invalid hex string')
290
290
  })
291
291
 
292
292
  it('should parse this long PUSHDATA1 script in ASM', () => {