@ -1,3 +1,5 @@
/* global describe, it, beforeEach, afterEach */
var assert = require ( 'assert' )
var bufferutils = require ( '../src/bufferutils' )
var crypto = require ( '../src/crypto' )
@ -15,72 +17,72 @@ var fixtureTxes = require('./fixtures/mainnet_tx')
var fixtureTx1Hex = fixtureTxes . prevTx
var fixtureTx2Hex = fixtureTxes . tx
function fakeTxHash ( i ) {
function fakeTxHash ( i ) {
var hash = new Buffer ( 32 )
hash . fill ( i )
return hash
}
function fakeTxId ( i ) {
function fakeTxId ( i ) {
var hash = fakeTxHash ( i )
Array . prototype . reverse . call ( hash )
return hash . toString ( 'hex' )
}
describe ( 'Wallet' , function ( ) {
describe ( 'Wallet' , function ( ) {
var seed
beforeEach ( function ( ) {
beforeEach ( function ( ) {
seed = crypto . sha256 ( "don't use a string seed like this in real life" )
} )
describe ( 'constructor' , function ( ) {
describe ( 'constructor' , function ( ) {
var wallet
beforeEach ( function ( ) {
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
it ( 'defaults to Bitcoin network' , function ( ) {
it ( 'defaults to Bitcoin network' , function ( ) {
assert . equal ( wallet . getMasterKey ( ) . network , networks . bitcoin )
} )
it ( "generates m/0' as the main account" , function ( ) {
it ( "generates m/0' as the main account" , function ( ) {
var mainAccount = wallet . getAccountZero ( )
assert . equal ( mainAccount . index , 0 + HDNode . HIGHEST_BIT )
assert . equal ( mainAccount . depth , 1 )
} )
it ( "generates m/0'/0 as the external account" , function ( ) {
it ( "generates m/0'/0 as the external account" , function ( ) {
var account = wallet . getExternalAccount ( )
assert . equal ( account . index , 0 )
assert . equal ( account . depth , 2 )
} )
it ( "generates m/0'/1 as the internal account" , function ( ) {
it ( "generates m/0'/1 as the internal account" , function ( ) {
var account = wallet . getInternalAccount ( )
assert . equal ( account . index , 1 )
assert . equal ( account . depth , 2 )
} )
describe ( 'when seed is not specified' , function ( ) {
it ( 'generates a seed' , function ( ) {
describe ( 'when seed is not specified' , function ( ) {
it ( 'generates a seed' , function ( ) {
var wallet = new Wallet ( )
assert ( wallet . getMasterKey ( ) )
} )
} )
describe ( 'constructor options' , function ( ) {
beforeEach ( function ( ) {
describe ( 'constructor options' , function ( ) {
beforeEach ( function ( ) {
wallet = new Wallet ( seed , networks . testnet )
} )
it ( 'uses the network if specified' , function ( ) {
it ( 'uses the network if specified' , function ( ) {
assert . equal ( wallet . getMasterKey ( ) . network , networks . testnet )
} )
} )
} )
describe ( 'newMasterKey' , function ( ) {
it ( 'resets accounts' , function ( ) {
describe ( 'newMasterKey' , function ( ) {
it ( 'resets accounts' , function ( ) {
var wallet = new Wallet ( )
var oldAccountZero = wallet . getAccountZero ( )
var oldExternalAccount = wallet . getExternalAccount ( )
@ -92,7 +94,7 @@ describe('Wallet', function() {
assertNotEqual ( wallet . getInternalAccount ( ) , oldInternalAccount )
} )
it ( 'resets addresses' , function ( ) {
it ( 'resets addresses' , function ( ) {
var wallet = new Wallet ( )
wallet . generateAddress ( )
wallet . generateChangeAddress ( )
@ -107,12 +109,12 @@ describe('Wallet', function() {
} )
} )
describe ( 'generateAddress' , function ( ) {
it ( 'generate receiving addresses' , function ( ) {
describe ( 'generateAddress' , function ( ) {
it ( 'generate receiving addresses' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
var expectedAddresses = [
"n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa" ,
"n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X"
'n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa' ,
'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X'
]
assert . equal ( wallet . generateAddress ( ) , expectedAddresses [ 0 ] )
@ -121,28 +123,18 @@ describe('Wallet', function() {
} )
} )
describe ( 'generateChangeAddress' , function ( ) {
var wallet
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
it ( 'generates change addresses' , function ( ) {
describe ( 'generateChangeAddress' , function ( ) {
it ( 'generates change addresses' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
var expectedAddresses = [ "mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn" ]
var expectedAddresses = [ 'mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn' ]
assert . equal ( wallet . generateChangeAddress ( ) , expectedAddresses [ 0 ] )
assert . deepEqual ( wallet . changeAddresses , expectedAddresses )
} )
} )
describe ( 'getPrivateKey' , function ( ) {
var wallet
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
it ( 'returns the private key at the given index of external account' , function ( ) {
describe ( 'getPrivateKey' , function ( ) {
it ( 'returns the private key at the given index of external account' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
assertEqual ( wallet . getPrivateKey ( 0 ) , wallet . getExternalAccount ( ) . derive ( 0 ) . privKey )
@ -150,13 +142,8 @@ describe('Wallet', function() {
} )
} )
describe ( 'getInternalPrivateKey' , function ( ) {
var wallet
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
it ( 'returns the private key at the given index of internal account' , function ( ) {
describe ( 'getInternalPrivateKey' , function ( ) {
it ( 'returns the private key at the given index of internal account' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
assertEqual ( wallet . getInternalPrivateKey ( 0 ) , wallet . getInternalAccount ( ) . derive ( 0 ) . privKey )
@ -164,59 +151,54 @@ describe('Wallet', function() {
} )
} )
describe ( 'getPrivateKeyForAddress' , function ( ) {
var wallet
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
it ( 'returns the private key for the given address' , function ( ) {
describe ( 'getPrivateKeyForAddress' , function ( ) {
it ( 'returns the private key for the given address' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
wallet . generateChangeAddress ( )
wallet . generateAddress ( )
wallet . generateAddress ( )
assertEqual (
wallet . getPrivateKeyForAddress ( "n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X" ) ,
wallet . getPrivateKeyForAddress ( 'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X' ) ,
wallet . getExternalAccount ( ) . derive ( 1 ) . privKey
)
assertEqual (
wallet . getPrivateKeyForAddress ( "mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn" ) ,
wallet . getPrivateKeyForAddress ( 'mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn' ) ,
wallet . getInternalAccount ( ) . derive ( 0 ) . privKey
)
} )
it ( 'raises an error when address is not found' , function ( ) {
it ( 'raises an error when address is not found' , function ( ) {
var wallet = new Wallet ( seed , networks . testnet )
assert . throws ( function ( ) {
wallet . getPrivateKeyForAddress ( "n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X" )
assert . throws ( function ( ) {
wallet . getPrivateKeyForAddress ( 'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X' )
} , /Unknown address. Make sure the address is from the keychain and has been generated/ )
} )
} )
describe ( 'Unspent Outputs' , function ( ) {
var utxo , expectedOutputKey
describe ( 'Unspent Outputs' , function ( ) {
var utxo
var wallet
beforeEach ( function ( ) {
beforeEach ( function ( ) {
utxo = {
"address" : "1AZpKpcfCzKDUeTFBQUL4MokQai3m3HMXv" ,
"confirmations" : 1 ,
"index" : 0 ,
"txId" : fakeTxId ( 6 ) ,
"value" : 20000 ,
"pending" : false
'address' : '1AZpKpcfCzKDUeTFBQUL4MokQai3m3HMXv' ,
'confirmations' : 1 ,
'index' : 0 ,
'txId' : fakeTxId ( 6 ) ,
'value' : 20000 ,
'pending' : false
}
} )
describe ( 'on construction' , function ( ) {
beforeEach ( function ( ) {
describe ( 'on construction' , function ( ) {
beforeEach ( function ( ) {
wallet = new Wallet ( seed , networks . bitcoin )
wallet . setUnspentOutputs ( [ utxo ] )
} )
it ( 'matches the expected behaviour' , function ( ) {
it ( 'matches the expected behaviour' , function ( ) {
var output = wallet . unspents [ 0 ]
assert . equal ( output . address , utxo . address )
@ -224,8 +206,8 @@ describe('Wallet', function() {
} )
} )
describe ( 'getBalance' , function ( ) {
beforeEach ( function ( ) {
describe ( 'getBalance' , function ( ) {
beforeEach ( function ( ) {
var utxo1 = cloneObject ( utxo )
utxo1 . hash = fakeTxId ( 5 )
@ -233,18 +215,18 @@ describe('Wallet', function() {
wallet . setUnspentOutputs ( [ utxo , utxo1 ] )
} )
it ( 'sums over utxo values' , function ( ) {
it ( 'sums over utxo values' , function ( ) {
assert . equal ( wallet . getBalance ( ) , 40000 )
} )
} )
describe ( 'getUnspentOutputs' , function ( ) {
beforeEach ( function ( ) {
describe ( 'getUnspentOutputs' , function ( ) {
beforeEach ( function ( ) {
wallet = new Wallet ( seed , networks . bitcoin )
wallet . setUnspentOutputs ( [ utxo ] )
} )
it ( 'parses wallet unspents to the expected format' , function ( ) {
it ( 'parses wallet unspents to the expected format' , function ( ) {
var outputs = wallet . getUnspentOutputs ( )
var output = outputs [ 0 ]
@ -261,7 +243,7 @@ describe('Wallet', function() {
assert . equal ( utxo . confirmations , output . confirmations )
} )
it ( "ignores spent unspents (outputs with 'spent' property)" , function ( ) {
it ( "ignores spent unspents (outputs with 'spent' property)" , function ( ) {
var unspent = wallet . unspents [ 0 ]
unspent . pending = true
unspent . spent = true
@ -270,12 +252,11 @@ describe('Wallet', function() {
} )
} )
describe ( 'setUnspentOutputs' , function ( ) {
describe ( 'setUnspentOutputs' , function ( ) {
var utxo
var expectedOutputKey
var wallet
beforeEach ( function ( ) {
beforeEach ( function ( ) {
utxo = {
hash : fakeTxId ( 0 ) ,
index : 0 ,
@ -286,7 +267,7 @@ describe('Wallet', function() {
wallet = new Wallet ( seed , networks . bitcoin )
} )
it ( 'matches the expected behaviour' , function ( ) {
it ( 'matches the expected behaviour' , function ( ) {
wallet . setUnspentOutputs ( [ utxo ] )
var output = wallet . unspents [ 0 ]
@ -294,12 +275,12 @@ describe('Wallet', function() {
assert . equal ( output . address , utxo . address )
} )
describe ( 'required fields' , function ( ) {
[ 'index' , 'address' , 'hash' , 'value' ] . forEach ( function ( field ) {
it ( "throws an error when " + field + " is missing" , function ( ) {
describe ( 'required fields' , function ( ) {
[ 'index' , 'address' , 'hash' , 'value' ] . forEach ( function ( field ) {
it ( 'throws an error when ' + field + ' is missing' , function ( ) {
delete utxo [ field ]
assert . throws ( function ( ) {
assert . throws ( function ( ) {
wallet . setUnspentOutputs ( [ utxo ] )
} )
} )
@ -307,16 +288,16 @@ describe('Wallet', function() {
} )
} )
describe ( 'Process transaction' , function ( ) {
describe ( 'Process transaction' , function ( ) {
var wallet
beforeEach ( function ( ) {
beforeEach ( function ( ) {
wallet = new Wallet ( seed )
} )
var addresses
var tx
beforeEach ( function ( ) {
beforeEach ( function ( ) {
addresses = [
'115qa7iPZqn6as57hxLL8E9VUnhmGQxKWi' ,
'1Bu3bhwRmevHLAy1JrRB6AfcxfgDG2vXRd' ,
@ -326,24 +307,24 @@ describe('Wallet', function() {
tx = Transaction . fromHex ( fixtureTx1Hex )
} )
describe ( "processPendingTx" , function ( ) {
it ( "incoming: sets the pending flag on output" , function ( ) {
describe ( 'processPendingTx' , function ( ) {
it ( 'incoming: sets the pending flag on output' , function ( ) {
wallet . addresses = [ addresses [ 0 ] ]
wallet . processPendingTx ( tx )
verifyOutputAdded ( 0 , true )
} )
describe ( "when tx ins outpoint contains a known txhash:i" , function ( ) {
describe ( 'when tx ins outpoint contains a known txhash:i' , function ( ) {
var spendTx
beforeEach ( function ( ) {
beforeEach ( function ( ) {
wallet . addresses = [ addresses [ 0 ] ]
wallet . processConfirmedTx ( tx )
spendTx = Transaction . fromHex ( fixtureTx2Hex )
} )
it ( "outgoing: sets the pending flag and 'spent' on output" , function ( ) {
it ( "outgoing: sets the pending flag and 'spent' on output" , function ( ) {
var txIn = spendTx . ins [ 0 ]
var txInId = new Buffer ( txIn . hash )
Array . prototype . reverse . call ( txInId )
@ -359,8 +340,8 @@ describe('Wallet', function() {
} )
} )
describe ( 'processConfirmedTx' , function ( ) {
it ( 'does not throw on scripts with no corresponding Address' , function ( ) {
describe ( 'processConfirmedTx' , function ( ) {
it ( 'does not throw on scripts with no corresponding Address' , function ( ) {
var pubKey = wallet . getPrivateKey ( 0 ) . pub
var script = scripts . pubKeyOutput ( pubKey )
var tx2 = new Transaction ( )
@ -371,8 +352,8 @@ describe('Wallet', function() {
wallet . processConfirmedTx ( tx2 )
} )
describe ( "when tx outs contains an address owned by the wallet, an 'output' gets added to wallet.unspentMap" , function ( ) {
it ( "works for receive address" , function ( ) {
describe ( "when tx outs contains an address owned by the wallet, an 'output' gets added to wallet.unspentMap" , function ( ) {
it ( 'works for receive address' , function ( ) {
var totalOuts = outputCount ( )
wallet . addresses = [ addresses [ 0 ] ]
@ -382,7 +363,7 @@ describe('Wallet', function() {
verifyOutputAdded ( 0 , false )
} )
it ( "works for change address" , function ( ) {
it ( 'works for change address' , function ( ) {
var totalOuts = outputCount ( )
wallet . changeAddresses = [ addresses [ 1 ] ]
@ -392,26 +373,26 @@ describe('Wallet', function() {
verifyOutputAdded ( 1 , false )
} )
function outputCount ( ) {
function outputCount ( ) {
return Object . keys ( wallet . unspentMap ) . length
}
} )
describe ( "when tx ins contains a known txhash:i" , function ( ) {
describe ( 'when tx ins contains a known txhash:i' , function ( ) {
var spendTx
beforeEach ( function ( ) {
beforeEach ( function ( ) {
wallet . addresses = [ addresses [ 0 ] ] // the address fixtureTx2 used as input
wallet . processConfirmedTx ( tx )
spendTx = Transaction . fromHex ( fixtureTx2Hex )
} )
it ( "does not add to wallet.unspentMap" , function ( ) {
it ( 'does not add to wallet.unspentMap' , function ( ) {
wallet . processConfirmedTx ( spendTx )
assert . deepEqual ( wallet . unspentMap , { } )
} )
it ( "deletes corresponding 'unspent'" , function ( ) {
it ( "deletes corresponding 'unspent'" , function ( ) {
var txIn = spendTx . ins [ 0 ]
var txInId = bufferutils . reverse ( txIn . hash ) . toString ( 'hex' )
@ -424,16 +405,15 @@ describe('Wallet', function() {
} )
} )
it ( "does nothing when none of the involved addresses belong to the wallet" , function ( ) {
it ( 'does nothing when none of the involved addresses belong to the wallet' , function ( ) {
wallet . processConfirmedTx ( tx )
assert . deepEqual ( wallet . unspentMap , { } )
} )
function verifyOutputAdded ( index , pending ) {
function verifyOutputAdded ( index , pending ) {
var txOut = tx . outs [ index ]
var key = tx . getId ( ) + ":" + index
var key = tx . getId ( ) + ':' + index
var output = wallet . unspentMap [ key ]
assert . deepEqual ( output . txHash , tx . getHash ( ) )
assert . equal ( output . value , txOut . value )
@ -444,37 +424,37 @@ describe('Wallet', function() {
}
} )
describe ( 'createTx' , function ( ) {
describe ( 'createTx' , function ( ) {
var wallet
var address1 , address2
var to , value
beforeEach ( function ( ) {
beforeEach ( function ( ) {
to = 'mt7MyTVVEWnbwpF5hBn6fgnJcv95Syk2ue'
value = 500000
address1 = "n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa"
address2 = "n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X"
address1 = 'n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa'
address2 = 'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X'
// set up 3 utxos
var utxos = [
{
"txId" : fakeTxId ( 1 ) ,
"index" : 0 ,
"address" : address1 ,
"value" : 400000 // not enough for value
'txId' : fakeTxId ( 1 ) ,
'index' : 0 ,
'address' : address1 ,
'value' : 400000 // not enough for value
} ,
{
"txId" : fakeTxId ( 2 ) ,
"index" : 1 ,
"address" : address1 ,
"value" : 500000 // enough for only value
'txId' : fakeTxId ( 2 ) ,
'index' : 1 ,
'address' : address1 ,
'value' : 500000 // enough for only value
} ,
{
"txId" : fakeTxId ( 3 ) ,
"index" : 0 ,
"address" : address2 ,
"value" : 510000 // enough for value and fee
'txId' : fakeTxId ( 3 ) ,
'index' : 0 ,
'address' : address2 ,
'value' : 510000 // enough for value and fee
}
]
@ -484,27 +464,31 @@ describe('Wallet', function() {
wallet . generateAddress ( )
} )
describe ( 'transaction fee' , function ( ) {
it ( 'allows fee to be specified' , function ( ) {
describe ( 'transaction fee' , function ( ) {
it ( 'allows fee to be specified' , function ( ) {
var fee = 30000
var tx = wallet . createTx ( to , value , { fixedFee : fee } )
var tx = wallet . createTx ( to , value , {
fixedFee : fee
} )
assert . equal ( getFee ( wallet , tx ) , fee )
} )
it ( 'allows fee to be set to zero' , function ( ) {
it ( 'allows fee to be set to zero' , function ( ) {
value = 510000
var fee = 0
var tx = wallet . createTx ( to , value , { fixedFee : fee } )
var tx = wallet . createTx ( to , value , {
fixedFee : fee
} )
assert . equal ( getFee ( wallet , tx ) , fee )
} )
it ( 'does not overestimate fees when network has dustSoftThreshold' , function ( ) {
it ( 'does not overestimate fees when network has dustSoftThreshold' , function ( ) {
var utxo = {
txId : fakeTxId ( 0 ) ,
index : 0 ,
address : "LeyySKbQrRRwodKEj1W4a8y3YQupPLw5os" ,
address : 'LeyySKbQrRRwodKEj1W4a8y3YQupPLw5os' ,
value : 500000
}
@ -518,21 +502,21 @@ describe('Wallet', function() {
assert . equal ( getFee ( wallet , tx ) , 100000 )
} )
function getFee ( wallet , tx ) {
var inputValue = tx . ins . reduce ( function ( accum , input ) {
function getFee ( wallet , tx ) {
var inputValue = tx . ins . reduce ( function ( accum , input ) {
var txId = bufferutils . reverse ( input . hash ) . toString ( 'hex' )
return accum + wallet . unspentMap [ txId + ':' + input . index ] . value
} , 0 )
return tx . outs . reduce ( function ( accum , output ) {
return tx . outs . reduce ( function ( accum , output ) {
return accum - output . value
} , inputValue )
}
} )
describe ( 'choosing utxo' , function ( ) {
it ( 'takes fees into account' , function ( ) {
describe ( 'choosing utxo' , function ( ) {
it ( 'takes fees into account' , function ( ) {
var tx = wallet . createTx ( to , value )
assert . equal ( tx . ins . length , 1 )
@ -540,7 +524,7 @@ describe('Wallet', function() {
assert . equal ( tx . ins [ 0 ] . index , 0 )
} )
it ( 'uses confirmed outputs' , function ( ) {
it ( 'uses confirmed outputs' , function ( ) {
var tx2 = new Transaction ( )
tx2 . addInput ( fakeTxId ( 4 ) , 0 )
tx2 . addOutput ( address2 , 530000 )
@ -553,7 +537,7 @@ describe('Wallet', function() {
assert . equal ( tx . ins [ 0 ] . index , 0 )
} )
it ( 'ignores pending outputs' , function ( ) {
it ( 'ignores pending outputs' , function ( ) {
var tx2 = new Transaction ( )
tx2 . addInput ( fakeTxId ( 4 ) , 0 )
tx2 . addOutput ( address2 , 530000 )
@ -567,8 +551,8 @@ describe('Wallet', function() {
} )
} )
describe ( 'changeAddress' , function ( ) {
it ( 'should allow custom changeAddress' , function ( ) {
describe ( 'changeAddress' , function ( ) {
it ( 'should allow custom changeAddress' , function ( ) {
var changeAddress = 'mfrFjnKZUvTcvdAK2fUX5D8v1Epu5H8JCk'
var fromValue = 510000
var toValue = fromValue / 2
@ -591,8 +575,8 @@ describe('Wallet', function() {
} )
} )
describe ( 'transaction outputs' , function ( ) {
it ( 'includes the specified address and amount' , function ( ) {
describe ( 'transaction outputs' , function ( ) {
it ( 'includes the specified address and amount' , function ( ) {
var tx = wallet . createTx ( to , value )
assert . equal ( tx . outs . length , 1 )
@ -603,12 +587,14 @@ describe('Wallet', function() {
assert . equal ( out . value , value )
} )
describe ( 'change' , function ( ) {
it ( 'uses the last change address if there is any' , function ( ) {
describe ( 'change' , function ( ) {
it ( 'uses the last change address if there is any' , function ( ) {
var fee = 0
wallet . generateChangeAddress ( )
wallet . generateChangeAddress ( )
var tx = wallet . createTx ( to , value , { fixedFee : fee } )
var tx = wallet . createTx ( to , value , {
fixedFee : fee
} )
assert . equal ( tx . outs . length , 2 )
var out = tx . outs [ 1 ]
@ -618,11 +604,13 @@ describe('Wallet', function() {
assert . equal ( out . value , 10000 )
} )
it ( 'generates a change address if there is not any' , function ( ) {
it ( 'generates a change address if there is not any' , function ( ) {
var fee = 0
assert . equal ( wallet . changeAddresses . length , 0 )
var tx = wallet . createTx ( to , value , { fixedFee : fee } )
var tx = wallet . createTx ( to , value , {
fixedFee : fee
} )
assert . equal ( wallet . changeAddresses . length , 1 )
var out = tx . outs [ 1 ]
@ -632,7 +620,7 @@ describe('Wallet', function() {
assert . equal ( out . value , 10000 )
} )
it ( 'skips change if it is not above dust threshold' , function ( ) {
it ( 'skips change if it is not above dust threshold' , function ( ) {
var tx1 = wallet . createTx ( to , value - 546 )
assert . equal ( tx1 . outs . length , 1 )
@ -642,59 +630,62 @@ describe('Wallet', function() {
} )
} )
describe ( 'signing' , function ( ) {
afterEach ( function ( ) {
describe ( 'signing' , function ( ) {
afterEach ( function ( ) {
TransactionBuilder . prototype . sign . restore ( )
} )
it ( 'signs the inputs with respective keys' , function ( ) {
it ( 'signs the inputs with respective keys' , function ( ) {
var fee = 30000
sinon . spy ( TransactionBuilder . prototype , "sign" )
sinon . spy ( TransactionBuilder . prototype , 'sign' )
wallet . createTx ( to , value , { fixedFee : fee } )
wallet . createTx ( to , value , {
fixedFee : fee
} )
var priv1 = wallet . getPrivateKeyForAddress ( address1 )
var priv2 = wallet . getPrivateKeyForAddress ( address2 )
// FIXME: boo (required) side effects
priv1 . pub . Q . affineX , priv2 . pub . Q . affineX
// FIXME: boo, toString invokes reqiuired affine coordinate side effects
priv1 . pub . Q . toString ( )
priv2 . pub . Q . toString ( )
assert ( TransactionBuilder . prototype . sign . calledWith ( 0 , priv2 ) )
assert ( TransactionBuilder . prototype . sign . calledWith ( 1 , priv1 ) )
} )
} )
describe ( 'when value is below dust threshold' , function ( ) {
it ( 'throws an error' , function ( ) {
describe ( 'when value is below dust threshold' , function ( ) {
it ( 'throws an error' , function ( ) {
var value = 546
assert . throws ( function ( ) {
assert . throws ( function ( ) {
wallet . createTx ( to , value )
} , /546 must be above dust threshold \(546 Satoshis\)/ )
} )
} )
describe ( 'when there is not enough money' , function ( ) {
it ( 'throws an error' , function ( ) {
describe ( 'when there is not enough money' , function ( ) {
it ( 'throws an error' , function ( ) {
var value = 1400001
assert . throws ( function ( ) {
assert . throws ( function ( ) {
wallet . createTx ( to , value )
} , /Not enough funds \(incl. fee\): 1410000 < 1410001/ )
} )
} )
} )
function assertEqual ( obj1 , obj2 ) {
function assertEqual ( obj1 , obj2 ) {
assert . equal ( obj1 . toString ( ) , obj2 . toString ( ) )
}
function assertNotEqual ( obj1 , obj2 ) {
function assertNotEqual ( obj1 , obj2 ) {
assert . notEqual ( obj1 . toString ( ) , obj2 . toString ( ) )
}
// quick and dirty: does not deal with functions on object
function cloneObject ( obj ) {
function cloneObject ( obj ) {
return JSON . parse ( JSON . stringify ( obj ) )
}
} )