]> git.codecow.com Git - libnemo.git/commitdiff
Update JSdoc for sign methods. Remove output option for sign method and just referenc...
authorChris Duncan <chris@zoso.dev>
Mon, 11 Aug 2025 13:33:15 +0000 (06:33 -0700)
committerChris Duncan <chris@zoso.dev>
Mon, 11 Aug 2025 13:33:15 +0000 (06:33 -0700)
src/lib/block.ts
src/lib/wallet/index.ts
src/lib/wallet/ledger.ts

index 2566ab535f692e82ab618eb6af0f92f461024da4..b57946d95b5dc359ebe5f1f1c2371e40eb49c20c 100644 (file)
@@ -378,7 +378,8 @@ export class Block {
        /**
        * Sets the `signature` property of the block to a precalculated value.
        *
-       * @param {string} [key] - 64-byte hexadecimal signature
+       * @param {string} signature - 64-byte hexadecimal signature
+       * @returns Block with `signature` value set
        */
        sign (signature: string): Block
        /**
@@ -386,18 +387,10 @@ export class Block {
        * the `signature` property of the block.
        *
        * @param {string} [key] - 32-byte hexadecimal private key to use for signing
+       * @returns Block with `signature` value set
        */
        async sign (key: string): Promise<Block>
        /**
-       * Signs the block using a Wallet. If successful, the result is stored in
-       * the `signature` property of the block. The wallet must be unlocked prior to
-       * signing.
-       *
-       * @param {Wallet} wallet - Wallet to use for signing
-       * @param {number} index - Account in wallet to use for signing
-       */
-       async sign (wallet: Wallet, index: number): Promise<Block>
-       /**
        * Signs the block using a Ledger hardware wallet. If that fails, an error is
        * thrown with the status code from the device. If successful, the result is
        * stored in the `signature` property of the block. The wallet must be unlocked
@@ -405,8 +398,19 @@ export class Block {
        *
        * @param {number} index - Account index between 0x0 and 0x7fffffff
        * @param {object} [frontier] - JSON of frontier block for offline signing
+       * @returns Block with `signature` value set
        */
        async sign (index: number, frontier?: Block): Promise<Block>
+       /**
+       * Signs the block using a Wallet. If successful, the result is stored in
+       * the `signature` property of the block. The wallet must be unlocked prior to
+       * signing.
+       *
+       * @param {Wallet} wallet - Wallet to use for signing
+       * @param {number} index - Account in wallet to use for signing
+       * @returns Block with `signature` value set
+       */
+       async sign (wallet: Wallet, index: number): Promise<Block>
        sign (input: unknown, param?: unknown): Block | Promise<Block> {
                if (typeof input === 'string' && /^[A-F0-9]{128}$/.test(input)) {
                        this.signature = input
@@ -414,14 +418,14 @@ export class Block {
                }
                return new Promise(async (resolve, reject) => {
                        try {
-                               if (typeof input !== 'number' && typeof input !== 'string' && !(input instanceof Wallet)) {
+                               if (typeof input === 'string' && /^[A-F0-9]{64}$/.test(input)) {
+                                       const signature = await NanoNaCl.detached(this.#hash(), hex.toBytes(input))
+                                       this.signature = bytes.toHex(signature)
+                               } else if (typeof input !== 'number' && typeof input !== 'string' && !(input instanceof Wallet)) {
                                        throw new TypeError('Invalid signing input')
-                               } else if (typeof input === 'string' && /^[A-F0-9]{64}$/.test(input)) {
-                                       const sig = await NanoNaCl.detached(this.#hash(), hex.toBytes(input))
-                                       this.signature = bytes.toHex(sig)
                                } else if (input instanceof Wallet && typeof param === 'number') {
                                        const wallet = input
-                                       await wallet.sign(param, this, 'hex')
+                                       await wallet.sign(param, this)
                                } else if (typeof input === 'number') {
                                        const index = input
                                        const { Ledger } = await import('./wallet/ledger')
@@ -434,9 +438,9 @@ export class Block {
                                                        console.warn('Error updating Ledger cache of previous block, attempting signature anyway', err)
                                                }
                                        }
-                                       this.signature = await ledger.sign(index, this, 'hex')
+                                       await ledger.sign(index, this)
                                } else {
-                                       throw new TypeError('invalid key for block signature', { cause: typeof input })
+                                       throw new TypeError('Invalid key for block signature', { cause: typeof input })
                                }
                                resolve(this)
                        } catch (err) {
index 60d406e5bc7dc0d3d82a600030c07f3270a9cf2a..b03275a2d67f5e6403a71263761091451f7fe326 100644 (file)
@@ -336,31 +336,24 @@ export class Wallet {
        *\r
        * @param {number} index - Account to use for signing\r
        * @param {(Block)} block - Block data to be hashed and signed\r
-       * @returns {Promise<string>} Hexadecimal-formatted 64-byte signature\r
        */\r
-       async sign (index: number, block: Block): Promise<Uint8Array<ArrayBuffer>>\r
-       /**\r
-       * Signs a block using the private key of the account at the wallet index\r
-       * specified. The signature is appended to the signature field of the block\r
-       * before being returned. The wallet must be unlocked prior to signing.\r
-       *\r
-       * @param {number} index - Account to use for signing\r
-       * @param {(Block)} block - Block data to be hashed and signed\r
-       * @returns {Promise<string>} Hexadecimal-formatted 64-byte signature\r
-       */\r
-       async sign (index: number, block: Block, format: 'hex'): Promise<string>\r
-       async sign (index: number, block: Block, format?: 'hex'): Promise<string | Uint8Array<ArrayBuffer>> {\r
+       async sign (index: number, block: Block): Promise<void>\r
+       async sign (index: unknown, block: unknown): Promise<void> {\r
                try {\r
+                       if (typeof index !== 'number') {\r
+                               throw new TypeError('Index must be a number', { cause: index })\r
+                       }\r
+                       if (!(block instanceof Block)) {\r
+                               throw new TypeError('Invalid Block', { cause: block })\r
+                       }\r
                        const { signature } = await this.#vault.request<ArrayBuffer>({\r
                                action: 'sign',\r
                                index,\r
                                data: hex.toBuffer(block.hash)\r
                        })\r
-                       const sig = new Uint8Array(signature)\r
-                       block.signature = bytes.toHex(sig)\r
+                       block.signature = bytes.toHex(new Uint8Array(signature))\r
                        clearTimeout(this.#lockTimer)\r
                        this.#lockTimer = setTimeout(() => this.lock(), 300000)\r
-                       return format === 'hex' ? block.signature : sig\r
                } catch (err) {\r
                        throw new Error(`Failed to sign block`, { cause: err })\r
                }\r
@@ -372,8 +365,12 @@ export class Wallet {
        * @param {string} password Used previously to lock the wallet\r
        * @returns True if successfully unlocked\r
        */\r
-       async unlock (password: string): Promise<boolean> {\r
+       async unlock (password: string): Promise<boolean>\r
+       async unlock (password: unknown): Promise<boolean> {\r
                try {\r
+                       if (typeof password !== 'string') {\r
+                               throw new TypeError('Password must be a string')\r
+                       }\r
                        const { iv, salt, encrypted } = await Wallet.#get(this.#id)\r
                        const { isUnlocked } = await this.#vault.request<boolean>({\r
                                action: 'unlock',\r
index 661a3d342379e3b8d898d79233854a8fad07f81b..b337bb9d1153508a8d92be7792853950f1baf2ee 100644 (file)
@@ -262,41 +262,40 @@ export class Ledger extends Wallet {
        * Sign a block with the Ledger device.\r
        *\r
        * @param {number} index - Account number\r
-       * @param {object} block - Block data to sign\r
-       * @returns {Promise<string>} Signature\r
+       * @param {Block} block - Block data to sign\r
+       * @param {Block} [frontier] - Previous block data to cache in the device\r
        */\r
-       async sign (index: number, block: Block): Promise<Uint8Array<ArrayBuffer>>\r
-       /**\r
-       * Sign a block with the Ledger device.\r
-       *\r
-       * @param {number} index - Account number\r
-       * @param {object} block - Block data to sign\r
-       * @returns {Promise<string>} Signature\r
-       */\r
-       async sign (index: number, block: Block, format?: 'hex', frontier?: Block): Promise<string>\r
-       async sign (index: number, block: Block, format?: 'hex', frontier?: Block): Promise<string | Uint8Array<ArrayBuffer>> {\r
-               if (typeof index !== 'number' || index < 0 || index >= HARDENED_OFFSET) {\r
-                       throw new TypeError('Invalid account index')\r
-               }\r
-               if (frontier != null) {\r
-                       const { status } = await this.#cacheBlock(index, frontier)\r
+       async sign (index: number, block: Block, frontier?: Block): Promise<void>\r
+       async sign (index: number, block: Block, frontier?: Block): Promise<void> {\r
+               try {\r
+                       if (typeof index !== 'number') {\r
+                               throw new TypeError('Index must be a number', { cause: index })\r
+                       }\r
+                       if (index < 0 || index >= HARDENED_OFFSET) {\r
+                               throw new RangeError(`Index outside allowed range 0-${HARDENED_OFFSET}`, { cause: index })\r
+                       }\r
+                       if (frontier != null) {\r
+                               const { status } = await this.#cacheBlock(index, frontier)\r
+                               if (status !== 'OK') {\r
+                                       throw new Error('Failed to cache frontier block in ledger', { cause: status })\r
+                               }\r
+                       }\r
+                       console.log('Waiting for signature confirmation on Ledger device...')\r
+                       const { status, signature, hash } = await this.#signBlock(index, block)\r
                        if (status !== 'OK') {\r
-                               throw new Error('failed to cache frontier block in ledger', { cause: status })\r
+                               throw new Error('Signing with ledger failed', { cause: status })\r
                        }\r
+                       if (hash !== block.hash) {\r
+                               throw new Error('Hash from ledger does not match hash from block', { cause: `${hash} | ${block.hash}` })\r
+                       }\r
+                       if (signature == null) {\r
+                               throw new Error('Ledger silently failed to return signature')\r
+                       }\r
+                       block.signature = signature\r
+               } catch (err) {\r
+                       console.error(err)\r
+                       throw new Error('Failed to sign block with Ledger', { cause: err })\r
                }\r
-               console.log('Waiting for signature confirmation on Ledger device...')\r
-               const { status, signature, hash } = await this.#signBlock(index, block)\r
-               if (status !== 'OK') {\r
-                       throw new Error('signing with ledger failed', { cause: status })\r
-               }\r
-               if (hash !== block.hash) {\r
-                       throw new Error('hash from ledger does not match hash from block', { cause: `${hash} | ${block.hash}` })\r
-               }\r
-               if (signature == null) {\r
-                       throw new Error('ledger failed to return signature')\r
-               }\r
-               block.signature = signature\r
-               return format === 'hex' ? signature : hex.toBytes(signature)\r
        }\r
 \r
        /**\r
@@ -372,10 +371,10 @@ export class Ledger extends Wallet {
                        .sign(testWallet, 0)\r
                const testSendBlock = new Block(testAccount.address, '0', testOpenBlock.hash, testAccount.address)\r
                        .send(testAccount.address, 0)\r
-               const testSignature = await testWallet.sign(0, testOpenBlock, 'hex')\r
+               await testWallet.sign(0, testOpenBlock)\r
                try {\r
-                       const signature = await this.sign(0, testSendBlock, 'hex', testOpenBlock)\r
-                       return signature === testSignature\r
+                       await this.sign(0, testSendBlock, testOpenBlock)\r
+                       return testSendBlock.signature === testOpenBlock.signature\r
                } catch (err) {\r
                        throw new Error('Failed to verify wallet', { cause: err })\r
                }\r