Version 1.1.0
* Separate block signer to it's own class * Add JSDOC to some functions * Renamed converter to tools * Added the ability to sign any strings with the private key
This commit is contained in:
parent
ba06a44cf4
commit
c3648758bc
13 changed files with 1091 additions and 941 deletions
20
README.md
20
README.md
|
|
@ -165,19 +165,31 @@ const signedBlock = block.representative(data, privateKey)
|
||||||
Supported unit values are RAW, NANO, MRAI, KRAI, RAW.
|
Supported unit values are RAW, NANO, MRAI, KRAI, RAW.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import { converter } from 'nanocurrency-web'
|
import { tools } from 'nanocurrency-web'
|
||||||
|
|
||||||
// Convert 1 Nano to RAW
|
// Convert 1 Nano to RAW
|
||||||
const converted = converter.convert('1', 'NANO', 'RAW')
|
const converted = tools.convert('1', 'NANO', 'RAW')
|
||||||
|
|
||||||
// Convert 1 RAW to Nano
|
// Convert 1 RAW to Nano
|
||||||
const converted = converter.convert('1000000000000000000000000000000', 'RAW', 'NANO')
|
const converted = tools.convert('1000000000000000000000000000000', 'RAW', 'NANO')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Signing any data with the private key
|
||||||
|
|
||||||
|
For example implementing client side login with the password being the user's e-mail signed with their private key
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { tools } from 'nanocurrency-web'
|
||||||
|
|
||||||
|
const privateKey = '781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3';
|
||||||
|
const signed = tools.sign(privateKey, 'foo@bar.com')
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### In web
|
### In web
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://unpkg.com/nanocurrency-web@1.0.6" type="text/javascript"></script>
|
<script src="https://unpkg.com/nanocurrency-web@1.1.0" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
NanocurrencyWeb.wallet.generate(...);
|
NanocurrencyWeb.wallet.generate(...);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
20
index.ts
20
index.ts
|
|
@ -3,9 +3,12 @@ import AddressImporter, { Account, Wallet } from './lib/address-importer'
|
||||||
import BlockSigner, { SendBlock, ReceiveBlock, RepresentativeBlock, SignedBlock } from './lib/block-signer'
|
import BlockSigner, { SendBlock, ReceiveBlock, RepresentativeBlock, SignedBlock } from './lib/block-signer'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import NanoConverter from './lib/nano-converter'
|
import NanoConverter from './lib/nano-converter'
|
||||||
|
import Signer from './lib/signer'
|
||||||
|
import Convert from './lib/util/convert'
|
||||||
|
|
||||||
const generator = new AddressGenerator()
|
const generator = new AddressGenerator()
|
||||||
const importer = new AddressImporter()
|
const importer = new AddressImporter()
|
||||||
|
const signer = new Signer();
|
||||||
const wallet = {
|
const wallet = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -162,7 +165,7 @@ const block = {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const converter = {
|
const tools = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert Nano values
|
* Convert Nano values
|
||||||
|
|
@ -173,14 +176,25 @@ const converter = {
|
||||||
* @param {string} inputUnit The unit of the input value
|
* @param {string} inputUnit The unit of the input value
|
||||||
* @param {string} outputUnit The unit you wish to convert to
|
* @param {string} outputUnit The unit you wish to convert to
|
||||||
*/
|
*/
|
||||||
convert: (input: string | BigNumber, inputUnit: string, outputUnit: string) => {
|
convert: (input: string | BigNumber, inputUnit: string, outputUnit: string): string => {
|
||||||
return NanoConverter.convert(input, inputUnit, outputUnit)
|
return NanoConverter.convert(input, inputUnit, outputUnit)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign any strings with the user's private key
|
||||||
|
*
|
||||||
|
* @param {string} privateKey The private key to sign with
|
||||||
|
* @param {...string} input Data to sign
|
||||||
|
*/
|
||||||
|
sign: (privateKey: string, ...input: string[]): string => {
|
||||||
|
const data = input.map(Convert.stringToHex)
|
||||||
|
return signer.sign(privateKey, ...data);
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
wallet,
|
wallet,
|
||||||
block,
|
block,
|
||||||
converter,
|
tools,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ export default class AddressGenerator {
|
||||||
/**
|
/**
|
||||||
* Generates the wallet
|
* Generates the wallet
|
||||||
*
|
*
|
||||||
* @param {String} seedPassword Password for the seed
|
* @param {string} [entropy] - (Optional) Custom entropy if the caller doesn't want a default generated entropy
|
||||||
|
* @param {string} [seedPassword] - (Optional) Password for the seed
|
||||||
*/
|
*/
|
||||||
generateWallet(entropy = '', seedPassword: string = ''): Wallet {
|
generateWallet(entropy = '', seedPassword: string = ''): Wallet {
|
||||||
const bip39 = new Bip39Mnemonic(seedPassword)
|
const bip39 = new Bip39Mnemonic(seedPassword)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,13 @@ import NanoAddress from './nano-address'
|
||||||
|
|
||||||
export default class AddressImporter {
|
export default class AddressImporter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a wallet using a mnemonic phrase
|
||||||
|
*
|
||||||
|
* @param {string} mnemonic - The mnemonic words to import the wallet from
|
||||||
|
* @param {string} [seedPassword] - (Optional) The password to use to secure the mnemonic
|
||||||
|
* @returns {Wallet} - The wallet derived from the mnemonic phrase
|
||||||
|
*/
|
||||||
fromMnemonic(mnemonic: string, seedPassword = ''): Wallet {
|
fromMnemonic(mnemonic: string, seedPassword = ''): Wallet {
|
||||||
const bip39 = new Bip39Mnemonic(seedPassword)
|
const bip39 = new Bip39Mnemonic(seedPassword)
|
||||||
if (!bip39.validateMnemonic(mnemonic)) {
|
if (!bip39.validateMnemonic(mnemonic)) {
|
||||||
|
|
@ -15,6 +22,14 @@ export default class AddressImporter {
|
||||||
return this.nano(seed, 0, 0, mnemonic)
|
return this.nano(seed, 0, 0, mnemonic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a wallet using a seed
|
||||||
|
*
|
||||||
|
* @param {string} seed - The seed to import the wallet from
|
||||||
|
* @param {number} [from] - (Optional) The start index of the private keys to derive from
|
||||||
|
* @param {number} [to] - (Optional) The end index of the private keys to derive to
|
||||||
|
* @returns {Wallet} The wallet derived from the mnemonic phrase
|
||||||
|
*/
|
||||||
fromSeed(seed: string, from = 0, to = 0): Wallet {
|
fromSeed(seed: string, from = 0, to = 0): Wallet {
|
||||||
if (seed.length !== 128) {
|
if (seed.length !== 128) {
|
||||||
throw new Error('Invalid seed length, must be a 128 byte hexadecimal string')
|
throw new Error('Invalid seed length, must be a 128 byte hexadecimal string')
|
||||||
|
|
@ -27,8 +42,12 @@ export default class AddressImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the wallet
|
* Derives the private keys
|
||||||
* @param {String} seedPassword Password for the seed
|
*
|
||||||
|
* @param {string} seed - The seed to use for private key derivation
|
||||||
|
* @param {number} from - The start index of private keys to derive from
|
||||||
|
* @param {number} to - The end index of private keys to derive to
|
||||||
|
* @param {string} [mnemonic] - (Optional) the mnemonic phrase to return with the wallet
|
||||||
*/
|
*/
|
||||||
private nano(seed: string, from: number, to: number, mnemonic?: string): Wallet {
|
private nano(seed: string, from: number, to: number, mnemonic?: string): Wallet {
|
||||||
const accounts = []
|
const accounts = []
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,13 @@ export default class Bip39Mnemonic {
|
||||||
this.password = password
|
this.password = password
|
||||||
}
|
}
|
||||||
|
|
||||||
createWallet = (entropy: string): { mnemonic: string, seed: string } => {
|
/**
|
||||||
|
* Creates a new wallet
|
||||||
|
*
|
||||||
|
* @param {string} [entropy] - (Optional) the entropy to use instead of generating
|
||||||
|
* @returns {MnemonicSeed} The mnemonic phrase and a seed derived from the (generated) entropy
|
||||||
|
*/
|
||||||
|
createWallet = (entropy: string): MnemonicSeed => {
|
||||||
if (entropy) {
|
if (entropy) {
|
||||||
if (entropy.length !== 64) {
|
if (entropy.length !== 64) {
|
||||||
throw new Error('Invalid entropy length, must be a 64 byte hexadecimal string')
|
throw new Error('Invalid entropy length, must be a 64 byte hexadecimal string')
|
||||||
|
|
@ -45,6 +51,12 @@ export default class Bip39Mnemonic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a mnemonic phrase
|
||||||
|
*
|
||||||
|
* @param {string} mnemonic - The mnemonic phrase to validate
|
||||||
|
* @returns {boolean} Is the mnemonic phrase valid
|
||||||
|
*/
|
||||||
validateMnemonic = (mnemonic: string): boolean => {
|
validateMnemonic = (mnemonic: string): boolean => {
|
||||||
const wordArray = Util.normalizeUTF8(mnemonic).split(' ')
|
const wordArray = Util.normalizeUTF8(mnemonic).split(' ')
|
||||||
if (wordArray.length % 3 !== 0) {
|
if (wordArray.length % 3 !== 0) {
|
||||||
|
|
@ -104,3 +116,8 @@ export default class Bip39Mnemonic {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MnemonicSeed {
|
||||||
|
mnemonic: string,
|
||||||
|
seed: string,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,28 @@
|
||||||
import BigNumber from 'bignumber.js'
|
|
||||||
import Ed25519 from './ed25519'
|
import Ed25519 from './ed25519'
|
||||||
import Convert from './util/convert'
|
import Convert from './util/convert'
|
||||||
import NanoAddress from './nano-address'
|
import NanoAddress from './nano-address'
|
||||||
import NanoConverter from './nano-converter'
|
import NanoConverter from './nano-converter'
|
||||||
|
import Signer from './signer'
|
||||||
|
|
||||||
|
import BigNumber from 'bignumber.js'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { blake2b, blake2bInit, blake2bUpdate, blake2bFinal } from 'blakejs'
|
import { blake2b } from 'blakejs'
|
||||||
|
|
||||||
export default class BlockSigner {
|
export default class BlockSigner {
|
||||||
|
|
||||||
nanoAddress = new NanoAddress()
|
nanoAddress = new NanoAddress()
|
||||||
ed25519 = new Ed25519()
|
ed25519 = new Ed25519()
|
||||||
|
signer = new Signer()
|
||||||
|
|
||||||
preamble = 0x6.toString().padStart(64, '0')
|
preamble: string = 0x6.toString().padStart(64, '0')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a receive block
|
||||||
|
*
|
||||||
|
* @param {ReceiveBlock} data The data required to sign a receive block
|
||||||
|
* @param {string} privateKey Private key to sign the data with
|
||||||
|
* @returns {SignedBlock} the signed block to publish to the blockchain
|
||||||
|
*/
|
||||||
receive(data: ReceiveBlock, privateKey: string): SignedBlock {
|
receive(data: ReceiveBlock, privateKey: string): SignedBlock {
|
||||||
const validateInputRaw = (input: string) => !!input && !isNaN(+input)
|
const validateInputRaw = (input: string) => !!input && !isNaN(+input)
|
||||||
if (!validateInputRaw(data.walletBalanceRaw)) {
|
if (!validateInputRaw(data.walletBalanceRaw)) {
|
||||||
|
|
@ -57,9 +66,14 @@ export default class BlockSigner {
|
||||||
const link = data.transactionHash
|
const link = data.transactionHash
|
||||||
const representative = this.nanoAddressToHexString(data.representativeAddress)
|
const representative = this.nanoAddressToHexString(data.representativeAddress)
|
||||||
|
|
||||||
const signatureBytes = this.ed25519.sign(
|
const signature = this.signer.sign(
|
||||||
this.generateHash(this.preamble, account, data.frontier, representative, newBalanceHex, link),
|
privateKey,
|
||||||
Convert.hex2ab(privateKey))
|
this.preamble,
|
||||||
|
account,
|
||||||
|
data.frontier,
|
||||||
|
representative,
|
||||||
|
newBalanceHex,
|
||||||
|
link)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'state',
|
type: 'state',
|
||||||
|
|
@ -68,11 +82,18 @@ export default class BlockSigner {
|
||||||
representative: data.representativeAddress,
|
representative: data.representativeAddress,
|
||||||
balance: newBalanceRaw,
|
balance: newBalanceRaw,
|
||||||
link: link,
|
link: link,
|
||||||
signature: Convert.ab2hex(signatureBytes),
|
signature: signature,
|
||||||
work: data.work,
|
work: data.work,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a send block
|
||||||
|
*
|
||||||
|
* @param {SendBlock} data The data required to sign a send block
|
||||||
|
* @param {string} privateKey Private key to sign the data with
|
||||||
|
* @returns {SignedBlock} the signed block to publish to the blockchain
|
||||||
|
*/
|
||||||
send(data: SendBlock, privateKey: string): SignedBlock {
|
send(data: SendBlock, privateKey: string): SignedBlock {
|
||||||
const validateInputRaw = (input: string) => !!input && !isNaN(+input)
|
const validateInputRaw = (input: string) => !!input && !isNaN(+input)
|
||||||
if (!validateInputRaw(data.walletBalanceRaw)) {
|
if (!validateInputRaw(data.walletBalanceRaw)) {
|
||||||
|
|
@ -96,11 +117,11 @@ export default class BlockSigner {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.frontier) {
|
if (!data.frontier) {
|
||||||
throw new Error('No frontier')
|
throw new Error('Frontier is not set')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.work) {
|
if (!data.work) {
|
||||||
throw new Error('No work')
|
throw new Error('Work is not set')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!privateKey) {
|
if (!privateKey) {
|
||||||
|
|
@ -116,9 +137,14 @@ export default class BlockSigner {
|
||||||
const link = this.nanoAddressToHexString(data.toAddress)
|
const link = this.nanoAddressToHexString(data.toAddress)
|
||||||
const representative = this.nanoAddressToHexString(data.representativeAddress)
|
const representative = this.nanoAddressToHexString(data.representativeAddress)
|
||||||
|
|
||||||
const signatureBytes = this.ed25519.sign(
|
const signature = this.signer.sign(
|
||||||
this.generateHash(this.preamble, account, data.frontier, representative, newBalanceHex, link),
|
privateKey,
|
||||||
Convert.hex2ab(privateKey))
|
this.preamble,
|
||||||
|
account,
|
||||||
|
data.frontier,
|
||||||
|
representative,
|
||||||
|
newBalanceHex,
|
||||||
|
link)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'state',
|
type: 'state',
|
||||||
|
|
@ -127,22 +153,11 @@ export default class BlockSigner {
|
||||||
representative: data.representativeAddress,
|
representative: data.representativeAddress,
|
||||||
balance: newBalanceRaw,
|
balance: newBalanceRaw,
|
||||||
link: link,
|
link: link,
|
||||||
signature: Convert.ab2hex(signatureBytes),
|
signature: signature,
|
||||||
work: data.work,
|
work: data.work,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateHash(preamble: string, account: string, previous: string, representative: string, balance: string, link: string) {
|
|
||||||
const ctx = blake2bInit(32, undefined)
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(preamble))
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(account))
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(previous))
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(representative))
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(balance))
|
|
||||||
blake2bUpdate(ctx, Convert.hex2ab(link))
|
|
||||||
return blake2bFinal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
private nanoAddressToHexString(addr: string): string {
|
private nanoAddressToHexString(addr: string): string {
|
||||||
addr = addr.slice(-60)
|
addr = addr.slice(-60)
|
||||||
const isValid = /^[13456789abcdefghijkmnopqrstuwxyz]+$/.test(addr)
|
const isValid = /^[13456789abcdefghijkmnopqrstuwxyz]+$/.test(addr)
|
||||||
|
|
@ -154,9 +169,9 @@ export default class BlockSigner {
|
||||||
const key = Convert.ab2hex(keyBytes).toUpperCase()
|
const key = Convert.ab2hex(keyBytes).toUpperCase()
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
throw new Error('Checksum mismatch')
|
throw new Error('Checksum mismatch in address')
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Illegal characters')
|
throw new Error('Illegal characters in address')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
35
lib/signer.ts
Normal file
35
lib/signer.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import Convert from './util/convert'
|
||||||
|
import Ed25519 from './ed25519'
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
import { blake2bInit, blake2bUpdate, blake2bFinal } from 'blakejs'
|
||||||
|
|
||||||
|
export default class Signer {
|
||||||
|
|
||||||
|
ed25519 = new Ed25519()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs any data using the ed25519 signature system
|
||||||
|
*
|
||||||
|
* @param privateKey Private key to sign the data with
|
||||||
|
* @param data Data to sign
|
||||||
|
*/
|
||||||
|
sign(privateKey: string, ...data: string[]): string {
|
||||||
|
const signature = this.ed25519.sign(
|
||||||
|
this.generateHash(data),
|
||||||
|
Convert.hex2ab(privateKey))
|
||||||
|
return Convert.ab2hex(signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a blake2b hash of the input data
|
||||||
|
*
|
||||||
|
* @param data Data to hash
|
||||||
|
*/
|
||||||
|
private generateHash(data: string[]): Uint8Array {
|
||||||
|
const ctx = blake2bInit(32, undefined)
|
||||||
|
data.forEach(str => blake2bUpdate(ctx, Convert.hex2ab(str)))
|
||||||
|
return blake2bFinal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -105,4 +105,8 @@ export default class Convert {
|
||||||
return parseInt(bin, 2).toString(16)
|
return parseInt(bin, 2).toString(16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static stringToHex = (str: string): string => {
|
||||||
|
return [...str].map(c => c.charCodeAt(0).toString(16)).join('')
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1813
package-lock.json
generated
1813
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "nanocurrency-web",
|
"name": "nanocurrency-web",
|
||||||
"version": "1.0.6",
|
"version": "1.1.0",
|
||||||
"description": "Toolkit for Nano cryptocurrency client side offline integrations",
|
"description": "Toolkit for Nano cryptocurrency client side offline integrations",
|
||||||
"author": "Miro Metsänheimo <miro@metsanheimo.fi>",
|
"author": "Miro Metsänheimo <miro@metsanheimo.fi>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bignumber.js": "9.0.0",
|
"bignumber.js": "9.0.0",
|
||||||
"blakejs": "1.1.0",
|
"blakejs": "1.1.0",
|
||||||
"crypto-js": "3.1.9-1"
|
"crypto-js": "4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "12.7.12",
|
"@types/node": "12.7.12",
|
||||||
|
|
|
||||||
20
test/test.js
20
test/test.js
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const expect = require('chai').expect
|
const expect = require('chai').expect
|
||||||
const { wallet, block, converter } = require('../dist/index')
|
const { wallet, block, tools } = require('../dist/index')
|
||||||
|
|
||||||
// WARNING: Do not send any funds to the test vectors below
|
// WARNING: Do not send any funds to the test vectors below
|
||||||
describe('generate wallet test', () => {
|
describe('generate wallet test', () => {
|
||||||
|
|
@ -158,13 +158,27 @@ describe('block signing tests using official test vectors', () => {
|
||||||
describe('unit conversion tests', () => {
|
describe('unit conversion tests', () => {
|
||||||
|
|
||||||
it('should convert nano to raw', () => {
|
it('should convert nano to raw', () => {
|
||||||
const result = converter.convert('1', 'NANO', 'RAW')
|
const result = tools.convert('1', 'NANO', 'RAW')
|
||||||
expect(result).to.equal('1000000000000000000000000000000')
|
expect(result).to.equal('1000000000000000000000000000000')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should convert raw to nano', () => {
|
it('should convert raw to nano', () => {
|
||||||
const result = converter.convert('1000000000000000000000000000000', 'RAW', 'NANO')
|
const result = tools.convert('1000000000000000000000000000000', 'RAW', 'NANO')
|
||||||
expect(result).to.equal('1.000000000000000')
|
expect(result).to.equal('1.000000000000000')
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Signer tests', () => {
|
||||||
|
|
||||||
|
it('should sign data with a single parameter', () => {
|
||||||
|
const result = tools.sign('781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3', 'miro@metsanheimo.fi')
|
||||||
|
expect(result).to.equal('0ede9f287b7d58a053aa9ad84419c856ac39ec4c2453098ef19abf9638b07b1993e0cd3747723aada71602e92e781060dc3b91c410d32def1b4780a62fd0eb02')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sign data with multiple parameters', () => {
|
||||||
|
const result = tools.sign('781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3', 'miro@metsanheimo.fi', 'somePassword')
|
||||||
|
expect(result).to.equal('a7b88357a160f54cf4db2826c86483eb60e66e8ccb36f9a37f3fb636c9d80f7b59d1fba88d0be27f85ac3fcbe5c6e13f911d7e5b713e86fb8e9a635932a2af05')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue