From: Chris Duncan Date: Wed, 6 Aug 2025 04:21:57 +0000 (-0700) Subject: Refactor block signing method to include wallet option. X-Git-Tag: v0.10.5~43^2~76 X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=a294fa028cc5f4af0c18d9127242458878fcd2be;p=libnemo.git Refactor block signing method to include wallet option. --- diff --git a/src/lib/block.ts b/src/lib/block.ts index 5148f5a..0261a3b 100644 --- a/src/lib/block.ts +++ b/src/lib/block.ts @@ -8,6 +8,7 @@ import { BURN_ADDRESS, PREAMBLE, DIFFICULTY_RECEIVE, DIFFICULTY_SEND } from './c import { bytes, dec, hex } from './convert' import { NanoNaCl } from './nano-nacl' import { Rpc } from './rpc' +import { Wallet } from './wallet' /** * Represents a block as defined by the Nano cryptocurrency protocol. The Block @@ -292,7 +293,16 @@ abstract class Block { * * @param {string} [key] - Hexadecimal-formatted private key to use for signing */ - async sign (key?: string): Promise + async sign (key: string): Promise + /** + * Signs the block using a Wallet. If successful, the result is stored in + * the object's `signature` property. 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 /** * Signs the block using a Ledger hardware wallet. If that fails, an error is * thrown with the status code from the device. @@ -303,37 +313,47 @@ abstract class Block { * @param {number} index - Account index between 0x0 and 0x7fffffff * @param {object} [frontier] - JSON of frontier block for offline signing */ - async sign (index?: number, frontier?: ChangeBlock | ReceiveBlock | SendBlock): Promise - async sign (input?: number | string, frontier?: ChangeBlock | ReceiveBlock | SendBlock): Promise { - if (typeof input === 'number') { - const index = input - const { Ledger } = await import('./ledger') - const ledger = await Ledger.create() - await ledger.connect() - if (frontier) { - try { - await ledger.updateCache(index, frontier) - } catch (err) { - console.warn('Error updating Ledger cache of previous block, attempting signature anyway', err) - } - } - try { - this.signature = await ledger.sign(index, this as SendBlock | ReceiveBlock | ChangeBlock) - return this.signature - } catch (err) { - throw new Error('Failed to sign block with Ledger', { cause: err }) - } - } else if (typeof input === 'string') { - try { + async sign (index: number, frontier?: Block): Promise + async sign (input: unknown, param?: unknown): Promise { + try { + if (typeof input !== 'string' && typeof input !== 'number' && !(input instanceof Wallet)) { + throw new TypeError('Invalid input') + + } else if (typeof input === 'string') { const sig = await NanoNaCl.detached(hex.toBytes(this.hash), hex.toBytes(input)) this.signature = bytes.toHex(sig) - return this.signature - } catch (err) { - throw new Error(`Failed to sign block with private key`, { cause: err }) + return this + + } else if (input instanceof Wallet && typeof param === 'number') { + const sig = await input.sign(param, this as SendBlock | ReceiveBlock | ChangeBlock) + if (this.signature !== sig) { + throw new Error('Wallet signature does not match block signature') + } + return this + + } else if (typeof input === 'number') { + const index = input + const { Ledger } = await import('./ledger') + const ledger = await Ledger.create() + await ledger.connect() + if (param && (param instanceof ChangeBlock || param instanceof ReceiveBlock || param instanceof SendBlock)) { + try { + await ledger.updateCache(index, param) + } catch (err) { + console.warn('Error updating Ledger cache of previous block, attempting signature anyway', err) + } + } + this.signature = await ledger.sign(index, this as SendBlock | ReceiveBlock | ChangeBlock) + return this + + } else { + throw new TypeError('invalid key for block signature', { cause: typeof input }) } - } else { - throw new TypeError('invalid key for block signature', { cause: typeof input }) + } catch (err) { + console.error(err) + throw new Error('Failed to sign block', { cause: err }) } + } /**