]> git.codecow.com Git - libnemo.git/commitdiff
Fix recursive imports and use convert modules instead of tools modules for text codec.
authorChris Duncan <chris@codecow.com>
Mon, 6 Jul 2026 06:27:08 +0000 (23:27 -0700)
committerChris Duncan <chris@codecow.com>
Mon, 6 Jul 2026 06:27:08 +0000 (23:27 -0700)
src/lib/convert/bytes.ts
src/lib/convert/utf8.ts
src/lib/crypto/bip39.ts
src/lib/crypto/bip44.ts
src/lib/crypto/wallet-aes-gcm.ts
src/lib/ledger/open.ts
src/lib/tools.ts
src/lib/vault/vault-worker.ts

index 3ff0855ca32f8cb5f6eed720a5aa65b23823b87c..cb29382c18df980a6c532d173bb6cb01c4fc438e 100644 (file)
@@ -2,7 +2,8 @@
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
 import { ALPHABET, HEXCHAR } from '../constants'
-import { decode } from '../tools'
+
+const decoder = Object.freeze(new TextDecoder())
 
 export const bytes = Object.freeze({
        /**
@@ -104,6 +105,6 @@ export const bytes = Object.freeze({
         * @returns {string} UTF-8 encoded text string
         */
        toUtf8 (bytes: Bytes): string {
-               return decode(bytes)
+               return decoder.decode(bytes)
        },
 })
index 2223be46cc1e8916204da6e891851586549e9b15..2bbb96d5036df5ce557bfc3be6203f29b91fd70f 100644 (file)
@@ -1,9 +1,10 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-import { encode } from '../tools'
 import { bytes } from './bytes'
 
