diff --git a/app/scripts/banano-util.js b/app/scripts/banano-util.js index a5cfb70..6740e3b 100644 --- a/app/scripts/banano-util.js +++ b/app/scripts/banano-util.js @@ -15,7 +15,7 @@ const preamble = '0000000000000000000000000000000000000000000000000000000000000006'; - + const bananoMessagePreamble = 'bananomsg-'; @@ -506,19 +506,6 @@ return uint4; }; - const utf8ToBytes = (utf8) => { - const bytes = new Uint8Array(utf8.length); - for (let i = 0; i < utf8.length; i++) { - const code = utf8.charCodeAt(i); - /* istanbul ignore if */ - if (code > 0xff) { - throw Error('Non utf-8 character found'); - } - bytes[i] = code; - } - return bytes; - }; - const hashMessageToBytes = (message) => { const context = blake.blake2bInit(32, null); // bananoMessagePreamble is technically not needed for dummy blocks but helps separate Nano signing from Banano signing @@ -526,10 +513,10 @@ blake.blake2bUpdate(context, message); const bytes = blake.blake2bFinal(context); return bytes; - } + }; - const DUMMY_BYTES = hexToBytes("0000000000000000000000000000000000000000000000000000000000000000"); - const DUMMY_BALANCE = hexToBytes("00000000000000000000000000000000"); + const DUMMY_BYTES = hexToBytes('0000000000000000000000000000000000000000000000000000000000000000'); + const DUMMY_BALANCE = hexToBytes('00000000000000000000000000000000'); const messageDummyBlock = (publicKeyBytes, message) => { let publicKey; @@ -552,11 +539,11 @@ previous: dummyHex, representative: representative, balance: '0', - link: dummyHex - } + link: dummyHex, + }; return block; - } + }; const messageDummyBlockHashBytes = (publicKeyBytes, message) => { if (typeof(publicKeyBytes) === 'string') { @@ -573,15 +560,15 @@ blake.blake2bUpdate(context, DUMMY_BYTES); // link const hashBytes = blake.blake2bFinal(context); return hashBytes; - } + }; - const signMessage = async (privateKey, message) => { - const publicKey = await getPublicKey(privateKey); + const signMessage = async (privateKeyOrSigner, message) => { + const publicKey = await getPublicKey(privateKeyOrSigner); const publicKeyBytes = hexToBytes(publicKey); - const privateKeyBytes = hexToBytes(privateKey); - + const privateKeyBytes = hexToBytes(privateKeyOrSigner); if (typeof privateKeyOrSigner === 'object') { + const block = messageDummyBlock(publicKeyBytes, message); // type is signer const hwResponse = await privateKeyOrSigner.signBlock(block); return hwResponse.signature; @@ -659,21 +646,6 @@ return nacl.sign.keyPair.fromSecretKey(accountSecretKeyBytes); }; - /** - * returns true if the work (in bytes) for the hash (in bytes) is valid. - * - * @memberof BananoUtil - * @param {Uint8Array} bytes the bytes to hash. - * @param {{number}} size the digest size - * @return {Uint8Array} the bytes of the hash. - */ - const getBlake2bHash = (bytes, size) => { - const context = blake.blake2bInit(size); - blake.blake2bUpdate(context, bytes); - const output = blake.blake2bFinal(context); - return output; - }; - /** * returns true if the work (in bytes) for the hash (in bytes) is valid. * @@ -1483,7 +1455,6 @@ exports.getPrivateKey = getPrivateKey; exports.hash = hash; exports.sign = sign; - exports.utf8ToBytes = utf8ToBytes; exports.hashMessageToBytes = hashMessageToBytes; exports.messageDummyBlock = messageDummyBlock; exports.messageDummyBlockHashBytes = messageDummyBlockHashBytes; @@ -1508,7 +1479,6 @@ exports.isAccountSuffixValid = isAccountSuffixValid; exports.isAccountOpen = isAccountOpen; exports.isSeedValid = isSeedValid; - exports.getBlake2bHash = getBlake2bHash; return exports; })(); diff --git a/dist/bananocoin-bananojs.js b/dist/bananocoin-bananojs.js index 2ca5240..15f942c 100644 --- a/dist/bananocoin-bananojs.js +++ b/dist/bananocoin-bananojs.js @@ -1,5 +1,5 @@ //bananocoin-bananojs.js -//version 2.8.10 +//version 2.9.1 //license MIT /* eslint-disable */ const require = (modname) => { @@ -2804,6 +2804,9 @@ window.bananocoin.bananojs.https.request = ( const preamble = '0000000000000000000000000000000000000000000000000000000000000006'; + const bananoMessagePreamble = + 'bananomsg-'; + const prefixDivisors = { ban_: { minorDivisor: BigInt('1000000000000000000000000000'), @@ -3291,33 +3294,88 @@ window.bananocoin.bananojs.https.request = ( return uint4; }; - const utf8ToBytes = (utf8) => { - const bytes = new Uint8Array(utf8.length); - for (let i = 0; i < utf8.length; i++) { - const code = utf8.charCodeAt(i); - /* istanbul ignore if */ - if (code > 0xff) { - throw Error('Non utf-8 character found'); - } - bytes[i] = code; - } + const hashMessageToBytes = (message) => { + const context = blake.blake2bInit(32, null); + // bananoMessagePreamble is technically not needed for dummy blocks but helps separate Nano signing from Banano signing + blake.blake2bUpdate(context, bananoMessagePreamble); + blake.blake2bUpdate(context, message); + const bytes = blake.blake2bFinal(context); return bytes; }; - const signMessage = (privateKey, message) => { - const messageBytes = utf8ToBytes(message); - const privateKeyBytes = hexToBytes(privateKey); - const signed = nacl.sign.detached(messageBytes, privateKeyBytes); + const DUMMY_BYTES = hexToBytes('0000000000000000000000000000000000000000000000000000000000000000'); + const DUMMY_BALANCE = hexToBytes('00000000000000000000000000000000'); + + const messageDummyBlock = (publicKeyBytes, message) => { + let publicKey; + if (typeof(publicKeyBytes) === 'string') { + publicKey = publicKeyBytes; + publicKeyBytes = hexToBytes(publicKeyBytes); + } else { + publicKey = bytesToHex(publicKeyBytes); + } + + const accountAddress = getAccount(publicKey, 'ban_'); + const hashedMessageBytes = hashMessageToBytes(message); + const hashedMessageHex = bytesToHex(hashedMessageBytes); + const representative = getAccount(hashedMessageHex, 'ban_'); + const dummyHex = bytesToHex(DUMMY_BYTES); + + const block = { + type: 'state', + account: accountAddress, + previous: dummyHex, + representative: representative, + balance: '0', + link: dummyHex, + }; + + return block; + }; + + const messageDummyBlockHashBytes = (publicKeyBytes, message) => { + if (typeof(publicKeyBytes) === 'string') { + publicKeyBytes = hexToBytes(publicKeyBytes); + } + const hashedMessageBytes = hashMessageToBytes(message); + + const context = blake.blake2bInit(32, null); + blake.blake2bUpdate(context, hexToBytes(preamble)); + blake.blake2bUpdate(context, publicKeyBytes); + blake.blake2bUpdate(context, DUMMY_BYTES); // previous + blake.blake2bUpdate(context, hashedMessageBytes); // representative + blake.blake2bUpdate(context, DUMMY_BALANCE); + blake.blake2bUpdate(context, DUMMY_BYTES); // link + const hashBytes = blake.blake2bFinal(context); + return hashBytes; + }; + + const signMessage = async (privateKeyOrSigner, message) => { + const publicKey = await getPublicKey(privateKeyOrSigner); + const publicKeyBytes = hexToBytes(publicKey); + const privateKeyBytes = hexToBytes(privateKeyOrSigner); + + if (typeof privateKeyOrSigner === 'object') { + const block = messageDummyBlock(publicKeyBytes, message); + // type is signer + const hwResponse = await privateKeyOrSigner.signBlock(block); + return hwResponse.signature; + } + + const dummyBlockHashBytes = messageDummyBlockHashBytes(publicKeyBytes, message); + const signed = nacl.sign.detached(dummyBlockHashBytes, privateKeyBytes); const signature = bytesToHex(signed); return signature; }; const verifyMessage = (publicKey, message, signature) => { - const messageBytes = utf8ToBytes(message); const publicKeyBytes = hexToBytes(publicKey); const signatureBytes = hexToBytes(signature); - const verifies = nacl.sign.detached.verify(messageBytes, signatureBytes, publicKeyBytes); - return verifies; + + const dummyBlockHashBytes = messageDummyBlockHashBytes(publicKeyBytes, message); + const verified = nacl.sign.detached.verify(dummyBlockHashBytes, signatureBytes, publicKeyBytes); + + return verified; }; const signHash = (privateKey, hash) => { @@ -3376,21 +3434,6 @@ window.bananocoin.bananojs.https.request = ( return nacl.sign.keyPair.fromSecretKey(accountSecretKeyBytes); }; - /** - * returns true if the work (in bytes) for the hash (in bytes) is valid. - * - * @memberof BananoUtil - * @param {Uint8Array} bytes the bytes to hash. - * @param {{number}} size the digest size - * @return {Uint8Array} the bytes of the hash. - */ - const getBlake2bHash = (bytes, size) => { - const context = blake.blake2bInit(size); - blake.blake2bUpdate(context, bytes); - const output = blake.blake2bFinal(context); - return output; - }; - /** * returns true if the work (in bytes) for the hash (in bytes) is valid. * @@ -4200,7 +4243,9 @@ window.bananocoin.bananojs.https.request = ( exports.getPrivateKey = getPrivateKey; exports.hash = hash; exports.sign = sign; - exports.utf8ToBytes = utf8ToBytes; + exports.hashMessageToBytes = hashMessageToBytes; + exports.messageDummyBlock = messageDummyBlock; + exports.messageDummyBlockHashBytes = messageDummyBlockHashBytes; exports.signMessage = signMessage; exports.verifyMessage = verifyMessage; exports.signHash = signHash; @@ -4222,7 +4267,6 @@ window.bananocoin.bananojs.https.request = ( exports.isAccountSuffixValid = isAccountSuffixValid; exports.isAccountOpen = isAccountOpen; exports.isSeedValid = isSeedValid; - exports.getBlake2bHash = getBlake2bHash; return exports; })(); @@ -6284,12 +6328,47 @@ window.bananocoin.bananojs.https.request = ( * signs a utf-8 message with private key. * * @memberof BananoUtil + * @param {string} privateKeyOrSigner the private key to use to sign. + * @param {string} message the utf-8 message to sign. + * @return {string} the message's hash. + */ + const signMessage = (privateKeyOrSigner, message) => { + return bananoUtil.signMessage(privateKeyOrSigner, message); + }; + + /** + * signs a utf-8 message with private key. Only used internally and for testing. + * + * @memberof BananoUtil + * @param {string} message the utf-8 message to sign. + * @return {string} the message's hash. + */ + const hashMessageToBytes = (message) => { + return bananoUtil.hashMessageToBytes(message); + }; + + /** + * generates a dummy block hash that is used for message signing. + * + * @memberof BananoUtil * @param {string} privateKey the private key to use to sign. * @param {string} message the utf-8 message to sign. * @return {string} the message's hash. */ - const signMessage = (privateKey, message) => { - return bananoUtil.signMessage(privateKey, message); + const messageDummyBlockHashBytes = (privateKey, message) => { + return bananoUtil.messageDummyBlockHashBytes(privateKey, message); + }; + + /** + * generates a dummy block that is used for message signing. + * + * @memberof BananoUtil + * @param {string} privateKey the private key to use to sign. + * @param {string} message the utf-8 message to sign. + * @return {string} the message's block. + */ + const messageDummyBlock = (privateKey, message) => { + return bananoUtil.messageDummyBlock(privateKey, message); }; /** @@ -7011,6 +7090,9 @@ window.bananocoin.bananojs.https.request = ( changeBananoRepresentativeForSeed; exports.changeNanoRepresentativeForSeed = changeNanoRepresentativeForSeed; exports.getSignature = getSignature; + exports.hashMessageToBytes = hashMessageToBytes; + exports.messageDummyBlockHashBytes = messageDummyBlockHashBytes; + exports.messageDummyBlock = messageDummyBlock; exports.signMessage = signMessage; exports.verifyMessage = verifyMessage; exports.signHash = signHash; diff --git a/docs/documentation.md b/docs/documentation.md index f24156c..34531df 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -504,7 +504,10 @@ checks if a camo account is valid. * [.openBananoAccountFromSeed(seed, seedIx, representative, pendingBlockHash, pendingValueRaw)](#BananoUtil.openBananoAccountFromSeed) ⇒ Promise.<string> * [.openNanoAccountFromSeed(seed, seedIx, representative, pendingBlockHash, pendingValueRaw)](#BananoUtil.openNanoAccountFromSeed) ⇒ Promise.<string> * [.getBlockHash(block)](#BananoUtil.getBlockHash) ⇒ string - * [.signMessage(privateKey, message)](#BananoUtil.signMessage) ⇒ string + * [.signMessage(privateKeyOrSigner, message)](#BananoUtil.signMessage) ⇒ string + * [.hashMessageToBytes(message)](#BananoUtil.hashMessageToBytes) ⇒ string + * [.messageDummyBlockHashBytes(privateKey, message)](#BananoUtil.messageDummyBlockHashBytes) ⇒ string + * [.messageDummyBlock(privateKey, message)](#BananoUtil.messageDummyBlock) ⇒ string * [.verifyMessage(publicKey, message, signature)](#BananoUtil.verifyMessage) ⇒ string * [.signHash(privateKey, hash)](#BananoUtil.signHash) ⇒ string * [.verify(hash, signature, publicKey)](#BananoUtil.verify) ⇒ string @@ -523,7 +526,6 @@ checks if a camo account is valid. * [.getAccountSuffix(publicKey)](#BananoUtil.getAccountSuffix) ⇒ string * [.getAccount(publicKey, accountPrefix)](#BananoUtil.getAccount) ⇒ string * [.sign(privateKeyOrSigner, block)](#BananoUtil.sign) ⇒ string - * [.getBlake2bHash(bytes, size)](#BananoUtil.getBlake2bHash) ⇒ Uint8Array * [.isWorkValid(hashBytes, workBytes)](#BananoUtil.isWorkValid) ⇒ boolean * [.getZeroedWorkBytes()](#BananoUtil.getZeroedWorkBytes) ⇒ Uint8Array * [.getPublicKey(privateKeyOrSigner)](#BananoUtil.getPublicKey) ⇒ Promise.<string> @@ -758,12 +760,50 @@ Get the hash for a given block. -### BananoUtil.signMessage(privateKey, message) ⇒ string +### BananoUtil.signMessage(privateKeyOrSigner, message) ⇒ string signs a utf-8 message with private key. **Kind**: static method of [BananoUtil](#BananoUtil) **Returns**: string - the message's hash. +| Param | Type | Description | +| --- | --- | --- | +| privateKeyOrSigner | string | the private key to use to sign. | +| message | string | the utf-8 message to sign. | + + + +### BananoUtil.hashMessageToBytes(message) ⇒ string +signs a utf-8 message with private key. Only used internally and for testing. + +**Kind**: static method of [BananoUtil](#BananoUtil) +**Returns**: string - the message's hash. + +| Param | Type | Description | +| --- | --- | --- | +| message | string | the utf-8 message to sign. | + + + +### BananoUtil.messageDummyBlockHashBytes(privateKey, message) ⇒ string +generates a dummy block hash that is used for message signing. + +**Kind**: static method of [BananoUtil](#BananoUtil) +**Returns**: string - the message's hash. + +| Param | Type | Description | +| --- | --- | --- | +| privateKey | string | the private key to use to sign. | +| message | string | the utf-8 message to sign. | + + + +### BananoUtil.messageDummyBlock(privateKey, message) ⇒ string +generates a dummy block that is used for message signing. + +**Kind**: static method of [BananoUtil](#BananoUtil) +**Returns**: string - the message's block. + | Param | Type | Description | | --- | --- | --- | | privateKey | string | the private key to use to sign. | @@ -997,19 +1037,6 @@ signs a block and returns the signature. | privateKeyOrSigner | string | the private key to use to sign or signer object (ledger). | | block | [Block](#Block) | block to sign | - - -### BananoUtil.getBlake2bHash(bytes, size) ⇒ Uint8Array -returns true if the work (in bytes) for the hash (in bytes) is valid. - -**Kind**: static method of [BananoUtil](#BananoUtil) -**Returns**: Uint8Array - the bytes of the hash. - -| Param | Type | Description | -| --- | --- | --- | -| bytes | Uint8Array | the bytes to hash. | -| size | Object | the digest size | - ### BananoUtil.isWorkValid(hashBytes, workBytes) ⇒ boolean diff --git a/index.d.ts b/index.d.ts index a85c733..4a88e9d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -374,11 +374,31 @@ declare namespace BananoUtil { function getBlockHash(block: string): string; /** * signs a utf-8 message with private key. + * @param privateKeyOrSigner - the private key to use to sign. + * @param message - the utf-8 message to sign. + * @returns the message's hash. + */ + function signMessage(privateKeyOrSigner: string, message: string): string; + /** + * signs a utf-8 message with private key. Only used internally and for testing. + * @param message - the utf-8 message to sign. + * @returns the message's hash. + */ + function hashMessageToBytes(message: string): string; + /** + * generates a dummy block hash that is used for message signing. * @param privateKey - the private key to use to sign. * @param message - the utf-8 message to sign. * @returns the message's hash. */ - function signMessage(privateKey: string, message: string): string; + function messageDummyBlockHashBytes(privateKey: string, message: string): string; + /** + * generates a dummy block that is used for message signing. + * @param privateKey - the private key to use to sign. + * @param message - the utf-8 message to sign. + * @returns the message's block. + */ + function messageDummyBlock(privateKey: string, message: string): string; /** * verifies a utf-8 message with public key. * @param publicKey - the public key to use to sign. @@ -499,13 +519,6 @@ declare namespace BananoUtil { * @returns the signature */ function sign(privateKeyOrSigner: string, block: Block): string; - /** - * returns true if the work (in bytes) for the hash (in bytes) is valid. - * @param bytes - the bytes to hash. - * @param size - the digest size - * @returns the bytes of the hash. - */ - function getBlake2bHash(bytes: Uint8Array, size: any): Uint8Array; /** * returns true if the work (in bytes) for the hash (in bytes) is valid. * @param hashBytes - the hash bytes to check. @@ -715,3 +728,14 @@ declare type AccountValidationInfo = { }; +export { + Block, + Main, + CamoUtil, + BananoUtil, + WithdrawUtil, + DepositUtil, + BananodeApi, + BananoParts, + AccountValidationInfo, +} diff --git a/index.js b/index.js index 258bb94..73286a1 100644 --- a/index.js +++ b/index.js @@ -727,7 +727,7 @@ * signs a utf-8 message with private key. * * @memberof BananoUtil - * @param {string} privateKey the private key to use to sign. + * @param {string} privateKeyOrSigner the private key to use to sign. * @param {string} message the utf-8 message to sign. * @return {string} the message's hash. */ @@ -758,6 +758,18 @@ return bananoUtil.messageDummyBlockHashBytes(privateKey, message); }; + /** + * generates a dummy block that is used for message signing. + * + * @memberof BananoUtil + * @param {string} privateKey the private key to use to sign. + * @param {string} message the utf-8 message to sign. + * @return {string} the message's block. + */ + const messageDummyBlock = (privateKey, message) => { + return bananoUtil.messageDummyBlock(privateKey, message); + }; + /** * verifies a utf-8 message with public key. * @@ -1479,6 +1491,7 @@ exports.getSignature = getSignature; exports.hashMessageToBytes = hashMessageToBytes; exports.messageDummyBlockHashBytes = messageDummyBlockHashBytes; + exports.messageDummyBlock = messageDummyBlock; exports.signMessage = signMessage; exports.verifyMessage = verifyMessage; exports.signHash = signHash; diff --git a/package-lock.json b/package-lock.json index 79ce0d3..9769c1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bananocoin/bananojs", - "version": "2.8.10", + "version": "2.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bananocoin/bananojs", - "version": "2.8.10", + "version": "2.9.1", "license": "MIT", "dependencies": { "package": "^1.0.1" @@ -21,7 +21,7 @@ "jsdoc": "^4.0.2", "jsdoc-to-markdown": "^8.0.0", "mocha": "^10.2.0", - "npm-check-updates": "^16.10.15", + "npm-check-updates": "^16.10.16", "nyc": "^15.1.0", "prettier": "^3.0.0", "tsd-jsdoc": "^2.5.0" @@ -1030,9 +1030,9 @@ } }, "node_modules/@sindresorhus/is": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.5.0.tgz", - "integrity": "sha512-3rO1QIz6mL0MvFVTOxqhDJRVsLfG/vK2VSlKKPghALA6FhJqU7L+RUHnFvH5BP5HhkWiMQqq514i9ZFTcqoGCQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.5.2.tgz", + "integrity": "sha512-8ZMK+V6YpeZFfW6hU9uAeWVuq8v3t7BaG276gIO+kVqnAcLrHCXdFUOf7kgouyfAarkZtuavIqY3RsXTsTWviw==", "dev": true, "engines": { "node": ">=14.16" @@ -2438,9 +2438,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.461", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz", - "integrity": "sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ==", + "version": "1.4.464", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.464.tgz", + "integrity": "sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==", "dev": true }, "node_modules/elliptic": { @@ -4051,9 +4051,9 @@ ] }, "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", "dev": true, "dependencies": { "json-buffer": "3.0.1" @@ -4837,9 +4837,9 @@ } }, "node_modules/npm-check-updates": { - "version": "16.10.15", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-16.10.15.tgz", - "integrity": "sha512-tmbFF7J1mIbjmnN4DzFRVlEeAaIB/FPRz4o95DWsGB7fT3ZECuxyMMDnvySfoijuWxx8E7pODN0IoKYnEJVxcg==", + "version": "16.10.16", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-16.10.16.tgz", + "integrity": "sha512-d8mNYce/l8o5RHPE5ZUp2P1zj9poI7KWQCh5AsTIP3EhicONEhc63mLQQv4/nkCsMb3wCrikx6YOo4BOwN4+1w==", "dev": true, "dependencies": { "chalk": "^5.3.0", diff --git a/package.json b/package.json index ec65b9c..e02f4d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bananocoin/bananojs", - "version": "2.8.10", + "version": "2.9.1", "module": "index.js", "repository": { "type": "git", @@ -42,7 +42,7 @@ "jsdoc": "^4.0.2", "jsdoc-to-markdown": "^8.0.0", "mocha": "^10.2.0", - "npm-check-updates": "^16.10.15", + "npm-check-updates": "^16.10.16", "nyc": "^15.1.0", "prettier": "^3.0.0", "tsd-jsdoc": "^2.5.0" diff --git a/test/unit/corner-case-test.js b/test/unit/corner-case-test.js index ae1768d..ad7685a 100644 --- a/test/unit/corner-case-test.js +++ b/test/unit/corner-case-test.js @@ -291,6 +291,28 @@ describe('corner-cases', () => { } }); + it('signMessage from hardware wallet', async () => { + const bananojs = testUtil.getBananojsWithMockApi(); + const destAccount = + 'ban_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7'; + const expected = + 'EA94473875A88E3777C7FF4251410F09B82AACECE02901D78FDAE4BC571AF77D'; + const accountSigner = {}; + accountSigner.getPublicKey = async () => { + return await bananojs.getPublicKey(destAccount); + }; + accountSigner.signBlock = async (block) => { + block.signature = expected; + return block; + }; + try { + const actual = await bananojs.signMessage(accountSigner, 'test'); + expect(expected).to.deep.equal(actual); + } catch (e) { + console.trace(e); + } + }); + beforeEach(async () => {}); afterEach(async () => { diff --git a/test/unit/message-signing-test.js b/test/unit/message-signing-test.js index b12e50c..1bdbd65 100644 --- a/test/unit/message-signing-test.js +++ b/test/unit/message-signing-test.js @@ -38,26 +38,28 @@ describe('message-sign', () => { expect(signatureVerify).to.deep.equal(false); }); + it('generates expected dummy block hash from public key bytes', async () => { + const bananojs = testUtil.getBananojsWithMockApi(); + const publicKey = await bananojs.getPublicKey(privateKey); + const publicKeyBytes = bananojs.BananoUtil.hexToBytes(publicKey); + const block = bananojs.messageDummyBlock(publicKeyBytes, 'test'); + const account = bananojs.getAccount(publicKey, 'ban_'); + expect(account).to.equal(block.account); + }); + it('generates expected dummy block hash', async () => { const bananojs = testUtil.getBananojsWithMockApi(); const publicKey = await bananojs.getPublicKey(privateKey); const hashedMessageBytes = bananojs.hashMessageToBytes('test'); const dummyBlockHashBytes = bananojs.messageDummyBlockHashBytes(publicKey, 'test'); - const hashedMessage = bananojs.getHexFromBytes(hashedMessageBytes); const dummyBlockHash = bananojs.getHexFromBytes(dummyBlockHashBytes); - - const address = bananojs.getAccount(publicKey, 'ban_'); - const representative = bananojs.getAccount(hashedMessage, 'ban_'); - const block = { - type: 'state', - account: address, - previous: '0000000000000000000000000000000000000000000000000000000000000000', - balance: '0', - representative: representative, - link: '0000000000000000000000000000000000000000000000000000000000000000' - } + const block = bananojs.messageDummyBlock(publicKey, 'test'); + + const hashedMessage = bananojs.getHexFromBytes(hashedMessageBytes); + const representative = bananojs.getAccount(hashedMessage, 'ban_'); + expect(representative).to.equal(block.representative); const manualDummyBlockHash = bananojs.getBlockHash(block); expect(dummyBlockHash).to.equal(manualDummyBlockHash);