+const encoder = Object.freeze(new TextEncoder())
+
 export const utf8 = Object.freeze({
        /**
         * Convert a UTF-8 text string to an ArrayBuffer.
@@ -22,7 +23,7 @@ export const utf8 = Object.freeze({
         * @returns {Uint8Array} Byte array representation of the input string
         */
        toBytes (utf8: string): Bytes {
-               return encode(utf8)
+               return encoder.encode(utf8)
        },
 
        /**
index 19e2c0f346b8959dc8c569a885dbbdafddbc4cb3..91e0b6b5af3b73407511570442aa9786fdbc7eb4 100644 (file)
@@ -1,8 +1,7 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>\r
 //! SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
-import { bytes } from '../convert'\r
-import { encode } from '../tools'\r
+import { bytes, utf8 } from '../convert'\r
 import { wordlist } from './wordlist'\r
 \r
 /**\r
@@ -194,13 +193,13 @@ export class Bip39 {
                        return Promise.resolve(seed)\r
                } else {\r
                        const salt = (typeof passphrase === 'string') ? passphrase : ''\r
-                       const keyData = encode(this.phrase)\r
+                       const keyData = utf8.toBuffer(this.phrase)\r
                        return crypto.subtle.importKey('raw', keyData, 'PBKDF2', false, ['deriveBits', 'deriveKey'])\r
                                .then(phraseKey => {\r
                                        const algorithm: Pbkdf2Params = {\r
                                                name: 'PBKDF2',\r
                                                hash: 'SHA-512',\r
-                                               salt: encode(`mnemonic${salt.normalize('NFKD')}`),\r
+                                               salt: utf8.toBuffer(`mnemonic${salt.normalize('NFKD')}`),\r
                                                iterations: 2048\r
                                        }\r
                                        return crypto.subtle.deriveBits(algorithm, phraseKey, 512)\r
index 11de053a8b6ecc9c822c138f1f454cd4c0c13c79..954f3f351f207d4fb22325640108069de39bf466 100644 (file)
@@ -2,8 +2,7 @@
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
 import { Point, getPublicKey as secp256k1_getPublicKey } from '@noble/secp256k1'
-import { dec } from '../convert'
-import { encode } from '../tools'
+import { dec, utf8 } from '../convert'
 
 type Curve = 'Bitcoin seed' | 'ed25519 seed'
 type ExtendedKey = {
@@ -76,7 +75,7 @@ function ckd (curve: Curve, seed: ArrayBuffer, coin: number, account: number, ch
 }
 
 function slip10 (curve: string, S: ArrayBuffer): Promise<ExtendedKey> {
-       const key = encode(curve).buffer
+       const key = utf8.toBuffer(curve)
        const data = S
        return hmac(key, data)
                .then(I => {
index 7a3869dde482e7ca52e2689d09938eac51ca18b0..1fcca162b99694698daaa4da3cd83753eaef77fd 100644 (file)
@@ -3,11 +3,12 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-import { encode } from "../tools"
+import { utf8 } from "../convert"
+
 export class WalletAesGcm {
        static decrypt (type: string, key: CryptoKey, iv: ArrayBuffer, encrypted: ArrayBuffer): Promise<Record<string, ArrayBuffer>> {
                const seedLength = type === 'BLAKE2b' ? 32 : 64
-               const additionalData = encode(type)
+               const additionalData = utf8.toBuffer(type)
                return crypto.subtle
                        .decrypt({ name: 'AES-GCM', iv, additionalData }, key, encrypted)
                        .then(decrypted => {
@@ -30,7 +31,7 @@ export class WalletAesGcm {
                }
                // restrict iv to 96 bits per GCM best practice
                const iv = crypto.getRandomValues(new Uint8Array(12)).buffer
-               const additionalData = encode(type)
+               const additionalData = utf8.toBuffer(type)
                const encoded = new Uint8Array([...new Uint8Array(seed), ...new Uint8Array(mnemonic ?? [])])
                return crypto.subtle
                        .encrypt({ name: 'AES-GCM', iv, additionalData }, key, encoded)
index 59edc68a31ce4a9baa018b91d66c6078dcd42599..7198ed7507881228bd2bf1e53ed03ad934c21c0e 100644 (file)
@@ -3,11 +3,10 @@
 
 import { TransportStatusError } from '@ledgerhq/errors'
 import { APDU_CODES, LISTEN_TIMEOUT, LedgerResponse, LedgerTransport, OPEN_TIMEOUT, STATUS_CODES } from '.'
-import { bytes } from '../convert'
-import { encode } from '../tools'
+import { bytes, utf8 } from '../convert'
 
 export async function _open (transport: LedgerTransport): Promise<LedgerResponse> {
-       const name = encode('Nano')
+       const name = utf8.toBytes('Nano')
        const t = await transport.create(OPEN_TIMEOUT, LISTEN_TIMEOUT)
        const response = await t
                .send(0xe0, 0xd8, APDU_CODES.paramUnused, APDU_CODES.paramUnused, name as Buffer)
index 4470314a5432b1be72398b233d93766b85bf8a67..9c8e28e283cad6c5a98beededcb87abd3274f7d1 100644 (file)
@@ -15,27 +15,6 @@ type SweepResult = {
        message: string
 }
 
-/**
- * Decodes bytes to a UTF-8 string.
- *
- * @param {AllowSharedBufferSource} [input]
- * @param {TextDecodeOptions} [options]
- * @returns {string} Decoded string
- */
-export function decode (input?: AllowSharedBufferSource, options?: TextDecodeOptions): string {
-       return decoder.decode(input, options)
-}
-
-/**
- * Encodes a UTF-8 string to bytes.
- *
- * @param {string} [input]
- * @returns {Bytes} Encoded bytes
- */
-export function encode (input?: string): Bytes {
-       return encoder.encode(input)
-}
-
 /**
  * Converts a decimal amount of nano from one unit divider to another.
  *
@@ -229,6 +208,3 @@ function normalize (input: string | ArrayBuffer | Bytes): Bytes {
                        ? new Uint8Array(input.slice())
                        : input
 }
-
-const decoder = Object.freeze(new TextDecoder())
-const encoder = Object.freeze(new TextEncoder())
index 514471a3a3fd0a0be97c7b78839803db2c573447..ede1faeeda85ecade9f824b99031d8b70a6d992a 100644 (file)
@@ -4,9 +4,8 @@
 import { derive as nano25519_derive, sign as nano25519_sign } from 'nano25519/sync'
 import { parentPort, threadId } from 'node:worker_threads'
 import { BIP44_COIN_NANO } from '../constants'
-import { dec } from '../convert'
+import { dec, utf8 } from '../convert'
 import { Bip39, Bip44, Blake2b, WalletAesGcm } from '../crypto'
-import { encode } from '../tools'
 import { WalletType } from '../wallet'
 import { parseAction, parseData, parseIv, parseKeySalt, parseType } from './parsers'
 import { Passkey } from './passkey'
@@ -365,7 +364,7 @@ function verify (seed?: ArrayBuffer, mnemonicPhrase?: string): Promise<Record<st
                }
                if (mnemonicPhrase != null) {
                        let diff = 0
-                       const userMnemonic = encode(mnemonicPhrase)
+                       const userMnemonic = utf8.toBytes(mnemonicPhrase)
                        const thisMnemonic = new Uint8Array(_mnemonic ?? [])
                        for (let i = 0; i < userMnemonic.byteLength; i++) {
                                diff |= userMnemonic[i] ^ thisMnemonic[i]
@@ -470,7 +469,7 @@ function _load (type?: 'BIP-44' | 'BLAKE2b' | 'Exodus', key?: CryptoKey, keySalt
                        if (type === 'BLAKE2b') {
                                seed = Bip39.fromEntropy(new Uint8Array(secret))
                                        .then(bip39 => {
-                                               _mnemonic = new Uint8Array(encode(bip39.phrase ?? '')).buffer
+                                               _mnemonic = utf8.toBuffer(bip39.phrase ?? '')
                                                return secret
                                        })
                        } else {
@@ -479,7 +478,7 @@ function _load (type?: 'BIP-44' | 'BLAKE2b' | 'Exodus', key?: CryptoKey, keySalt
                } else {
                        seed = Bip39.fromPhrase(secret)
                                .then(bip39 => {
-                                       _mnemonic = new Uint8Array(encode(bip39.phrase ?? '')).buffer
+                                       _mnemonic = utf8.toBuffer(bip39.phrase ?? '')
                                        const derive = type === 'BLAKE2b'
                                                ? Promise.resolve(bip39.toBlake2bSeed())
                                                : bip39.toBip39Seed(mnemonicSalt ?? '')