From 5f60d26a2b1ed30d07379631c1fcf97d26ddcd24 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 1 Oct 2014 16:26:09 -0400 Subject: [PATCH 01/13] Migrate from Address() to Identity(). --- lib/{address.js => identity.js} | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) rename lib/{address.js => identity.js} (77%) diff --git a/lib/address.js b/lib/identity.js similarity index 77% rename from lib/address.js rename to lib/identity.js index 6103098b0..bd85ccd7a 100644 --- a/lib/address.js +++ b/lib/identity.js @@ -4,9 +4,9 @@ var Hash = require('./hash'); var Pubkey = require('./pubkey'); var Script = require('./script'); -function Address(buf) { - if (!(this instanceof Address)) - return new Address(buf); +function Identity(buf) { + if (!(this instanceof Identity)) + return new Identity(buf); if (Buffer.isBuffer(buf)) { this.fromBuffer(buf); } else if (typeof buf === 'string') { @@ -18,16 +18,16 @@ function Address(buf) { } }; -Address.prototype.set = function(obj) { +Identity.prototype.set = function(obj) { this.hashbuf = obj.hashbuf || this.hashbuf || null; this.networkstr = obj.networkstr || this.networkstr || 'mainnet'; this.typestr = obj.typestr || this.typestr || 'pubkeyhash'; return this; }; -Address.prototype.fromBuffer = function(buf) { +Identity.prototype.fromBuffer = function(buf) { if (buf.length !== 1 + 20) - throw new Error('Address buffers must be exactly 21 bytes'); + throw new Error('Identity buffers must be exactly 21 bytes'); var version = buf[0]; if (version === constants['mainnet']['pubkeyhash']) { this.networkstr = 'mainnet'; @@ -51,7 +51,7 @@ Address.prototype.fromBuffer = function(buf) { return this; }; -Address.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) { +Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) { if (hashbuf.length !== 20) throw new Error('hashbuf must be exactly 20 bytes'); this.hashbuf = hashbuf; @@ -60,35 +60,35 @@ Address.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) { return this; }; -Address.prototype.fromPubkey = function(pubkey, networkstr) { +Identity.prototype.fromPubkey = function(pubkey, networkstr) { this.hashbuf = Hash.sha256ripemd160(pubkey.toBuffer()); this.networkstr = networkstr || 'mainnet'; this.typestr = 'pubkeyhash'; return this; }; -Address.prototype.fromScript = function(script, networkstr) { +Identity.prototype.fromScript = function(script, networkstr) { this.hashbuf = Hash.sha256ripemd160(script.toBuffer()); this.networkstr = networkstr || 'mainnet'; this.typestr = 'scripthash'; return this; }; -Address.prototype.fromString = function(str) { +Identity.prototype.fromString = function(str) { var buf = base58check.decode(str); return this.fromBuffer(buf); } -Address.isValid = function(addrstr) { +Identity.isValid = function(addrstr) { try { - var address = new Address().fromString(addrstr); + var address = new Identity().fromString(addrstr); } catch (e) { return false; } return address.isValid(); }; -Address.prototype.isValid = function() { +Identity.prototype.isValid = function() { try { this.validate(); return true; @@ -97,17 +97,17 @@ Address.prototype.isValid = function() { } }; -Address.prototype.toBuffer = function() { +Identity.prototype.toBuffer = function() { version = new Buffer([constants[this.networkstr][this.typestr]]); var buf = Buffer.concat([version, this.hashbuf]); return buf; }; -Address.prototype.toString = function() { +Identity.prototype.toString = function() { return base58check.encode(this.toBuffer()); }; -Address.prototype.validate = function() { +Identity.prototype.validate = function() { if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 20) throw new Error('hash must be a buffer of 20 bytes'); if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet') @@ -117,4 +117,4 @@ Address.prototype.validate = function() { return this; }; -module.exports = Address; +module.exports = Identity; From 541196cb5a632cadc4b090dd583a49d366bca538 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 1 Oct 2014 16:28:57 -0400 Subject: [PATCH 02/13] Re-implement addresses. --- lib/address.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/address.js diff --git a/lib/address.js b/lib/address.js new file mode 100644 index 000000000..d87c08ed6 --- /dev/null +++ b/lib/address.js @@ -0,0 +1,14 @@ +var base58check = require('./base58check'); +var constants = require('./constants'); +var util = require('util'); +var Identity = require('./identity'); + +function Address() { + +}; + +util.inherits( Address , Identity ); + + + +module.exports = Address; From e8d4786e484f45d166e50c0d209f076de07d5171 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 1 Oct 2014 19:20:03 -0400 Subject: [PATCH 03/13] CLASSICAL INHERITANCE IS FOR THE DOGS. --- lib/address.js | 116 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 5 deletions(-) diff --git a/lib/address.js b/lib/address.js index d87c08ed6..6103098b0 100644 --- a/lib/address.js +++ b/lib/address.js @@ -1,14 +1,120 @@ var base58check = require('./base58check'); var constants = require('./constants'); -var util = require('util'); -var Identity = require('./identity'); - -function Address() { +var Hash = require('./hash'); +var Pubkey = require('./pubkey'); +var Script = require('./script'); +function Address(buf) { + if (!(this instanceof Address)) + return new Address(buf); + if (Buffer.isBuffer(buf)) { + this.fromBuffer(buf); + } else if (typeof buf === 'string') { + var str = buf; + this.fromString(str); + } else if (buf) { + var obj = buf; + this.set(obj); + } }; -util.inherits( Address , Identity ); +Address.prototype.set = function(obj) { + this.hashbuf = obj.hashbuf || this.hashbuf || null; + this.networkstr = obj.networkstr || this.networkstr || 'mainnet'; + this.typestr = obj.typestr || this.typestr || 'pubkeyhash'; + return this; +}; +Address.prototype.fromBuffer = function(buf) { + if (buf.length !== 1 + 20) + throw new Error('Address buffers must be exactly 21 bytes'); + var version = buf[0]; + if (version === constants['mainnet']['pubkeyhash']) { + this.networkstr = 'mainnet'; + this.typestr = 'pubkeyhash'; + } else if (version === constants['mainnet']['scripthash']) { + this.networkstr = 'mainnet'; + this.typestr = 'scripthash'; + } else if (version === constants['testnet']['pubkeyhash']) { + this.networkstr = 'testnet'; + this.typestr = 'pubkeyhash'; + } else if (version === constants['testnet']['scripthash']) { + this.networkstr = 'testnet'; + this.typestr = 'scripthash'; + } else { + this.networkstr = 'unknown'; + this.typestr = 'unknown'; + } + this.hashbuf = buf.slice(1); + + return this; +}; + +Address.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) { + if (hashbuf.length !== 20) + throw new Error('hashbuf must be exactly 20 bytes'); + this.hashbuf = hashbuf; + this.networkstr = networkstr || 'mainnet'; + this.typestr = typestr || 'pubkeyhash'; + return this; +}; + +Address.prototype.fromPubkey = function(pubkey, networkstr) { + this.hashbuf = Hash.sha256ripemd160(pubkey.toBuffer()); + this.networkstr = networkstr || 'mainnet'; + this.typestr = 'pubkeyhash'; + return this; +}; + +Address.prototype.fromScript = function(script, networkstr) { + this.hashbuf = Hash.sha256ripemd160(script.toBuffer()); + this.networkstr = networkstr || 'mainnet'; + this.typestr = 'scripthash'; + return this; +}; + +Address.prototype.fromString = function(str) { + var buf = base58check.decode(str); + return this.fromBuffer(buf); +} + +Address.isValid = function(addrstr) { + try { + var address = new Address().fromString(addrstr); + } catch (e) { + return false; + } + return address.isValid(); +}; + +Address.prototype.isValid = function() { + try { + this.validate(); + return true; + } catch (e) { + return false; + } +}; + +Address.prototype.toBuffer = function() { + version = new Buffer([constants[this.networkstr][this.typestr]]); + var buf = Buffer.concat([version, this.hashbuf]); + return buf; +}; + +Address.prototype.toString = function() { + return base58check.encode(this.toBuffer()); +}; + +Address.prototype.validate = function() { + if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 20) + throw new Error('hash must be a buffer of 20 bytes'); + if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet') + throw new Error('networkstr must be "mainnet" or "testnet"'); + if (this.typestr !== 'pubkeyhash' && this.typestr !== 'scripthash') + throw new Error('typestr must be "pubkeyhash" or "scripthash"'); + return this; +}; module.exports = Address; From 43d21e9f029d9dbd7e1bf238ebbe00e4e73c31f8 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 1 Oct 2014 19:22:41 -0400 Subject: [PATCH 04/13] Remove old tests. --- examples/Address.js | 28 -- examples/Armory.js | 65 --- examples/ConnectionTor.js | 37 -- examples/CreateAndSignTx-Multisig.js | 108 ---- examples/CreateAndSignTx-PayToPubkeyHash.js | 73 --- examples/CreateAndSignTx-PayToScriptHash.js | 151 ------ examples/CreateKey.js | 48 -- examples/CreateScript.js | 76 --- examples/ECIES.js | 30 -- examples/ElectrumMPK.js | 11 - examples/HierarchicalKey.js | 83 ---- examples/NetworkMonitor.js | 29 -- examples/Opreturn.js | 20 - examples/PayPro/README.md | 74 --- examples/PayPro/bitcore.js | 1 - examples/PayPro/customer.js | 515 -------------------- examples/PayPro/index.html | 28 -- examples/PayPro/index.js | 3 - examples/PayPro/server.js | 438 ----------------- examples/PayPro/style.css | 66 --- examples/PayToScriptHashAddress.js | 17 - examples/PeerDiscovery.js | 6 - examples/PeerManager.js | 47 -- examples/Rpc.js | 32 -- examples/Script.js | 52 -- examples/ScriptInterpreter.js | 42 -- examples/SendTx.js | 107 ---- examples/SimpleP2Pmonitor.js | 72 --- examples/VanityAddress.js | 28 -- examples/browser/README.md | 1 - examples/browser/armory.html | 58 --- examples/browser/example.html | 98 ---- examples/browser/simple.html | 13 - 33 files changed, 2457 deletions(-) delete mode 100644 examples/Address.js delete mode 100644 examples/Armory.js delete mode 100644 examples/ConnectionTor.js delete mode 100644 examples/CreateAndSignTx-Multisig.js delete mode 100644 examples/CreateAndSignTx-PayToPubkeyHash.js delete mode 100644 examples/CreateAndSignTx-PayToScriptHash.js delete mode 100644 examples/CreateKey.js delete mode 100644 examples/CreateScript.js delete mode 100644 examples/ECIES.js delete mode 100644 examples/ElectrumMPK.js delete mode 100644 examples/HierarchicalKey.js delete mode 100644 examples/NetworkMonitor.js delete mode 100644 examples/Opreturn.js delete mode 100644 examples/PayPro/README.md delete mode 120000 examples/PayPro/bitcore.js delete mode 100644 examples/PayPro/customer.js delete mode 100644 examples/PayPro/index.html delete mode 100755 examples/PayPro/index.js delete mode 100755 examples/PayPro/server.js delete mode 100644 examples/PayPro/style.css delete mode 100644 examples/PayToScriptHashAddress.js delete mode 100644 examples/PeerDiscovery.js delete mode 100644 examples/PeerManager.js delete mode 100644 examples/Rpc.js delete mode 100644 examples/Script.js delete mode 100644 examples/ScriptInterpreter.js delete mode 100644 examples/SendTx.js delete mode 100644 examples/SimpleP2Pmonitor.js delete mode 100644 examples/VanityAddress.js delete mode 100644 examples/browser/README.md delete mode 100644 examples/browser/armory.html delete mode 100644 examples/browser/example.html delete mode 100644 examples/browser/simple.html diff --git a/examples/Address.js b/examples/Address.js deleted file mode 100644 index 7aa9778cf..000000000 --- a/examples/Address.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - - -var run = function() { - // Replace '../bitcore' with 'bitcore' if you use this code elsewhere. - var bitcore = require('../bitcore'); - var Address = bitcore.Address; - - var addrs = [ - '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', - '1A1zP1eP5QGefi2DMPTfTL5SLmv7Dixxxx', - 'A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', - '1600 Pennsylvania Ave NW', - ].map(function(addr) { - return new Address(addr); - }); - - addrs.forEach(function(addr) { - var valid = addr.isValid(); - console.log(addr.data + ' is ' + (valid ? '' : 'not ') + 'valid'); - }); - -}; - -module.exports.run = run; -if (require.main === module) { - run(); -} diff --git a/examples/Armory.js b/examples/Armory.js deleted file mode 100644 index c077c9e2f..000000000 --- a/examples/Armory.js +++ /dev/null @@ -1,65 +0,0 @@ -var Armory = require('../lib/Armory'); -var Address = require('../lib/Address'); - -// Initial public key can be retrieved from paper backup - -var PublicX = '9df5 23e7 18b9 1f59 a790 2d46 999f 9357 ccf8 7208 24d4 3076 4516 b809 f7ab ce4e'; -var PublicY = '66ba 5d21 4682 0dae 401d 9506 8437 2516 79f9 0c56 4186 cc50 07df c6d0 6989 1ff4'; -var pubkey = '04' + PublicX.split(' ').join('') + PublicY.split(' ').join(''); - -// Chain code can be generated by entering paper backup -// on brainwallet.org/#chains or by using Armory.fromSeed() below - -var chaincode = '84ac14bc4b388b33da099a0b4ee3b507284d99e1476639e36e5ca5e6af86481e'; - -var armory = new Armory(chaincode, pubkey); - -console.log('Deriving public keys for'); -console.log('------------------------'); -console.log('Chain code: %s', chaincode); -console.log('Public key: %s', pubkey); -console.log(''); - -for (var i = 0; i < 5; i++) { - console.log(Address.fromPubKey(armory.pubkey).as('base58')); - armory = armory.next(); -} - -// Derive first public key and chain code from seed -var seed = [ - 'aagh hjfj sihk ietj giik wwai awtd uodh hnji', - 'soss uaku egod utai itos fijj ihgi jhau jtoo' -]; - -console.log(''); -console.log(''); -console.log('Deriving public keys for'); -console.log('------------------------'); -console.log('Seed: %s', seed.join(' ')); -console.log(''); - -// skip first public key -var a = Armory.fromSeed(seed.join('\n')).next(); - -for (var i = 0; i < 5; i++) { - console.log(Address.fromPubKey(a.pubkey).as('base58')); - a = a.next(); -} - - -var mpk = '045a09a3286873a72f164476bde9d1d8e5c2bc044e35aa47eb6e798e325a86417f7c35b61d9905053533e0b4f2a26eca0330aadf21c638969e45aaace50e4c0c8784ac14bc4b388b33da099a0b4ee3b507284d99e1476639e36e5ca5e6af86481e'; - -console.log(''); -console.log(''); -console.log('Deriving public keys for'); -console.log('------------------------'); -console.log('Master Public Key: %s', mpk); -console.log(''); - -// skip first public key -var b = Armory.fromMasterPublicKey(mpk).next(); - -for (var i = 0; i < 5; i++) { - console.log(Address.fromPubKey(b.pubkey).as('base58')); - b = b.next(); -} diff --git a/examples/ConnectionTor.js b/examples/ConnectionTor.js deleted file mode 100644 index a62217806..000000000 --- a/examples/ConnectionTor.js +++ /dev/null @@ -1,37 +0,0 @@ -var Peer = require('../lib/Peer'); -var Connection = require('../lib/Connection'); -var dns = require('dns'); - -// get a peer from dns seed -dns.resolve('dnsseed.bluematt.me', function(err, seeds) { - // use the first peer - var peer = new Peer(seeds[0], 8333); - - //Custom peer: - //var peer = new Peer('180.153.139.246', '8888'); - - // create a connection without an existing socket - // but specify a socks5 proxy to create a socket - // that's bound to that proxy in it's place - var connection = new Connection(null, peer, { - proxy: { - host: '127.0.0.1', - port: 9050 - } - }); - - connection.open(); - - connection.on('connect', function(data) { - console.log('connected through socks5!'); - }); - - connection.on('error', function(err) { - console.log('There was an error running this example.'); - console.log('Are you running Tor? Tor must running for this example to work.'); - console.log('If you still get an error, you may need to use a different proxy from here:'); - console.log('http://sockslist.net/'); - //console.log(err); - }); - -}); diff --git a/examples/CreateAndSignTx-Multisig.js b/examples/CreateAndSignTx-Multisig.js deleted file mode 100644 index 1f9a739f0..000000000 --- a/examples/CreateAndSignTx-Multisig.js +++ /dev/null @@ -1,108 +0,0 @@ -var run = function() { - bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - var networks = require('../networks'); - var WalletKey = bitcore.WalletKey; - var Builder = bitcore.TransactionBuilder; - var opts = { - network: networks.testnet - }; - - console.log('## Network: ' + opts.network.name); - - var input = {}; - input.addr = "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp"; - input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V"; - - // Complete with the corresponding UTXO you want to use - var utxos = [{ - address: input.addr, - txid: "39c71ebda371f75f4b854a720eaf9898b237facf3c2b101b58cd4383a44a6adc", - vout: 1, - ts: 1396288753, - scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac", - amount: 0.4296, - confirmations: 2 - }]; - - var privs = [ - "cP6JBHuQf7yqeqtdKRd22ibF3VehDv7G6BdzxSNABgrv3jFJUGoN", - "cQfRwF7XLSM5xGUpF8PZvob2MZyULvZPA2j5cat2RKDJrja7FtCZ", - "cUkYub4jtFVYymHh38yMMW36nJB4pXG5Pzd5QjResq79kAndkJcg", - "cMyBgowsyrJRufoKWob73rMQB1PBqDdwFt8z4TJ6APN2HkmX1Ttm", - "cN9yZCom6hAZpHtCp8ovE1zFa7RqDf3Cr4W6AwH2tp59Jjh9JcXu", - ]; - - var pubkeys = [] - privs.forEach(function(p) { - var wk = new WalletKey(opts); - wk.fromObj({ - priv: p - }); - pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public)); - }); - - - var outs = [{ - nreq: 3, - pubkeys: pubkeys, - amount: 0.05 - }]; - var tx = new Builder(opts) - .setUnspent(utxos) - .setOutputs(outs) - .sign([input.priv]) - .build(); - var txHex = tx.serialize().toString('hex'); - console.log('1) SEND TO MULSISIG TX: ', txHex); - console.log('[this example originally generated TXID: e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5 on testnet]\n\n\thttp://test.bitcore.io/tx/e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5\n\n'); - - - //save scriptPubKey - var scriptPubKey = tx.outs[0].s.toString('hex'); - - /* - * - * REDDEEM TX - */ - var utxos2 = [{ - address: input.addr, - txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5", - vout: 0, - ts: 1396288753, - scriptPubKey: scriptPubKey, - amount: 0.05, - confirmations: 2 - }]; - - outs = [{ - address: input.addr, - amount: 0.04 - }]; - var b = new Builder(opts) - .setUnspent(utxos2) - .setOutputs(outs) - .sign(privs); - - - tx = b.build(); - - - var txHex = tx.serialize().toString('hex'); - console.log('2) REDEEM SCRIPT: ', txHex); - console.log('=> Is signed status:', b.isFullySigned(), tx.countInputMissingSignatures(0)); - - console.log('[this example originally generated TXID: 1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83 on testnet]\n\n\thttp://test.bitcore.io/tx/1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83'); - -}; - -// This is just for browser & mocha compatibility -if (typeof module !== 'undefined') { - module.exports.run = run; - if (require.main === module) { - run(); - } -} else { - run(); -} - -//// diff --git a/examples/CreateAndSignTx-PayToPubkeyHash.js b/examples/CreateAndSignTx-PayToPubkeyHash.js deleted file mode 100644 index c719cd6ba..000000000 --- a/examples/CreateAndSignTx-PayToPubkeyHash.js +++ /dev/null @@ -1,73 +0,0 @@ -var run = function() { - bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - - var priv = 'cTgGUrcro89yUtKeG6gHBAS14r3qp25KwTTxG9d4kEzcFxecuZDm'; - var amt = '0.005'; - var toAddress = 'myuAQcCc1REUgXGsCTiYhZvPPc3XxZ36G1'; - var changeAddressString = 'moDz3jEo9q7CxjBDjmb13sL4SKkgo2AACE'; - - var utxos = [{ - address: "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ", - txid: "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", - vout: 1, - ts: 1394719301, - scriptPubKey: "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac", - amount: 0.01, - confirmations: 2 - }]; - - console.log('TX Data: BTC:' + amt + ' => ' + toAddress + ', change To:' + changeAddressString); - console.log('Unspends Outputs:', utxos); - - - var outs = [{ - address: toAddress, - amount: amt - }]; - var keys = [priv]; - var opts = { - remainderOut: { - address: changeAddressString - } - }; - var Builder = bitcore.TransactionBuilder; - - var tx = new Builder(opts) - .setUnspent(utxos) - .setOutputs(outs) - .sign(keys) - .build(); - - /* create and signing can be done in multiple steps using: - * - * var builder = new bitcore.TransactionBuilder(opts) - * .setUnspent(utxos) - * .setOutputs(outs); - * - * builder.sign(key1); - * builder.sign(key2); - * ... - * if (builder.isFullySigned()){ - * var tx = builder.build(); - * } - * - * The selected Unspent Outputs for the transaction can be retrieved with: - * - * var selectedUnspent = build.getSelectedUnspent(); - */ - - var txHex = tx.serialize().toString('hex'); - console.log('TX HEX IS: ', txHex); -}; - -// This is just for browser & mocha compatibility -if (typeof module !== 'undefined') { - module.exports.run = run; - if (require.main === module) { - run(); - } -} else { - run(); -} - -//// diff --git a/examples/CreateAndSignTx-PayToScriptHash.js b/examples/CreateAndSignTx-PayToScriptHash.js deleted file mode 100644 index c23414916..000000000 --- a/examples/CreateAndSignTx-PayToScriptHash.js +++ /dev/null @@ -1,151 +0,0 @@ -var run = function() { - bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - var networks = require('../networks'); - var WalletKey = bitcore.WalletKey; - var Script = bitcore.Script; - var Builder = bitcore.TransactionBuilder; - var opts = { - network: networks.testnet - }; - - console.log('## Network: ' + opts.network.name); - - var input = {}; - input.addr = "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp"; - input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V"; - - // Complete with the corresponding UTXO you want to use - var utxos = [{ - address: "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp", - txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5", - vout: 1, - ts: 1396290442, - scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac", - amount: 0.3795, - confirmations: 7 - }]; - - var privs = [ - "cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA", - "cVf32m9MR4vxcPwKNJuPepUe8XrHD2z63eCk76d6njRGyCkXpkSM", - "cQ2sVRFX4jQYMLhWyzz6jTQ2xju51P36968ecXnPhRLKLH677eKR", - "cSw7x9ERcmeWCU3yVBT6Nz7b9JiZ5yjUB7JMhBUv9UM7rSaDpwX9", - "cRQBM8qM4ZXJGP1De4D5RtJm7Q6FNWQSMx7YExxzgn2ehjM3haxW", - ]; - - var pubkeys = [] - privs.forEach(function(p) { - var wk = new WalletKey(opts); - wk.fromObj({ - priv: p - }); - pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public)); - }); - - // multisig p2sh - var opts = { - nreq: 3, - pubkeys: pubkeys - }; - - // p2scriphash p2sh - //var opts = [{address: an_address}]; - - var info = Builder.infoForP2sh(opts, 'testnet'); - var p2shScript = info.scriptBufHex; - var p2shAddress = info.address; - - - var outs = [{ - address: p2shAddress, - amount: 0.05 - }]; - var tx = new Builder(opts) - .setUnspent(utxos) - .setOutputs(outs) - .sign([input.priv]) - .build(); - - var txHex = tx.serialize().toString('hex'); - - - console.log('## p2sh address: ' + p2shAddress); //TODO - console.log('\n1) SEND TO P2SH TX: ', txHex); - console.log('[this example originally generated TXID: c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7 on testnet]\n\n\thttp://test.bitcore.io/tx/c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7\n\n'); - - //save scriptPubKey - var scriptPubKey = tx.outs[0].s.toString('hex'); - - /* - * - * REDDEEM TX - */ - var utxos2 = [{ - address: p2shAddress, - txid: "c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7", - vout: 0, - ts: 1396375187, - scriptPubKey: scriptPubKey, - amount: 0.05, - confirmations: 1 - }]; - - outs = [{ - address: input.addr, - amount: 0.04 - }]; - - var hashMap = {}; - hashMap[p2shAddress] = p2shScript; - - var b = new Builder(opts) - .setUnspent(utxos2) - .setHashToScriptMap(hashMap) - .setOutputs(outs) - .sign(privs); - - tx = b.build(); - - - console.log('Builder:'); - console.log('\tSignatures:' + tx.countInputMissingSignatures(0)); - console.log('\t#isFullySigned:' + b.isFullySigned()); - - console.log('TX:'); - console.log('\t #isComplete:' + tx.isComplete()); - - var txHex = tx.serialize().toString('hex'); - console.log('2) REDEEM SCRIPT: ', txHex); - console.log('[this example originally generated TXID: 8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7 on testnet]\n\n\thttp://test.bitcore.io/tx/8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7\n\n'); - - /* - // To send TX with RPC: - var RpcClient = bitcore.RpcClient; - var config = { - protocol: 'http', - user: 'user', - pass: 'pass', - host: '127.0.0.1', - port: '18332', - }; - var rpc = new RpcClient(config); - rpc.sendRawTransaction(txHex, function(err, ret) { - console.log('err', err); //TODO - console.log('ret', ret); //TODO - process.exit(-1); - }); -}; -*/ - -}; - - -// This is just for browser & mocha compatibility -if (typeof module !== 'undefined') { - module.exports.run = run; - if (require.main === module) { - run(); - } -} else { - run(); -} diff --git a/examples/CreateKey.js b/examples/CreateKey.js deleted file mode 100644 index eb7661af8..000000000 --- a/examples/CreateKey.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - - - -var run = function() { - // replace '../bitcore' with 'bitcore' if you use this code elsewhere. - var bitcore = require('../bitcore'); - var networks = require('../networks'); - var WalletKey = bitcore.WalletKey; - - var opts = { - network: networks.testnet - }; - - function print(wk) { - - console.log('\n## Network: ' + wk.network.name); - console.log('\t * Hex Representation'); - console.log('\tPrivate: ' + bitcore.buffertools.toHex(wk.privKey.private)); - console.log('\tPublic : ' + bitcore.buffertools.toHex(wk.privKey.public)); - console.log('\tPublic Compressed : ' + (wk.privKey.compressed ? 'Yes' : 'No')); - - var wkObj = wk.storeObj(); - console.log('\n\t * WalletKey Store Object'); - console.log('\tPrivate: ' + wkObj.priv); - console.log('\tPublic : ' + wkObj.pub); - console.log('\tAddr : ' + wkObj.addr); - }; - - //Generate a new one (compressed public key, compressed WIF flag) - var wk = new WalletKey(opts); - wk.generate(); - print(wk); - - //Generate from private Key WIF. Compressed status taken from WIF. - var wk2 = new WalletKey(opts); - wk2.fromObj({ - priv: 'cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA' - }); - print(wk2); - - -}; - -module.exports.run = run; -if (require.main === module) { - run(); -} diff --git a/examples/CreateScript.js b/examples/CreateScript.js deleted file mode 100644 index d4595c464..000000000 --- a/examples/CreateScript.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict'; - -var run = function() { - // replace '../bitcore' with 'bitcore' if you use this code elsewhere. - var bitcore = require('../bitcore'); - var networks = require('../networks'); - var Script = bitcore.Script; - var WalletKey = bitcore.WalletKey; - var buffertools = bitcore.buffertools; - var Address = bitcore.Address; - var util = bitcore.util; - var opts = { - network: networks.testnet - }; - - var p = console.log; - - var wk = new WalletKey(opts); - wk.generate(); - var wkObj = wk.storeObj(); - - var s = Script.createPubKeyOut(wk.privKey.public); - p('\nScript PubKey:'); - p('\tHex : ' + buffertools.toHex(s.buffer)); - p('\tHuman : ' + s.toHumanReadable()); - p('\tKey -------------------------------'); - console.log('\tPrivate: ' + wkObj.priv); - console.log('\tPublic : ' + wkObj.pub); - console.log('\tAddr : ' + wkObj.addr); - - s = Script.createPubKeyHashOut(wk.privKey.public); - p('\nScript PubKeyHash:'); - p('\tHex : ' + buffertools.toHex(s.buffer)); - p('\tHuman : ' + s.toHumanReadable()); - p('\tKey -------------------------------'); - console.log('\tPrivate: ' + wkObj.priv); - console.log('\tPublic : ' + wkObj.pub); - console.log('\tAddr : ' + wkObj.addr); - - var wks = []; - var pubs = []; - for (var i = 0; i < 5; i++) { - wks[i] = new WalletKey(opts); - wks[i].generate(); - pubs.push(wks[i].privKey.public); - } - - s = Script.createMultisig(3, pubs); - p('\nScript MultiSig (3 out of 5 required signatures):'); - p('\tHex : ' + buffertools.toHex(s.buffer)); - p('\tHuman : ' + s.toHumanReadable()); - - for (i = 0; i < 5; i++) { - wkObj = wks[i].storeObj(); - p('\tKey [' + i + '] -------------------------------'); - console.log('\tPrivate: ' + wkObj.priv); - console.log('\tPublic : ' + wkObj.pub); - console.log('\tAddr : ' + wkObj.addr); - } - - var hash = util.sha256ripe160(s.buffer); - - s = Script.createP2SH(hash); - p('\nScript P2SH:'); - p('\tHex : ' + buffertools.toHex(s.buffer)); - p('\tHuman : ' + s.toHumanReadable()); - p('\tScript Hash: ' + buffertools.toHex(hash)); - var a = new Address(networks.livenet.P2SHVersion, hash); - p('\tp2sh Addr: ' + a.toString()); - -}; - -module.exports.run = run; -if (require.main === module) { - run(); -} diff --git a/examples/ECIES.js b/examples/ECIES.js deleted file mode 100644 index ea38b688f..000000000 --- a/examples/ECIES.js +++ /dev/null @@ -1,30 +0,0 @@ -var run = function() { - bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - - console.log('ECIES: Elliptic Curve Integrated Encryption Scheme'); - console.log('A way of encrypting with a public key and decrypting with a private key.'); - - var key = bitcore.Key.generateSync(); - console.log('Private key: ' + key.private.toString('hex')); - console.log('Public key: ' + key.public.toString('hex')); - - var message = new Buffer('This is a message to be encrypted'); - console.log('Message: "' + message.toString() + '"'); - - var encrypted = bitcore.ECIES.encrypt(key.public, message); - console.log('Encrypted (with public key): ' + encrypted.toString('hex')); - - var decrypted = bitcore.ECIES.decrypt(key.private, encrypted); - console.log('Decrypted (with private key): "' + decrypted.toString() + '"'); -}; - - -// This is just for browser & mocha compatibility -if (typeof module !== 'undefined') { - module.exports.run = run; - if (require.main === module) { - run(); - } -} else { - run(); -} diff --git a/examples/ElectrumMPK.js b/examples/ElectrumMPK.js deleted file mode 100644 index c6bbb13a3..000000000 --- a/examples/ElectrumMPK.js +++ /dev/null @@ -1,11 +0,0 @@ -var Electrum = require('../lib/Electrum'); -var Address = require('../lib/Address'); - -var mpk = '92eea4d2f5263651db9e3222caded1fd4c89772f79a7c03fb6afc00e9d2c9d2ed9b86c2c95fc1171e49163079dacb7f048b3c509a27a490e1df9e7128362d468'; - -mpk = new Electrum(mpk); - -var key0 = mpk.generatePubKey(0); -var addr0 = Address.fromPubKey(key0); - -console.log(addr0.as('base58')); diff --git a/examples/HierarchicalKey.js b/examples/HierarchicalKey.js deleted file mode 100644 index 0a485fc37..000000000 --- a/examples/HierarchicalKey.js +++ /dev/null @@ -1,83 +0,0 @@ -var run = function() { - bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - var HierarchicalKey = bitcore.HierarchicalKey; - var Address = bitcore.Address; - var networks = bitcore.networks; - var coinUtil = bitcore.util; - var crypto = require('crypto'); - - console.log('HierarchicalKey: Hierarchical Deterministic Wallets (BIP32)'); - console.log('https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n'); - console.log('1) Make new hkey from randomly generated new seed'); - - var randomBytes = crypto.randomBytes(32); - var hkey = HierarchicalKey.seed(randomBytes); - console.log('master extended private key: ' + hkey.extendedPrivateKeyString()); - console.log('master extended public key: ' + hkey.extendedPublicKeyString()); - console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString()); - console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString()); - console.log(); - - console.log('2) Make new hkey from known seed'); - var knownBytes = coinUtil.sha256('do not use this password as a brain wallet'); - var hkey = HierarchicalKey.seed(knownBytes); - console.log('master extended private key: ' + hkey.extendedPrivateKeyString()); - console.log('master extended public key: ' + hkey.extendedPublicKeyString()); - console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString()); - console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString()); - console.log(); - - console.log('3) Make new hkey from known master private key'); - var knownMasterPrivateKey = 'xprv9s21ZrQH143K2LvayFZWVVTomiDKheKWvnupDB8fmjKwxkKG47uvzmFa3vCXoy9fxPJhRYsU19apVfexvMeLpJQuF2XtX1zRF3eao9GqqaQ'; - var hkey = new HierarchicalKey(knownMasterPrivateKey); - console.log('master extended private key: ' + hkey.extendedPrivateKeyString()); - console.log('master extended public key: ' + hkey.extendedPublicKeyString()); - console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString()); - console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString()); - console.log(); - - console.log('4) Make new hkey from known master public key'); - var knownMasterPublicKey = 'xpub661MyMwAqRbcGpiFufipqsKKBG1NHNwfJKishAEFNqJ6ryLcKeKyFNEZces7gMWd4XGg4uUhXy8DS64o1oPGUECVHeLq957Txjwagxt475H'; - var hkey = new HierarchicalKey(knownMasterPublicKey); - console.log('master extended private key: cannot derive'); - console.log('master extended public key: ' + hkey.extendedPublicKeyString()); - console.log('m/0/3/5 extended private key: cannot derive'); - console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString()); - console.log(); - - console.log('5) Make new hkey from known derived public key'); - var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3'; - var hkey = new HierarchicalKey(knownPublicKey); - console.log('master extended private key: cannot derive'); - console.log('master extended public key: ' + hkey.extendedPublicKeyString()); - console.log('m/0/3/5 extended private key: cannot derive'); - console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString()); - console.log(); - - console.log('6) Make a bunch of new addresses from known public key'); - var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3'; - var hkey = new HierarchicalKey(knownPublicKey); - console.log('m/0 address: ' + Address.fromPubKey(hkey.derive('m/0').eckey.public).toString()); - //console.log('m/1 extended public key: ' + hkey.derive('m/1').extendedPublicKeyString()); - console.log('m/1 address: ' + Address.fromPubKey(hkey.derive('m/1').eckey.public).toString()); - //console.log('m/2 extended public key: ' + hkey.derive('m/2').extendedPublicKeyString()); - console.log('m/2 address: ' + Address.fromPubKey(hkey.derive('m/2').eckey.public).toString()); - //console.log('m/3 extended public key: ' + hkey.derive('m/3').extendedPublicKeyString()); - console.log('m/3 address: ' + Address.fromPubKey(hkey.derive('m/3').eckey.public).toString()); - console.log('...'); - //console.log('m/100 extended public key: ' + hkey.derive('m/100').extendedPublicKeyString()); - console.log('m/100 address: ' + Address.fromPubKey(hkey.derive('m/100').eckey.public).toString()); - console.log(); - -}; - - -// This is just for browser & mocha compatibility -if (typeof module !== 'undefined') { - module.exports.run = run; - if (require.main === module) { - run(); - } -} else { - run(); -} diff --git a/examples/NetworkMonitor.js b/examples/NetworkMonitor.js deleted file mode 100644 index d61aecb8f..000000000 --- a/examples/NetworkMonitor.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -var run = function() { - // Replace '../bitcore' with 'bitcore' if you use this code elsewhere. - var bitcore = require('../bitcore'); - var NetworkMonitor = bitcore.NetworkMonitor; - - var config = { - networkName: 'testnet', - host: 'localhost', - port: 18333 - }; - - - var nm = new NetworkMonitor.create(config); - // monitor incoming transactions to http://tpfaucet.appspot.com/ donation address - nm.incoming('msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', function(tx) { - console.log('Donation to tpfaucet! '+JSON.stringify(tx.getStandardizedObject())); - }); - - // connect to bitcoin network and start listening - nm.start(); - -}; - -module.exports.run = run; -if (require.main === module) { - run(); -} diff --git a/examples/Opreturn.js b/examples/Opreturn.js deleted file mode 100644 index 66ce779fd..000000000 --- a/examples/Opreturn.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -var run = function() { - // Replace '../bitcore' with 'bitcore' if you use this code elsewhere. - var bitcore = require('../bitcore'); - var Address = bitcore.Address; - var coinUtil = bitcore.util; - var Script = bitcore.Script; - var network = bitcore.networks.testnet; - - var script = 'OP_RETURN 58434c524e4748530000000000000000000000010000000005f5e100'; - var s = Script.fromHumanReadable(script); - var result = (s.classify() == Script.TX_RETURN) - console.log("Is op_return:", result); -}; - -module.exports.run = run; -if (require.main === module) { - run(); -} diff --git a/examples/PayPro/README.md b/examples/PayPro/README.md deleted file mode 100644 index 0c5487bc1..000000000 --- a/examples/PayPro/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Running the Payment Protocol Demo - -## Node - -The node payment protocol demonstration will run automatically via: - -``` bash -$ node examples/PayPro -``` - -You will see the server and customer logs output in the terminal. - -## Browser - -To run our payment protocol demonstration in the browser, you may run: - -``` bash -$ node examples/PayPro/server.js -b -p 8080 -``` - -This will start the payment protocol demonstration server in browser mode, -which serves outputs in the payment protocol request (don't worry, it doesn't -ask for *too* many testnet coins). - -Once the server is started, you can visit it in your browser: - -``` bash -$ chromium https://localhost:8080/ -``` - -You will see a simple checkout page to buy some imaginary products. Once you -press checkout, you will see all the server and client logs in the browser as -well as the terminal. - -If you're connected to enough peers, your transaction will be broadcast -throughout the bitcoin testnet network and hopefully ACKed by your peers. - -## Logs - -Your logs may ultimately look something like this: - -``` -Customer: Our payment was acknowledged! -Customer: Message from Merchant: Thank you for your payment! -Customer: Payment sent successfully. -``` - -## Changing the server address contained in outputs - -If you want to alter the address or public key the testnet coins get sent to by -the payment server, you can pass in the `--pubkey` or `--address` options. -`address` has to be a testnet address, whereas `pubkey` is a hex encoded public -key. The `--privkey` option is also available in the standard bitcoind privkey -format. - -## Other Options - -If you you're not connected to enough peers to broadcast your transaction (by -default, this example only connects to the core seed peers), you can enable -peer discovery in bitcore by passing the `--discovery` (`-d`) argument onto the -server command line. - -If you don't want to actually broadcast your transaction and want to keep your -testnet coins, you can pass `--no-tx` on the server command line. - -If you don't want the tests to run automatically and simply host the payment -server, simply pass `--browser` (`-b`) as mentioned above. - -## Using the example in a modular manner - -``` js -var server = require('bitcore/examples/PayPro'); -server.listen(8080); -``` diff --git a/examples/PayPro/bitcore.js b/examples/PayPro/bitcore.js deleted file mode 120000 index af56eb816..000000000 --- a/examples/PayPro/bitcore.js +++ /dev/null @@ -1 +0,0 @@ -../../browser/bundle.js \ No newline at end of file diff --git a/examples/PayPro/customer.js b/examples/PayPro/customer.js deleted file mode 100644 index 61fe763d8..000000000 --- a/examples/PayPro/customer.js +++ /dev/null @@ -1,515 +0,0 @@ -/** - * Payment-Customer - A Payment Protocol demonstration. - * This file will run in node or the browser. - * Copyright (c) 2014, BitPay - * https://github.com/bitpay/bitcore - */ - -;(function() { - -/** - * Global - */ - -var window = this; -var global = this; - -/** - * Platform - */ - -var isNode = !!(typeof process === 'object' && process && process.versions.node); - -// Disable strictSSL -if (isNode) { - process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; -} - -/** - * Dependencies - */ - -var bitcore = isNode - ? require('../../') - : require('bitcore'); -var PayPro = bitcore.PayPro; -var Transaction = bitcore.Transaction; -var TransactionBuilder = bitcore.TransactionBuilder; - -/** - * Variables - */ - -var port = 8080; - -if (isNode) { - var argv = require('optimist').argv; - if (argv.p || argv.port) { - port = +argv.p || +argv.port; - } -} else { - port = +window.location.port || 443; -} - -var merchant = isNode - ? parseMerchantURI(argv.m || argv.u || argv._[0]) - : parseMerchantURI(window.merchantURI); - -/** - * Send Payment - */ - -if (isNode) { - var Buffer = global.Buffer; -} else { - var Buffer = bitcore.Buffer; -} - -function request(options, callback) { - if (typeof options === 'string') { - options = { uri: options }; - } - - options.method = options.method || 'GET'; - options.headers = options.headers || {}; - - if (!isNode) { - var xhr = new XMLHttpRequest(); - xhr.open(options.method, options.uri, true); - - Object.keys(options.headers).forEach(function(key) { - var val = options.headers[key]; - if (key === 'Content-Length') return; - if (key === 'Content-Transfer-Encoding') return; - xhr.setRequestHeader(key, val); - }); - - // For older browsers: - // xhr.overrideMimeType('text/plain; charset=x-user-defined'); - - // Newer browsers: - xhr.responseType = 'arraybuffer'; - - xhr.onload = function(event) { - var response = xhr.response; - var buf = new Uint8Array(response); - return callback(null, xhr, buf); - }; - - if (options.body) { - xhr.send(options.body); - } else { - xhr.send(null); - } - - return; - } - - return require('request')(options, callback); -} - -function sendPayment(msg, callback) { - if (arguments.length === 1) { - callback = msg; - msg = null; - } - - return request({ - method: 'GET', - uri: 'https://localhost:' + port + '/-/request', - headers: { - 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE - + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE, - 'Content-Type': 'application/octet-stream', - 'Content-Length': 0 - }, - encoding: null - }, function(err, res, body) { - if (err) return callback(err); - - body = PayPro.PaymentRequest.decode(body); - - var pr = new PayPro(); - pr = pr.makePaymentRequest(body); - - var ver = pr.get('payment_details_version'); - var pki_type = pr.get('pki_type'); - var pki_data = pr.get('pki_data'); - var details = pr.get('serialized_payment_details'); - var sig = pr.get('signature'); - - // Verify Signature - var verified = pr.verify(); - - if (!verified) { - return callback(new Error('Server sent a bad signature.')); - } - - details = PayPro.PaymentDetails.decode(details); - var pd = new PayPro(); - pd = pd.makePaymentDetails(details); - var network = pd.get('network'); - var outputs = pd.get('outputs'); - var time = pd.get('time'); - var expires = pd.get('expires'); - var memo = pd.get('memo'); - var payment_url = pd.get('payment_url'); - var merchant_data = pd.get('merchant_data'); - - print('You are currently on this BTC network:'); - print(network); - print('The server sent you a message:'); - print(memo); - - var refund_outputs = []; - - var rpo = new PayPro(); - rpo = rpo.makeOutput(); - rpo.set('amount', 0); - rpo.set('script', new Buffer([ - 118, // OP_DUP - 169, // OP_HASH160 - 76, // OP_PUSHDATA1 - 20, // number of bytes - 0xcf, - 0xbe, - 0x41, - 0xf4, - 0xa5, - 0x18, - 0xed, - 0xc2, - 0x5a, - 0xf7, - 0x1b, - 0xaf, - 0xc7, - 0x2f, - 0xb6, - 0x1b, - 0xfc, - 0xfc, - 0x4f, - 0xcd, - 136, // OP_EQUALVERIFY - 172 // OP_CHECKSIG - ])); - - refund_outputs.push(rpo.message); - - // We send this to the serve after receiving a PaymentRequest - var pay = new PayPro(); - pay = pay.makePayment(); - pay.set('merchant_data', merchant_data); - pay.set('transactions', [createTX(outputs)]); - pay.set('refund_to', refund_outputs); - - msg = msg || 'Hi server, I would like to give you some money.'; - - if (isNode && argv.memo) { - msg = argv.memo; - } - - pay.set('memo', msg); - pay = pay.serialize(); - - return request({ - method: 'POST', - uri: payment_url, - headers: { - // BIP-71 - 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE - + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE, - 'Content-Type': PayPro.PAYMENT_CONTENT_TYPE, - 'Content-Length': pay.length + '', - 'Content-Transfer-Encoding': 'binary' - }, - body: pay, - encoding: null - }, function(err, res, body) { - if (err) return callback(err); - body = PayPro.PaymentACK.decode(body); - var ack = new PayPro(); - ack = ack.makePaymentACK(body); - var payment = ack.get('payment'); - var memo = ack.get('memo'); - print('Our payment was acknowledged!'); - print('Message from Merchant: %s', memo); - payment = PayPro.Payment.decode(payment); - var pay = new PayPro(); - payment = pay.makePayment(payment); - print(payment); - var tx = payment.message.transactions[0]; - if (tx.buffer) { - tx.buffer = tx.buffer.slice(tx.offset, tx.limit); - var ptx = new bitcore.Transaction(); - - var parser = new bitcore.BinaryParser(tx.buffer); - ptx.parse(parser); - // ptx.parse(tx.buffer); - - tx = ptx; - } - var txid = tx.getHash().toString('hex'); - print('First payment txid: %s', txid); - return callback(); - }); - }); -} - -/** - * Helpers - */ - -// URI Spec -// A backwards-compatible request: -// bitcoin:mq7se9wy2egettFxPbmn99cK8v5AFq55Lx?amount=0.11&r=https://merchant.com/pay.php?h%3D2a8628fc2fbe -// Non-backwards-compatible equivalent: -// bitcoin:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe -function parseMerchantURI(uri) { - uri = uri || 'bitcoin:?r=https://localhost:' + port + '/-/request'; - var query, id; - if (uri.indexOf('bitcoin:') !== 0) { - throw new Error('Not a Bitcoin URI.'); - } - if (~uri.indexOf(':?')) { - query = uri.split(':?')[1]; - } else { - // Legacy URI - uri = uri.substring('bitcoin:'.length); - uri = uri.split('?'); - id = uri[0]; - query = uri[1]; - } - query = parseQS(query); - if (!query.r) { - throw new Error('No uri.'); - } - if (id) { - query.id = id; - } - return query; -} - -function parseQS(query) { - var out = {}; - var parts = query.split('&'); - parts.forEach(function(part) { - var parts = part.split('='); - var key = parts[0]; - var value = parts[1]; - out[key] = value; - }); - return out; -} - -function createTX(outputs) { - // Addresses - var addrs = [ - 'mzTQ66VKcybz9BD1LAqEwMFp9NrBGS82sY', - 'mmu9k3KzsDMEm9JxmJmZaLhovAoRKW3zr4', - 'myqss64GNZuWuFyg5LTaoTCyWEpKH56Fgz' - ]; - - // Private keys in WIF format (see TransactionBuilder.js for other options) - var keys = [ - 'cVvr5YmWVAkVeZWAawd2djwXM4QvNuwMdCw1vFQZBM1SPFrtE8W8', - 'cPyx1hXbe3cGQcHZbW3GNSshCYZCriidQ7afR2EBsV6ReiYhSkNF' - // 'cUB9quDzq1Bj7pocenmofzNQnb1wJNZ5V3cua6pWKzNL1eQtaDqQ' - ]; - - var unspent = [{ - // http://blockexplorer.com/testnet/rawtx/1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22 - 'txid': '1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22', - 'vout': 1, - 'address': addrs[0], - 'scriptPubKey': '76a94c14cfbe41f4a518edc25af71bafc72fb61bfcfc4fcd88ac', - 'amount': 1.60000000, - 'confirmations': 9 - }, - - { - // http://blockexplorer.com/testnet/rawtx/0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804 - 'txid': '0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804', - 'vout': 1, - 'address': addrs[1], - 'scriptPubKey': '76a94c14460376539c219c5e3274d86f16b40e806b37817688ac', - 'amount': 1.60000000, - 'confirmations': 9 - }]; - - // set change address - var opts = { - remainderOut: { - address: addrs[0] - } - }; - - var outs = []; - outputs.forEach(function(output) { - var amount = output.get('amount'); - var script = { - offset: output.get('script').offset, - limit: output.get('script').limit, - buffer: new Buffer(new Uint8Array( - output.get('script').buffer)) - }; - - // big endian - var v = new Buffer(8); - v[0] = (amount.high >> 24) & 0xff; - v[1] = (amount.high >> 16) & 0xff; - v[2] = (amount.high >> 8) & 0xff; - v[3] = (amount.high >> 0) & 0xff; - v[4] = (amount.low >> 24) & 0xff; - v[5] = (amount.low >> 16) & 0xff; - v[6] = (amount.low >> 8) & 0xff; - v[7] = (amount.low >> 0) & 0xff; - - var s = script.buffer.slice(script.offset, script.limit); - var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), 'testnet'); - - outs.push({ - address: addr.toString(), - amountSatStr: bitcore.Bignum.fromBuffer(v, { - // XXX for some reason, endian is ALWAYS 'big' - // in node (in the browser it behaves correctly) - endian: 'big', - size: 1 - }).toString(10) - }); - }); - - var b = new bitcore.TransactionBuilder(opts) - .setUnspent(unspent) - .setOutputs(outs); - - outputs.forEach(function(output, i) { - var script = { - offset: output.get('script').offset, - limit: output.get('script').limit, - buffer: new Buffer(new Uint8Array( - output.get('script').buffer)) - }; - var s = script.buffer.slice(script.offset, script.limit); - b.tx.outs[i].s = s; - }); - - b = b.sign(keys); - - var tx = b.build(); - - print(''); - print('Customer created transaction:'); - print(tx.getStandardizedObject()); - print(''); - - return tx.serialize(); -} - -/** - * Helpers - */ - -function clientLog(args, isError) { - var log = document.getElementById('log'); - var msg = args[0]; - if (typeof msg !== 'string') { - msg = JSON.stringify(msg, null, 2); - if (isError) msg = '' + msg + ''; - log.innerHTML += msg + '\n'; - return; - } - var i = 0; - msg = msg.replace(/%[sdji]/g, function(ch) { - i++; - if (ch === 'j' || typeof args[i] !== 'string') { - return JSON.stringify(args[i]); - } - return args[i]; - }); - if (isError) msg = '' + msg + ''; - log.innerHTML += msg + '\n'; -} - -function print() { - var args = Array.prototype.slice.call(arguments); - if (!isNode) { - return clientLog(args, false); - } - var util = require('util'); - if (typeof args[0] !== 'string') { - args[0] = util.inspect(args[0], null, 20, true); - console.log('\x1b[32mCustomer:\x1b[m'); - console.log(args[0]); - return; - } - if (!args[0]) return process.stdout.write('\n'); - var msg = '\x1b[32mCustomer:\x1b[m ' - + util.format.apply(util.format, args); - return process.stdout.write(msg + '\n'); -} - -function error() { - var args = Array.prototype.slice.call(arguments); - if (!isNode) { - return clientLog(args, true); - } - var util = require('util'); - if (typeof args[0] !== 'string') { - args[0] = util.inspect(args[0], null, 20, true); - console.log('\x1b[32mCustomer:\x1b[m'); - console.log(args[0]); - return; - } - if (!args[0]) return process.stderr.write('\n'); - var msg = '\x1b[32mCustomer:\x1b[m \x1b[31m' - + util.format.apply(util.format, args) + '\x1b[m'; - return process.stderr.write(msg + '\n'); -} - -/** - * Execute - */ - -if (isNode) { - if (!module.parent) { - sendPayment(function(err) { - if (err) return error(err.message); - print('Payment sent successfully.'); - }); - } else { - var customer = sendPayment; - customer.sendPayment = sendPayment; - customer.print = print; - customer.error = error; - module.exports = customer; - } -} else { - var customer = sendPayment; - customer.sendPayment = sendPayment; - customer.print = print; - customer.error = error; - window.customer = window.sendPayment = customer; - window.onload = function() { - var form = document.getElementsByTagName('form')[0]; - var memo = document.querySelector('input[name="memo"]'); - var loader = document.getElementById('load'); - loader.style.display = 'none'; - form.onsubmit = function() { - form.style.display = 'none'; - loader.style.display = 'block'; - form.onsubmit = function() { return false; }; - customer.sendPayment(memo.value || null, function(err) { - loader.style.display = 'none'; - if (err) return error(err.message); - print('Payment sent successfully.'); - }); - return false; - }; - }; -} - -}).call(function() { - return this || (typeof window !== 'undefined' ? window : global); -}()); diff --git a/examples/PayPro/index.html b/examples/PayPro/index.html deleted file mode 100644 index 490529257..000000000 --- a/examples/PayPro/index.html +++ /dev/null @@ -1,28 +0,0 @@ - -Payment Protocol - - -

Payment Protocol

- -

- BIP-70 - is here! -

- -
-
    -
  • BitPay T-Shirt: 0.00002000 BTC
  • -
  • BitPay Mug: 0.00001000 BTC
  • -
-

These items will cost you a total of 0.00003000 BTC.

-

Would you like to checkout?

- - -
- -

Loading...

- -

-
-
-
diff --git a/examples/PayPro/index.js b/examples/PayPro/index.js
deleted file mode 100755
index bfbc85d64..000000000
--- a/examples/PayPro/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env node
-
-module.exports = require('./server');
diff --git a/examples/PayPro/server.js b/examples/PayPro/server.js
deleted file mode 100755
index a13381841..000000000
--- a/examples/PayPro/server.js
+++ /dev/null
@@ -1,438 +0,0 @@
-#!/bin/bash
-
-/**
- * Payment-Server - A Payment Protocol demonstration.
- * Copyright (c) 2014, BitPay
- * https://github.com/bitpay/bitcore
- */
-
-/**
- * Modules
- */
-
-var https = require('https');
-var fs = require('fs');
-var path = require('path');
-var qs = require('querystring');
-var crypto = require('crypto');
-var assert = require('assert');
-
-// Disable strictSSL
-process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
-
-/**
- * Dependencies
- */
-
-var argv = require('optimist').argv;
-var express = require('express');
-var bitcore = require('../../');
-
-var PayPro = bitcore.PayPro;
-var Transaction = bitcore.Transaction;
-var TransactionBuilder = bitcore.TransactionBuilder;
-
-/**
- * Variables
- */
-
-var x509 = {
-  priv: fs.readFileSync(__dirname + '/../../test/data/x509.key'),
-  pub: fs.readFileSync(__dirname + '/../../test/data/x509.pub'),
-  der: fs.readFileSync(__dirname + '/../../test/data/x509.der'),
-  pem: fs.readFileSync(__dirname + '/../../test/data/x509.crt')
-};
-
-var server = https.createServer({
-  key: fs.readFileSync(__dirname + '/../../test/data/x509.key'),
-  cert: fs.readFileSync(__dirname + '/../../test/data/x509.crt')
-});
-
-server.options = argv;
-
-server.setOptions = function(options) {
-  server.options = argv = options;
-};
-
-var app = express();
-
-/**
- * Ignore Cache Headers
- * Allow CORS
- * Accept Payments
- */
-
-app.use(function(req, res, next) {
-  var setHeader = res.setHeader;
-
-  res.setHeader = function(name) {
-    switch (name) {
-      case 'Cache-Control':
-      case 'Last-Modified':
-      case 'ETag':
-        return;
-    }
-    return setHeader.apply(res, arguments);
-  };
-
-  res.setHeader('Access-Control-Allow-Origin', '*');
-  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
-  res.setHeader('Access-Control-Allow-Headers', [
-    'Host',
-    'Connection',
-    'Content-Length',
-    'Accept',
-    'Origin',
-    'User-Agent',
-    'Content-Type',
-    'Accept-Encoding',
-    'Accept-Language'
-  ].join(','));
-
-  res.setHeader('Accept', PayPro.PAYMENT_CONTENT_TYPE);
-
-  return next();
-});
-
-/**
- * Body Parser
- */
-
-app.use('/-/pay', function(req, res, next) {
-  var buf = [];
-
-  req.on('error', function(err) {
-    error('Request Error: %s', err.message);
-    try {
-      req.socket.destroy();
-    } catch (e) {
-      ;
-    }
-  });
-
-  req.on('data', function(data) {
-    buf.push(data);
-  });
-
-  req.on('end', function(data) {
-    if (data) buf.push(data);
-    buf = Buffer.concat(buf, buf.length);
-    req.paymentData = buf;
-    return next();
-  })
-});
-
-/**
- * Router
- */
-
-// Not used in express 4.x
-// app.use(app.router);
-
-/**
- * Receive "I want to pay"
- */
-
-app.uid = 0;
-
-app.get('/-/request', function(req, res, next) {
-  print('Received payment "request" from %s.', req.socket.remoteAddress);
-
-  var outputs = [];
-
-  [2000, 1000, 10000].forEach(function(value) {
-    var po = new PayPro();
-    po = po.makeOutput();
-
-    // number of satoshis to be paid
-    po.set('amount', value);
-
-    // a TxOut script where the payment should be sent. similar to OP_CHECKSIG
-
-    // Instead of creating it ourselves:
-    // if (!argv.pubkey && !argv.privkey && !argv.address) {
-    //   //argv.pubkey = '3730febcba04bad0cd476cfb820f9c37d7466fd9';
-    //   argv.pubkey = 'd96f46d7379c0f82fb6c47cdd0ba04babcfe3037'
-    // }
-
-    if (argv.pubkey || argv.privkey || argv.address) {
-      var pubKey;
-      if (argv.pubkey) {
-        pubKey = new Buffer(argv.pubkey, 'hex');
-      } else if (argv.privkey) {
-        pubKey = bitcore.Key.recoverPubKey(new Buffer(argv.privkey)).toCompressedPubKey();
-      } else if (argv.address) {
-        pubKey = bitcore.Base58Check.decode(new Buffer(argv.address));
-      }
-      var address = bitcore.Address.fromPubKey(pubKey, 'testnet');
-      var scriptPubKey = address.getScriptPubKey();
-      assert.equal(scriptPubKey.isPubkeyHash(), true);
-      po.set('script', scriptPubKey.getBuffer());
-    } else {
-      po.set('script', new Buffer([
-        118, // OP_DUP
-        169, // OP_HASH160
-        76,  // OP_PUSHDATA1
-        20,  // number of bytes
-        55,
-        48,
-        254,
-        188,
-        186,
-        4,
-        186,
-        208,
-        205,
-        71,
-        108,
-        251,
-        130,
-        15,
-        156,
-        55,
-        215,
-        70,
-        111,
-        217,
-        136, // OP_EQUALVERIFY
-        172  // OP_CHECKSIG
-      ]));
-    }
-
-    outputs.push(po.message);
-  });
-
-  /**
-   * Payment Details
-   */
-
-  var mdata = new Buffer([0]);
-  app.uid++;
-  if (app.uid > 0xffff) {
-    throw new Error('UIDs bigger than 0xffff not supported.');
-  } else if (app.uid > 0xff) {
-    mdata = new Buffer([(app.uid >> 8) & 0xff, (app.uid >> 0) & 0xff])
-  } else {
-    mdata = new Buffer([0, app.uid])
-  }
-  var now = Date.now() / 1000 | 0;
-  var pd = new PayPro();
-  pd = pd.makePaymentDetails();
-  pd.set('network', 'test');
-  pd.set('outputs', outputs);
-  pd.set('time', now);
-  pd.set('expires', now + 60 * 60 * 24);
-  pd.set('memo', 'Hello, this is the server, we would like some money.');
-  var port = +req.headers.host.split(':')[1] || server.port;
-  pd.set('payment_url', 'https://localhost:' + port + '/-/pay');
-  pd.set('merchant_data', mdata);
-
-  /*
-   * PaymentRequest
-   */
-
-  var cr = new PayPro();
-  cr = cr.makeX509Certificates();
-  cr.set('certificate', [x509.der]);
-
-  // We send the PaymentRequest to the customer
-  var pr = new PayPro();
-  pr = pr.makePaymentRequest();
-  pr.set('payment_details_version', 1);
-  pr.set('pki_type', 'x509+sha256');
-  pr.set('pki_data', cr.serialize());
-  pr.set('serialized_payment_details', pd.serialize());
-  pr.sign(x509.priv);
-
-  pr = pr.serialize();
-
-  // BIP-71 - set the content-type
-  res.setHeader('Content-Type', PayPro.PAYMENT_REQUEST_CONTENT_TYPE);
-  res.setHeader('Content-Length', pr.length + '');
-  res.setHeader('Content-Transfer-Encoding', 'binary');
-
-  res.send(pr);
-});
-
-/**
- * Receive Payment
- */
-
-app.post('/-/pay', function(req, res, next) {
-  var body = req.paymentData;
-
-  print('Received Payment Message Body:');
-  print(body.toString('hex'));
-
-  body = PayPro.Payment.decode(body);
-
-  var pay = new PayPro();
-  pay = pay.makePayment(body);
-  var merchant_data = pay.get('merchant_data');
-  var transactions = pay.get('transactions');
-  var refund_to = pay.get('refund_to');
-  var memo = pay.get('memo');
-
-  print('Received Payment from %s.', req.socket.remoteAddress);
-  print('Customer Message: %s', memo);
-  print('Payment Message:');
-  print(pay);
-
-  // We send this to the customer after receiving a Payment
-  // Then we propogate the transaction through bitcoin network
-  var ack = new PayPro();
-  ack = ack.makePaymentACK();
-  ack.set('payment', pay.message);
-  ack.set('memo', 'Thank you for your payment!');
-
-  ack = ack.serialize();
-
-  // BIP-71 - set the content-type
-  res.setHeader('Content-Type', PayPro.PAYMENT_ACK_CONTENT_TYPE);
-  res.setHeader('Content-Length', ack.length + '');
-  res.setHeader('Content-Transfer-Encoding', 'binary');
-
-  transactions = transactions.map(function(tx) {
-    tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
-    var ptx = new bitcore.Transaction();
-    ptx.parse(tx.buffer);
-    return ptx;
-  });
-
-  if (!argv['no-tx']) {
-    (function retry() {
-      var timeout = setTimeout(function() {
-        if (conn) {
-          transactions.forEach(function(tx) {
-            var id = tx.getHash().toString('hex');
-            print('');
-            print('Sending transaction with txid: %s', id);
-            print(tx.getStandardizedObject());
-
-            print('Broadcasting transaction...');
-
-            var pending = 1;
-            peerman.on('ack', function listener() {
-              if (!--pending) {
-                peerman.removeListener('ack', listener);
-                clearTimeout(timeout);
-                print('Transaction sent to peer successfully.');
-                res.send(ack);
-              }
-            });
-            conn.sendTx(tx);
-          });
-        } else {
-          print('No BTC network connection. Retrying...');
-          conn = peerman.getActiveConnection();
-          retry();
-        }
-      }, 1000);
-    })();
-  } else {
-    print('Broadcasting transaction...');
-    res.send(ack);
-  }
-});
-
-/**
- * Bitcoin
- */
-
-var conn;
-
-var peerman = new bitcore.PeerManager({
-  network: 'testnet'
-});
-
-peerman.peerDiscovery = argv.d || argv.discovery || false;
-
-peerman.addPeer(new bitcore.Peer('testnet-seed.alexykot.me', 18333));
-peerman.addPeer(new bitcore.Peer('testnet-seed.bitcoin.petertodd.org', 18333));
-peerman.addPeer(new bitcore.Peer('testnet-seed.bluematt.me', 18333));
-
-peerman.on('connect', function() {
-  conn = peerman.getActiveConnection();
-});
-
-peerman.start();
-
-/**
- * File Access
- */
-
-app.use(express.static(__dirname));
-
-/**
- * Helpers
- */
-
-var log = require('../../util/log');
-
-log.err = error;
-log.debug = error;
-log.info = print;
-
-var util = require('util');
-
-function print() {
-  var args = Array.prototype.slice.call(arguments);
-  if (typeof args[0] !== 'string') {
-    args[0] = util.inspect(args[0], null, 20, true);
-    console.log('\x1b[34mServer:\x1b[m');
-    console.log(args[0]);
-    return;
-  }
-  if (!args[0]) return process.stdout.write('\n');
-  var msg = '\x1b[34mServer:\x1b[m '
-    + util.format.apply(util.format, args);
-  return process.stdout.write(msg + '\n');
-}
-
-function error() {
-  var args = Array.prototype.slice.call(arguments);
-  if (typeof args[0] !== 'string') {
-    args[0] = util.inspect(args[0], null, 20, true);
-    console.log('\x1b[34mServer:\x1b[m');
-    console.log(args[0]);
-    return;
-  }
-  if (!args[0]) return process.stderr.write('\n');
-  var msg = '\x1b[34mServer:\x1b[m \x1b[31m'
-    + util.format.apply(util.format, args)
-    + '\x1b[m';
-  return process.stderr.write(msg + '\n');
-}
-
-/**
- * Start Server
- */
-
-server.on('request', app);
-server.app = app;
-server.port = 8080;
-server.isNode = true;
-
-setTimeout(function() {
-  server.port = argv.p = argv.port = +argv.p || +argv.port || 8080;
-  server.isNode = !argv.b && !argv.browser;
-  if (argv.s || argv.server || argv.l || argv.listen) {
-    server.listen(server.port, function(addr) {
-      print('Listening on port %s.', server.port);
-    });
-    return;
-  }
-  if (!module.parent || path.basename(module.parent.filename) === 'index.js') {
-    server.listen(server.port, function(addr) {
-      print('Listening on port %s.', server.port);
-      if (!server.isNode) return;
-      var customer = require('./customer');
-      customer.sendPayment(function(err) {
-        if (err) return error(err.message);
-        customer.print('Payment sent successfully.');
-      });
-    });
-  }
-}, 1);
-
-module.exports = server;
diff --git a/examples/PayPro/style.css b/examples/PayPro/style.css
deleted file mode 100644
index 0d5a08049..000000000
--- a/examples/PayPro/style.css
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Stylesheet for Payment Protocol
- */
-
-/**
- * Raleway
- */
-
-@font-face {
-  font-family: 'Raleway';
-  font-style: normal;
-  font-weight: 400;
-  src: local('Raleway'), url(http://themes.googleusercontent.com/static/fonts/raleway/v7/cIFypx4yrWPDz3zOxk7hIQLUuEpTyoUstqEm5AMlJo4.woff) format('woff');
-}
-
-/**
- * Ubuntu
- */
-
-@font-face {
-  font-family: 'Ubuntu';
-  font-style: normal;
-  font-weight: 400;
-  src: local('Ubuntu'), url(https://themes.googleusercontent.com/static/fonts/ubuntu/v5/lhhB5ZCwEkBRbHMSnYuKyA.ttf) format('truetype');
-}
-
-article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary {
-	display: block
-}
-
-html {
-  width: 840px;
-  font-family: "Raleway", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Helvetica", "Verdana", sans-serif;
-  font-size: 22px;
-  line-height: 30px;
-  -webkit-font-smoothing: antialiased;
-  text-rendering: optimizeLegibility;
-  color: #000;
-  background-image: -webkit-gradient( linear, 0 0, 0 100%, color-stop(0, rgba(0, 0, 0, 0.15)), color-stop(0.2, transparent), color-stop(0.8, transparent), color-stop(1, rgba(0, 0, 0, 0.15)));
-  background-image: -moz-linear-gradient( -90deg, rgba(0, 0, 0, 0.15) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.15) 100%);
-  background-attachment: fixed;
-  background-color: #c1d3e3;
-}
-
-input {
-  display: block;
-  margin: 0 0 20px 0;
-  font-family: "Raleway", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Helvetica", "Verdana", sans-serif;
-  font-size: 22px;
-  line-height: 30px;
-  -webkit-font-smoothing: antialiased;
-  text-rendering: optimizeLegibility;
-  color: #000;
-}
-
-body {
-  padding: 20px;
-  text-shadow: rgba(0, 0, 0, 0.025) 0 -1px 0, rgba(255, 255, 255, 0.2) 0 1px 0;
-}
-
-h1 {
-  width: 350px;
-  color: #000;
-  font: 60px/1.0 "Ubuntu", "Helvetica", "Verdana", "Arial", sans-serif;
-  margin-left: 20px;
-}
diff --git a/examples/PayToScriptHashAddress.js b/examples/PayToScriptHashAddress.js
deleted file mode 100644
index 846d6d2dd..000000000
--- a/examples/PayToScriptHashAddress.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var bitcore = require('../bitcore');
-var Address = bitcore.Address;
-var bitcoreUtil = bitcore.util;
-var Script = bitcore.Script;
-var network = bitcore.networks.livenet;
-
-
-var script = ''; // write down your script here
-var s = Script.fromHumanReadable(script);
-var hash = bitcoreUtil.sha256ripe160(s.getBuffer());
-var version = network.addressScript;
-
-var addr = new Address(version, hash);
-var addrStr = addr.as('base58');
-
-// This outputs the "address" of thescript
-console.log(addrStr);
diff --git a/examples/PeerDiscovery.js b/examples/PeerDiscovery.js
deleted file mode 100644
index 576364f9a..000000000
--- a/examples/PeerDiscovery.js
+++ /dev/null
@@ -1,6 +0,0 @@
-var PeerManager = require('../lib/PeerManager');
-var peerman = new PeerManager();
-
-peerman.discover({
-  limit: 12
-}).start();
diff --git a/examples/PeerManager.js b/examples/PeerManager.js
deleted file mode 100644
index 06d2c2648..000000000
--- a/examples/PeerManager.js
+++ /dev/null
@@ -1,47 +0,0 @@
-'use strict';
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var Peer = bitcore.Peer;
-  var PeerManager = bitcore.PeerManager;
-
-  var handleBlock = function(info) {
-    console.log('** Block Received **');
-    console.log(info.message);
-  };
-
-  var handleTx = function(info) {
-    var tx = info.message.tx.getStandardizedObject();
-
-    console.log('** TX Received **');
-    console.log(tx);
-  };
-
-  var handleInv = function(info) {
-    console.log('** Inv **');
-    console.log(info.message);
-
-    var invs = info.message.invs;
-    info.conn.sendGetData(invs);
-  };
-
-  var peerman = new PeerManager({
-    network: 'testnet'
-  });
-
-  peerman.addPeer(new Peer('127.0.0.1', 18333));
-
-  peerman.on('connection', function(conn) {
-    conn.on('inv', handleInv);
-    conn.on('block', handleBlock);
-    conn.on('tx', handleTx);
-  });
-
-  peerman.start();
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/Rpc.js b/examples/Rpc.js
deleted file mode 100644
index e4bf5226b..000000000
--- a/examples/Rpc.js
+++ /dev/null
@@ -1,32 +0,0 @@
-'use strict';
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var RpcClient = bitcore.RpcClient;
-  var hash = '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4';
-
-  var config = {
-    protocol: 'http',
-    user: 'user',
-    pass: 'pass',
-    host: '127.0.0.1',
-    port: '18332',
-  };
-
-  var rpc = new RpcClient(config);
-
-  rpc.getBlock(hash, function(err, ret) {
-    if (err) {
-      console.error('An error occured fetching block', hash);
-      console.error(err);
-      return;
-    }
-    console.log(ret);
-  });
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/Script.js b/examples/Script.js
deleted file mode 100644
index a52fc1694..000000000
--- a/examples/Script.js
+++ /dev/null
@@ -1,52 +0,0 @@
-'use strict';
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var Address = bitcore.Address;
-  var coinUtil = bitcore.util;
-  var Script = bitcore.Script;
-  var network = bitcore.networks.testnet;
-
-  var getAddrStr = function(s) {
-    var addrStrs = [];
-    var type = s.classify();
-    var addr;
-
-    switch (type) {
-      case Script.TX_PUBKEY:
-        var chunk = s.captureOne();
-        addr = new Address(network.addressVersion, coinUtil.sha256ripe160(chunk));
-        addrStrs.push(addr.toString());
-        break;
-      case Script.TX_PUBKEYHASH:
-        addr = new Address(network.addressVersion, s.captureOne());
-        addrStrs.push(addr.toString());
-        break;
-      case Script.TX_SCRIPTHASH:
-        addr = new Address(network.P2SHVersion, s.captureOne());
-        addrStrs.push(addr.toString());
-        break;
-      case Script.TX_MULTISIG:
-        var chunks = s.capture();
-        chunks.forEach(function(chunk) {
-          var a = new Address(network.addressVersion, coinUtil.sha256ripe160(chunk));
-          addrStrs.push(a.toString());
-        });
-        break;
-      case Script.TX_UNKNOWN:
-        console.log('tx type unkown');
-        break;
-    }
-    return addrStrs;
-  };
-
-  var script = 'DUP HASH160 0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71 EQUALVERIFY CHECKSIG';
-  var s = Script.fromHumanReadable(script);
-  console.log(getAddrStr(s)[0]); // mkZBYBiq6DNoQEKakpMJegyDbw2YiNQnHT
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/ScriptInterpreter.js b/examples/ScriptInterpreter.js
deleted file mode 100644
index 424fc0088..000000000
--- a/examples/ScriptInterpreter.js
+++ /dev/null
@@ -1,42 +0,0 @@
-'use strict';
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var Address = bitcore.Address;
-  var coinUtil = bitcore.util;
-  var Script = bitcore.Script;
-  var ScriptInterpreter = bitcore.ScriptInterpreter;
-  var network = bitcore.networks.testnet;
-
-
-  // using "static" method
-  var scriptPubKeyHR = '0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71 EQUAL';
-  var scriptPubKey = Script.fromHumanReadable(scriptPubKeyHR);
-
-  var scriptSigHR = '0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71';
-  var scriptSig = Script.fromHumanReadable(scriptSigHR);
-
-  ScriptInterpreter.verifyFull(scriptSig, scriptPubKey, undefined, undefined,
-    undefined, undefined, function(err, result) {
-      console.log('script verified successfully? ', result)
-  });
-
-  // using an instance
-  scriptPubKeyHR = '0x26 0x554e5a49500370e53982a1d5201829562c5d9eebf256eb755b92c9b1449afd99f9f8c3265631 DROP HASH256 0x20 0x34b4f6042e1bcfc6182ee2727a3d0069a9071385bc07b318f57e77a28ffa13ac EQUAL';
-  scriptPubKey = Script.fromHumanReadable(scriptPubKeyHR);
-
-  scriptSigHR = '0x41 0x0470e53982a1d5201829562c5d9eebf256eb755b92c9b1449afd99f9f8c3265631142f3bf6954e3bec4bdad1a1a197bf90904a1e6f06c209eb477e2fde00d26691';
-  scriptSig = Script.fromHumanReadable(scriptSigHR);
-
-  var si = new ScriptInterpreter();
-  si.verifyFull(scriptSig, scriptPubKey, undefined, undefined,
-    undefined, function(err, result) {
-      console.log('script verified successfully? ', result)
-  });
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/SendTx.js b/examples/SendTx.js
deleted file mode 100644
index a7454b51f..000000000
--- a/examples/SendTx.js
+++ /dev/null
@@ -1,107 +0,0 @@
-'use strict';
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var Peer = bitcore.Peer;
-
-  var TransactionBuilder = bitcore.TransactionBuilder;
-  var PeerManager = bitcore.PeerManager;
-
-  // Unspent transactions can be found via the insight.bitcore.io or blockchain.info APIs
-  var unspent = [{
-      'txid': '707108b5ba4f78dc951df4647a03365bf36432ea57fb641676045c5044daaea7',
-      'vout': 0,
-      'address': 'n3QDC7DzsMmN4mcyp3k7XGPX7zFXXHG387',
-      'scriptPubKey': '76a914f00c4a92ee2314ab08ac0283dc8d07d9bf2be32388ac',
-      'amount': 0.12345600,
-      'confirmations': 43537
-    }, {
-      'txid': '87a158d32833cb555aea27b6a21af569ccaeb8f9b19691e05f1e6c2b3440bdb3',
-      'vout': 1,
-      'address': 'mxdrp9s4mVxS9X4RBYiLe99v59V81XA5C3',
-      'scriptPubKey': '76a914bbc87986da6b17c7876db4efacf59a95e14f6cf588ac',
-      'amount': 0.05749800,
-      'confirmations': 43536
-    }
-
-  ];
-
-  // Private keys in WIF format (see TransactionBuilder.js for other options)
-  var keys = [
-    'cQA75LXhV5JkMT8wkkqjR87SnHK4doh3c21p7PAd5tp8tc1tRBAY',
-    'cRz85dz9AiDieRpEwoucfXXQa1jdHHghcv6YnnVVGZ3MQyR1X4u2',
-    'cSq7yo4fvsbMyWVN945VUGUWMaSazZPWqBVJZyoGsHmNq6W4HVBV',
-    'cPa87VgwZfowGZYaEenoQeJgRfKW6PhZ1R65EHTkN1K19cSvc92G',
-    'cPQ9DSbBRLva9av5nqeF5AGrh3dsdW8p2E5jS4P8bDWZAoQTeeKB'
-  ];
-
-  var peerman = new PeerManager({
-    network: 'testnet'
-  });
-  peerman.addPeer(new Peer('127.0.0.1', 18333));
-
-  peerman.on('connect', function() {
-    var conn = peerman.getActiveConnection();
-    if (conn) {
-      // define transaction output
-      var outs = [{
-        address: 'mhNCT9TwZAGF1tLPpZdqfkTmtBkY282YDW',
-        amount: 0.1337
-      }];
-      // set change address
-      var opts = {
-        remainderOut: {
-          address: 'n4g2TFaQo8UgedwpkYdcQFF6xE2Ei9Czvy'
-        }
-      };
-      var tx = new TransactionBuilder(opts)
-        .setUnspent(unspent)
-        .setOutputs(outs)
-        .sign(keys)
-        .build();
-
-      /* Create and signing can be done in multiple steps:
-       *
-       *  var builder = new bitcore.TransactionBuilder(opts)
-       *                .setUnspent(utxos)
-       *                .setOutputs(outs);
-       *
-       *  // Sign with the first key
-       *  builder.sign(key1);
-       *  var tx = builder.build(); // Partially signed transaction
-       *
-       *  // Sign with the second key
-       *  builder.sign(key2);
-       *  if (builder.isFullySigned()){
-       *   var tx = builder.build();
-       *  }
-       *
-       *  var selectedUnspent = build.getSelectedUnspent(); // Retrieve selected unspent outputs from the transaction
-       */
-
-      var txid = tx.getHash().toString('hex');
-      console.log('Created transaction with txid ' + txid);
-      var raw_tx = tx.serialize().toString('hex');
-      console.log('Transaction raw hex dump:');
-      console.log('-------------------------------------');
-      console.log(raw_tx);
-      console.log('-------------------------------------');
-      // finally, send transaction to the bitcoin network
-      conn.sendTx(tx);
-
-      // for now, the network won't respond in any case
-      // (transaction accepted, transaction rejected)
-      // in the future, we may listen to 'reject' message
-      // see https://gist.github.com/gavinandresen/7079034
-    }
-  });
-
-  peerman.start();
-
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/SimpleP2Pmonitor.js b/examples/SimpleP2Pmonitor.js
deleted file mode 100644
index a2e2674f3..000000000
--- a/examples/SimpleP2Pmonitor.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * This is a simple script that will display network messages.
- * It users the Peer / Connection classes directly instead of
- * relying on PeerManager.
- */
-
-// replace by require('bitcore') if you use somewhere else
-var bitcore = require('../');
-
-//bitcore.config.logger = 'debug';
-
-var Peer = bitcore.Peer,
-  Connection = bitcore.Connection;
-
-var peer = new Peer('127.0.0.1', 8333);
-
-var socket = peer.createConnection();
-
-var con = new Connection(socket, peer);
-
-con.on('error', function(msg) {
-  var peer = msg.peer,
-    err = msg.err;
-  console.error('Error connecting to peer', peer.host + ':' + peer.port, '(' + err.message + ')');
-});
-
-con.on('disconnect', function(msg) {
-  console.log('disconnect: ', msg);
-});
-
-con.on('connect', function(msg) {
-  console.log('Connected to %s', msg.peer.host + ':' + msg.peer.port);
-});
-
-/* Listen P2P messages */
-
-// Make a log function available to all listeners
-// The log function is just like console.log except it prefixes 
-// messages with [host:port]
-function listen(event_name, fn) {
-  con.on(event_name, function(event) {
-    fn(event, function() {
-      var args = Array.prototype.slice.call(arguments);
-      var str = args.shift();
-      str = '[%s:%s] ' + str;
-      args = [str, event.peer.host, event.peer.port].concat(args);
-      console.log.apply(console, args);
-    });
-  });
-}
-
-listen('getaddr', function(event, log) {
-  log('Received message getaddr');
-  log(event);
-});
-
-listen('verack', function(event, log) {
-  log('Received message verack');
-});
-
-listen('version', function(event, log) {
-  log('Received message version (%s)', event.message.version);
-});
-
-listen('addr', function(event, log) {
-  log('Received message addr (%s addresses)', event.message.addrs.length);
-});
-
-listen('inv', function(event, log) {
-  log('Received message inv (%s invs)', event.message.count);
-  console.log(event.message.invs);
-});
diff --git a/examples/VanityAddress.js b/examples/VanityAddress.js
deleted file mode 100644
index 1e9d004a6..000000000
--- a/examples/VanityAddress.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-
-
-var run = function() {
-  // Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
-  var bitcore = require('../bitcore');
-  var Key = bitcore.Key;
-  var Address = bitcore.Address;
-
-  // config your regular expression
-  var re = /[0-9]{6}$/; // ends in 6 digits
-
-  var a, k, m;
-  while (true) {
-    k = Key.generateSync();
-    a = Address.fromKey(k);
-    m = a.toString().match(re);
-    if (m) break;
-  }
-  console.log('Address: ' + a.toString());
-  console.log('Private Key: ' + k.private.toString('hex'));
-
-};
-
-module.exports.run = run;
-if (require.main === module) {
-  run();
-}
diff --git a/examples/browser/README.md b/examples/browser/README.md
deleted file mode 100644
index 6dcc8b6c2..000000000
--- a/examples/browser/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Run `node browser/build.js -a` in the repository's root directory before using those examples.
diff --git a/examples/browser/armory.html b/examples/browser/armory.html
deleted file mode 100644
index 4de54d5aa..000000000
--- a/examples/browser/armory.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-  
-    
-  
-  
-    
-    Enter you paper wallet seed:
- -
- -
-

-    
-  
-
diff --git a/examples/browser/example.html b/examples/browser/example.html
deleted file mode 100644
index 3687cd834..000000000
--- a/examples/browser/example.html
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-  
-    Bitcore browser examples
-    
-    
-  
-  
-    
-      
-
- - - - - - diff --git a/examples/browser/simple.html b/examples/browser/simple.html deleted file mode 100644 index 18f35efaa..000000000 --- a/examples/browser/simple.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -

-    
-  
-

From f01ebd97d2081e29bc2d264d09fbbd7ec3fcc829 Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Wed, 1 Oct 2014 21:08:06 -0400
Subject: [PATCH 05/13] Buffers, identities, and randomNumbers.

---
 examples/identity.js |   5 ++
 lib/constants.js     |  18 ++--
 lib/identity.js      |  53 +++++------
 test/identity.js     | 204 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 242 insertions(+), 38 deletions(-)
 create mode 100644 examples/identity.js
 create mode 100644 test/identity.js

diff --git a/examples/identity.js b/examples/identity.js
new file mode 100644
index 000000000..1bbc26073
--- /dev/null
+++ b/examples/identity.js
@@ -0,0 +1,5 @@
+var Identity = require('../lib/identity');
+
+var identity = new Identity( 0x02 );
+
+console.log( identity.toString() );
diff --git a/lib/constants.js b/lib/constants.js
index c64494da2..43bf75bbe 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,15 +1,17 @@
 exports.mainnet = {
-  pubkeyhash: 0x00,
-  privkey: 0x80,
-  scripthash: 0x05,
-  bip32pubkey: 0x0488b21e,
+  pubkeyhash:   0x00,
+  identpersist: 0x01,
+  identephem:   0x02,
+  privkey:      0x80,
+  scripthash:   0x05,
+  bip32pubkey:  0x0488b21e,
   bip32privkey: 0x0488ade4,
 };
 
 exports.testnet = {
-  pubkeyhash: 0x6f,
-  privkey: 0xef,
-  scripthash: 0xc4,
-  bip32pubkey: 0x043587cf,
+  pubkeyhash:   0x6f,
+  privkey:      0xef,
+  scripthash:   0xc4,
+  bip32pubkey:  0x043587cf,
   bip32privkey: 0x04358394,
 };
diff --git a/lib/identity.js b/lib/identity.js
index bd85ccd7a..789cb54b4 100644
--- a/lib/identity.js
+++ b/lib/identity.js
@@ -1,12 +1,14 @@
 var base58check = require('./base58check');
-var constants = require('./constants');
-var Hash = require('./hash');
-var Pubkey = require('./pubkey');
-var Script = require('./script');
+var constants   = require('./constants');
+var Hash        = require('./hash');
+var Pubkey      = require('./pubkey');
+var Script      = require('./script');
+var Random      = require('./random');
 
 function Identity(buf) {
-  if (!(this instanceof Identity))
-    return new Identity(buf);
+  // TODO: instantiate identities without providing any configuration
+  if (!(this instanceof Identity)) return new Identity(buf);
+
   if (Buffer.isBuffer(buf)) {
     this.fromBuffer(buf);
   } else if (typeof buf === 'string') {
@@ -19,9 +21,9 @@ function Identity(buf) {
 };
 
 Identity.prototype.set = function(obj) {
-  this.hashbuf = obj.hashbuf || this.hashbuf || null;
-  this.networkstr = obj.networkstr || this.networkstr || 'mainnet';
-  this.typestr = obj.typestr || this.typestr || 'pubkeyhash';
+  this.hashbuf    = obj.hashbuf     || this.hashbuf     || null;
+  this.networkstr = obj.networkstr  || this.networkstr  || 'mainnet';
+  this.typestr    = obj.typestr     || this.typestr     || 'identephem';
   return this;
 };
 
@@ -29,18 +31,13 @@ Identity.prototype.fromBuffer = function(buf) {
   if (buf.length !== 1 + 20)
     throw new Error('Identity buffers must be exactly 21 bytes');
   var version = buf[0];
-  if (version === constants['mainnet']['pubkeyhash']) {
+
+  if (version === constants['mainnet']['identephem']) {
     this.networkstr = 'mainnet';
-    this.typestr = 'pubkeyhash';
-  } else if (version === constants['mainnet']['scripthash']) {
+    this.typestr = 'identephem';
+  } else if (version === constants['mainnet']['identpersist']) {
     this.networkstr = 'mainnet';
-    this.typestr = 'scripthash';
-  } else if (version === constants['testnet']['pubkeyhash']) {
-    this.networkstr = 'testnet';
-    this.typestr = 'pubkeyhash';
-  } else if (version === constants['testnet']['scripthash']) {
-    this.networkstr = 'testnet';
-    this.typestr = 'scripthash';
+    this.typestr = 'identpersist';
   } else {
     this.networkstr = 'unknown';
     this.typestr = 'unknown';
@@ -56,21 +53,14 @@ Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) {
     throw new Error('hashbuf must be exactly 20 bytes');
   this.hashbuf = hashbuf;
   this.networkstr = networkstr || 'mainnet';
-  this.typestr = typestr || 'pubkeyhash';
+  this.typestr = typestr || 'identephem';
   return this;
 };
 
 Identity.prototype.fromPubkey = function(pubkey, networkstr) {
   this.hashbuf = Hash.sha256ripemd160(pubkey.toBuffer());
   this.networkstr = networkstr || 'mainnet';
-  this.typestr = 'pubkeyhash';
-  return this;
-};
-
-Identity.prototype.fromScript = function(script, networkstr) {
-  this.hashbuf = Hash.sha256ripemd160(script.toBuffer());
-  this.networkstr = networkstr || 'mainnet';
-  this.typestr = 'scripthash';
+  this.typestr = 'identephem';
   return this;
 };
 
@@ -98,6 +88,9 @@ Identity.prototype.isValid = function() {
 };
 
 Identity.prototype.toBuffer = function() {
+  
+  console.log(this.networkstr); process.exit();
+  
   version = new Buffer([constants[this.networkstr][this.typestr]]);
   var buf = Buffer.concat([version, this.hashbuf]);
   return buf;
@@ -112,8 +105,8 @@ Identity.prototype.validate = function() {
     throw new Error('hash must be a buffer of 20 bytes');
   if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet')
     throw new Error('networkstr must be "mainnet" or "testnet"');
-  if (this.typestr !== 'pubkeyhash' && this.typestr !== 'scripthash')
-    throw new Error('typestr must be "pubkeyhash" or "scripthash"');
+  if (this.typestr !== 'identephem' && this.typestr !== 'scripthash')
+    throw new Error('typestr must be "identephem" or "scripthash"');
   return this;
 };
 
diff --git a/test/identity.js b/test/identity.js
new file mode 100644
index 000000000..a37be64d0
--- /dev/null
+++ b/test/identity.js
@@ -0,0 +1,204 @@
+var should = require('chai').should();
+var constants = require('../lib/constants');
+var Pubkey = require('../lib/pubkey');
+var Identity = require('../lib/identity');
+var Script = require('../lib/script');
+
+describe('Identity', function() {
+  
+  var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
+  var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
+  var str = '16VZnHwRhwrExfeHFHGjwrgEMq8VcYPs9r';
+
+  it('should create a new identity object', function() {
+    var identity = new Identity();
+    should.exist(identity);
+    identity = Identity(buf);
+    should.exist(identity);
+    identity = Identity(str);
+    should.exist(identity);
+  });
+
+  describe('@isValid', function() {
+
+    it('should validate this valid identity string', function() {
+      Identity.isValid(str).should.equal(true);
+    });
+
+    it('should invalidate this valid identity string', function() {
+      Identity.isValid(str.substr(1)).should.equal(false);
+    });
+
+  });
+
+  describe('#fromBuffer', function() {
+    
+    it('should make an identity from a buffer', function() {
+      Identity().fromBuffer(buf).toString().should.equal(str);
+    });
+
+  });
+
+  describe('#fromHashbuf', function() {
+    
+    it('should make an identity from a hashbuf', function() {
+      Identity().fromHashbuf(pubkeyhash).toString().should.equal(str);
+      var a = Identity().fromHashbuf(pubkeyhash, 'testnet', 'scripthash');
+      a.networkstr.should.equal('testnet');
+      a.typestr.should.equal('scripthash');
+    });
+
+    it('should throw an error for invalid length hashbuf', function() {
+      (function() {
+        Identity().fromHashbuf(buf);
+      }).should.throw('hashbuf must be exactly 20 bytes');
+    });
+
+  });
+
+  describe('#fromPubkey', function() {
+
+    it('should make this identity from a compressed pubkey', function() {
+      var pubkey = new Pubkey();
+      pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
+      var identity = new Identity();
+      identity.fromPubkey(pubkey);
+      identity.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke');
+    });
+
+    it('should make this identity from an uncompressed pubkey', function() {
+      var pubkey = new Pubkey();
+      pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
+      var identity = new Identity();
+      pubkey.compressed = false;
+      identity.fromPubkey(pubkey, 'mainnet');
+      identity.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
+    });
+
+  });
+
+  describe('#fromScript', function() {
+
+    it('should make this identity from a script', function() {
+      var script = Script().fromString("OP_CHECKMULTISIG");
+      var identity = Identity().fromScript(script);
+      identity.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm');
+    });
+
+    it('should make this identity from other script', function() {
+      var script = Script().fromString("OP_CHECKSIG OP_HASH160");
+      var identity = Identity().fromScript(script);
+      identity.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7');
+    });
+
+  });
+
+  describe('#fromString', function() {
+    
+    it('should derive from this known identity string mainnet', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
+    });
+
+    it('should derive from this known identity string testnet', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.networkstr = 'testnet';
+      identity.fromString(identity.toString());
+      identity.toString().should.equal('mm1X5M2QWyHVjn7txrF7mmtZDpjCXzoa98');
+    });
+
+    it('should derive from this known identity string mainnet scripthash', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.networkstr = 'mainnet';
+      identity.typestr = 'scripthash';
+      identity.fromString(identity.toString());
+      identity.toString().should.equal('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+    });
+
+    it('should derive from this known identity string testnet scripthash', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.networkstr = 'testnet';
+      identity.typestr = 'scripthash';
+      identity.fromString(identity.toString());
+      identity.toString().should.equal('2MxjnmaMtsJfyFcyG3WZCzS2RihdNuWqeX4');
+    });
+
+  });
+
+  describe('#isValid', function() {
+    
+    it('should describe this valid identity as valid', function() {
+      var identity = new Identity();
+      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.isValid().should.equal(true);
+    });
+
+    it('should describe this identity with unknown network as invalid', function() {
+      var identity = new Identity();
+      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.networkstr = 'unknown';
+      identity.isValid().should.equal(false);
+    });
+
+    it('should describe this identity with unknown type as invalid', function() {
+      var identity = new Identity();
+      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.typestr = 'unknown';
+      identity.isValid().should.equal(false);
+    });
+
+  });
+
+  describe('#toBuffer', function() {
+
+    it('should output this known hash', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
+    });
+
+  });
+
+  describe('#toString', function() {
+    
+    it('should output the same thing that was input', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.toString().should.equal(str);
+    });
+
+  });
+
+  describe('#validate', function() {
+    
+    it('should not throw an error on this valid identity', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      should.exist(identity.validate());
+    });
+
+    it('should throw an error on this invalid network', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.networkstr = 'unknown';
+      (function() {
+        identity.validate();
+      }).should.throw('networkstr must be "mainnet" or "testnet"');
+    });
+
+    it('should throw an error on this invalid type', function() {
+      var identity = new Identity();
+      identity.fromString(str);
+      identity.typestr = 'unknown';
+      (function() {
+        identity.validate();
+      }).should.throw('typestr must be "pubkeyhash" or "scripthash"');
+    });
+
+  });
+
+});

From 5fc9721647d4751c9b152d358158db4f5af3f71d Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Thu, 2 Oct 2014 15:08:44 -0400
Subject: [PATCH 06/13] Add support for identities.

---
 examples/identity.js |  4 +++-
 lib/identity.js      |  8 ++++----
 lib/keypair.js       | 10 ++++++++--
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/examples/identity.js b/examples/identity.js
index 1bbc26073..7a0476a4a 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -1,5 +1,7 @@
 var Identity = require('../lib/identity');
+var Keypair = require('../lib/keypair');
 
-var identity = new Identity( 0x02 );
+var keypair  = new Keypair();
+var identity = new Identity().fromPubkey( keypair.pubkey );
 
 console.log( identity.toString() );
diff --git a/lib/identity.js b/lib/identity.js
index 789cb54b4..22841f4a8 100644
--- a/lib/identity.js
+++ b/lib/identity.js
@@ -58,7 +58,10 @@ Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) {
 };
 
 Identity.prototype.fromPubkey = function(pubkey, networkstr) {
-  this.hashbuf = Hash.sha256ripemd160(pubkey.toBuffer());
+  var p = new Buffer( 0x01 );
+  var b = pubkey.toBuffer();
+
+  this.hashbuf = Hash.sha256ripemd160( Buffer.concat([ p , b ]) );
   this.networkstr = networkstr || 'mainnet';
   this.typestr = 'identephem';
   return this;
@@ -88,9 +91,6 @@ Identity.prototype.isValid = function() {
 };
 
 Identity.prototype.toBuffer = function() {
-  
-  console.log(this.networkstr); process.exit();
-  
   version = new Buffer([constants[this.networkstr][this.typestr]]);
   var buf = Buffer.concat([version, this.hashbuf]);
   return buf;
diff --git a/lib/keypair.js b/lib/keypair.js
index bc3adf88c..1ba511dd9 100644
--- a/lib/keypair.js
+++ b/lib/keypair.js
@@ -3,16 +3,22 @@ var Pubkey = require('./pubkey');
 var BN = require('./bn');
 var point = require('./point');
 
-var Keypair = function Keypair(obj) {
+var Keypair = function Keypair(obj) {  
   if (!(this instanceof Keypair))
     return new Keypair(obj);
+    
+  if (!obj) {
+    var privkey = Privkey().fromRandom();
+    var obj = this.fromPrivkey( privkey );
+  }
+
   if (obj)
     this.set(obj);
 };
 
 Keypair.prototype.set = function(obj) {
   this.privkey = obj.privkey || this.privkey || undefined;
-  this.pubkey = obj.pubkey || this.pubkey || undefined;
+  this.pubkey  = obj.pubkey  || this.pubkey  || undefined;
   return this;
 };
 

From 75cf4c4f9af3512f41ca10e5dee5ebc2069fa316 Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Thu, 2 Oct 2014 22:27:18 -0400
Subject: [PATCH 07/13] tidy up identity class, add tests.

---
 examples/identity.js | 10 ++++++++--
 lib/identity.js      | 13 ++++++-------
 test/identity.js     | 10 +++++-----
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/examples/identity.js b/examples/identity.js
index 7a0476a4a..8ef2ba411 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -1,7 +1,13 @@
 var Identity = require('../lib/identity');
-var Keypair = require('../lib/keypair');
+var Keypair  = require('../lib/keypair');
 
-var keypair  = new Keypair();
+var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
+var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
+
+var keypair  = new Keypair().fromString( buf.toString('hex') );
 var identity = new Identity().fromPubkey( keypair.pubkey );
 
+console.log( 'pubkey',  keypair.pubkey.toString() );
+console.log( 'privkey', keypair.privkey.toString() );
+console.log( identity );
 console.log( identity.toString() );
diff --git a/lib/identity.js b/lib/identity.js
index 22841f4a8..7a66324a9 100644
--- a/lib/identity.js
+++ b/lib/identity.js
@@ -58,12 +58,9 @@ Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) {
 };
 
 Identity.prototype.fromPubkey = function(pubkey, networkstr) {
-  var p = new Buffer( 0x01 );
-  var b = pubkey.toBuffer();
-
-  this.hashbuf = Hash.sha256ripemd160( Buffer.concat([ p , b ]) );
+  this.hashbuf    = Hash.sha256ripemd160( pubkey.toBuffer() );
   this.networkstr = networkstr || 'mainnet';
-  this.typestr = 'identephem';
+  this.typestr    = 'identephem';
   return this;
 };
 
@@ -91,6 +88,8 @@ Identity.prototype.isValid = function() {
 };
 
 Identity.prototype.toBuffer = function() {
+  console.log( this.networkstr );
+  
   version = new Buffer([constants[this.networkstr][this.typestr]]);
   var buf = Buffer.concat([version, this.hashbuf]);
   return buf;
@@ -105,8 +104,8 @@ Identity.prototype.validate = function() {
     throw new Error('hash must be a buffer of 20 bytes');
   if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet')
     throw new Error('networkstr must be "mainnet" or "testnet"');
-  if (this.typestr !== 'identephem' && this.typestr !== 'scripthash')
-    throw new Error('typestr must be "identephem" or "scripthash"');
+  if (this.typestr !== 'identephem' && this.typestr !== 'identpersist')
+    throw new Error('typestr must be "identephem" or "identpersist"');
   return this;
 };
 
diff --git a/test/identity.js b/test/identity.js
index a37be64d0..e3a12f514 100644
--- a/test/identity.js
+++ b/test/identity.js
@@ -8,7 +8,7 @@ describe('Identity', function() {
   
   var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
   var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
-  var str = '16VZnHwRhwrExfeHFHGjwrgEMq8VcYPs9r';
+  var str = 'sMKQzi3RTDK8zRRimoPZQGw4sfsj9Ttx1';
 
   it('should create a new identity object', function() {
     var identity = new Identity();
@@ -45,7 +45,7 @@ describe('Identity', function() {
       Identity().fromHashbuf(pubkeyhash).toString().should.equal(str);
       var a = Identity().fromHashbuf(pubkeyhash, 'testnet', 'scripthash');
       a.networkstr.should.equal('testnet');
-      a.typestr.should.equal('scripthash');
+      a.typestr.should.equal('identephem');
     });
 
     it('should throw an error for invalid length hashbuf', function() {
@@ -113,7 +113,7 @@ describe('Identity', function() {
       var identity = new Identity();
       identity.fromString(str);
       identity.networkstr = 'mainnet';
-      identity.typestr = 'scripthash';
+      identity.typestr = 'identephem';
       identity.fromString(identity.toString());
       identity.toString().should.equal('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
     });
@@ -122,7 +122,7 @@ describe('Identity', function() {
       var identity = new Identity();
       identity.fromString(str);
       identity.networkstr = 'testnet';
-      identity.typestr = 'scripthash';
+      identity.typestr = 'identephem';
       identity.fromString(identity.toString());
       identity.toString().should.equal('2MxjnmaMtsJfyFcyG3WZCzS2RihdNuWqeX4');
     });
@@ -196,7 +196,7 @@ describe('Identity', function() {
       identity.typestr = 'unknown';
       (function() {
         identity.validate();
-      }).should.throw('typestr must be "pubkeyhash" or "scripthash"');
+      }).should.throw('typestr must be "identephem" or "identpersist"');
     });
 
   });

From 4dfe9fd13d178322f597238d858f70346729e49b Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Thu, 2 Oct 2014 22:33:22 -0400
Subject: [PATCH 08/13] Update example code.

---
 examples/identity.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/examples/identity.js b/examples/identity.js
index 8ef2ba411..e8df7fd2a 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -4,7 +4,8 @@ var Keypair  = require('../lib/keypair');
 var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
 var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
 
-var keypair  = new Keypair().fromString( buf.toString('hex') );
+var keypair  = new Keypair();
+//var identity = new Identity().fromPubkey( keypair.pubkey );
 var identity = new Identity().fromPubkey( keypair.pubkey );
 
 console.log( 'pubkey',  keypair.pubkey.toString() );

From dac2acc743400c453dc9e12f25775e33249a3b52 Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Mon, 6 Oct 2014 14:00:03 -0400
Subject: [PATCH 09/13] Clean example for full identities.

---
 examples/identity.js | 16 ++++++-------
 lib/constants.js     | 11 ++++++++-
 lib/identity.js      | 54 +++++++++++++++++++++++++-------------------
 3 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/examples/identity.js b/examples/identity.js
index e8df7fd2a..25fc992e4 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -1,14 +1,12 @@
 var Identity = require('../lib/identity');
-var Keypair  = require('../lib/keypair');
+var KeyPair  = require('../lib/keypair');
 
-var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
-var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
+var keypair = new KeyPair().fromRandom();
+
+console.log( 'keypair:' , keypair );
+console.log( 'public key:' , keypair.pubkey.toString() );
 
-var keypair  = new Keypair();
-//var identity = new Identity().fromPubkey( keypair.pubkey );
 var identity = new Identity().fromPubkey( keypair.pubkey );
 
-console.log( 'pubkey',  keypair.pubkey.toString() );
-console.log( 'privkey', keypair.privkey.toString() );
-console.log( identity );
-console.log( identity.toString() );
+console.log( 'identity:' , identity );
+console.log( 'identity string:' , identity.toString() );
diff --git a/lib/constants.js b/lib/constants.js
index 43bf75bbe..2c8b7e3e8 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -1,7 +1,8 @@
 exports.mainnet = {
   pubkeyhash:   0x00,
-  identpersist: 0x01,
+  identity:     0x0f,
   identephem:   0x02,
+  identpersist: 0x01,
   privkey:      0x80,
   scripthash:   0x05,
   bip32pubkey:  0x0488b21e,
@@ -10,8 +11,16 @@ exports.mainnet = {
 
 exports.testnet = {
   pubkeyhash:   0x6f,
+  identity:     0x0f,
+  identephem:   0x02,
+  identpersist: 0x11,
   privkey:      0xef,
   scripthash:   0xc4,
   bip32pubkey:  0x043587cf,
   bip32privkey: 0x04358394,
 };
+
+exports.ephemeral = {
+  prefix:   0x0f,
+  identity: 0x02
+}
diff --git a/lib/identity.js b/lib/identity.js
index 7a66324a9..f89d2ae6b 100644
--- a/lib/identity.js
+++ b/lib/identity.js
@@ -22,28 +22,37 @@ function Identity(buf) {
 
 Identity.prototype.set = function(obj) {
   this.hashbuf    = obj.hashbuf     || this.hashbuf     || null;
-  this.networkstr = obj.networkstr  || this.networkstr  || 'mainnet';
-  this.typestr    = obj.typestr     || this.typestr     || 'identephem';
+  this.networkstr = obj.networkstr  || this.networkstr  || 'ephemeral';
+  this.typestr    = obj.typestr     || this.typestr     || 'identity';
   return this;
 };
 
 Identity.prototype.fromBuffer = function(buf) {
-  if (buf.length !== 1 + 20)
-    throw new Error('Identity buffers must be exactly 21 bytes');
-  var version = buf[0];
+  // Identities are prefix + type + key
+  if (buf.length !== 1 + 1 + 20)
+    throw new Error('Identity buffers must be exactly 22 bytes');
+  
+  var prefix  = buf[0];
+  var version = buf[1];
+  
+  if (prefix !== constants['ephemeral'][ prefix ])
+    throw new Error('Identity buffers must contain an identity prefix (0x0f)');
 
-  if (version === constants['mainnet']['identephem']) {
+  if (version === constants['ephemeral']['identity']) {
+    this.networkstr = 'ephemeral';
+    this.typestr = 'identity';
+  } else if (version === constants['mainnet']['identity']) {
     this.networkstr = 'mainnet';
-    this.typestr = 'identephem';
-  } else if (version === constants['mainnet']['identpersist']) {
-    this.networkstr = 'mainnet';
-    this.typestr = 'identpersist';
+    this.typestr = 'identity';
+  } else if (version === constants['testnet']['identity']) {
+    this.networkstr = 'testnet';
+    this.typestr = 'identity';
   } else {
     this.networkstr = 'unknown';
     this.typestr = 'unknown';
   }
 
-  this.hashbuf = buf.slice(1);
+  this.hashbuf = buf.slice( 2 );
 
   return this;
 };
@@ -51,16 +60,16 @@ Identity.prototype.fromBuffer = function(buf) {
 Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) {
   if (hashbuf.length !== 20)
     throw new Error('hashbuf must be exactly 20 bytes');
-  this.hashbuf = hashbuf;
-  this.networkstr = networkstr || 'mainnet';
-  this.typestr = typestr || 'identephem';
+  this.hashbuf    = hashbuf;
+  this.networkstr = networkstr || 'ephemeral';
+  this.typestr    = typestr    || 'identity';
   return this;
 };
 
 Identity.prototype.fromPubkey = function(pubkey, networkstr) {
   this.hashbuf    = Hash.sha256ripemd160( pubkey.toBuffer() );
-  this.networkstr = networkstr || 'mainnet';
-  this.typestr    = 'identephem';
+  this.networkstr = networkstr || 'ephemeral';
+  this.typestr    = 'identity';
   return this;
 };
 
@@ -71,7 +80,7 @@ Identity.prototype.fromString = function(str) {
 
 Identity.isValid = function(addrstr) {
   try {
-    var address = new Identity().fromString(addrstr);
+    var address = new Identity().fromString( addrstr );
   } catch (e) {
     return false;
   }
@@ -88,21 +97,20 @@ Identity.prototype.isValid = function() {
 };
 
 Identity.prototype.toBuffer = function() {
-  console.log( this.networkstr );
-  
-  version = new Buffer([constants[this.networkstr][this.typestr]]);
-  var buf = Buffer.concat([version, this.hashbuf]);
+  var prefix  = new Buffer([ constants[ this.networkstr ][ 'prefix' ] ])
+  var version = new Buffer([ constants[ this.networkstr ][ this.typestr ] ]);;
+  var buf     = Buffer.concat([ prefix , version, this.hashbuf ]);
   return buf;
 };
 
 Identity.prototype.toString = function() {
-  return base58check.encode(this.toBuffer());
+  return base58check.encode( this.toBuffer() );
 };
 
 Identity.prototype.validate = function() {
   if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 20)
     throw new Error('hash must be a buffer of 20 bytes');
-  if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet')
+  if (['ephemeral', 'mainnet', 'testnet'].indexOf( this.networkstr ))
     throw new Error('networkstr must be "mainnet" or "testnet"');
   if (this.typestr !== 'identephem' && this.typestr !== 'identpersist')
     throw new Error('typestr must be "identephem" or "identpersist"');

From 4b6e9aaf033392a1cb29db335b268579067e0b23 Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Mon, 6 Oct 2014 15:40:30 -0400
Subject: [PATCH 10/13] Improve tests.

---
 lib/address.js   |  2 +-
 lib/identity.js  | 14 ++++----
 lib/pubkey.js    |  5 +--
 test/identity.js | 93 ++++++++++++++++--------------------------------
 4 files changed, 41 insertions(+), 73 deletions(-)

diff --git a/lib/address.js b/lib/address.js
index 6103098b0..6d599c05e 100644
--- a/lib/address.js
+++ b/lib/address.js
@@ -98,7 +98,7 @@ Address.prototype.isValid = function() {
 };
 
 Address.prototype.toBuffer = function() {
-  version = new Buffer([constants[this.networkstr][this.typestr]]);
+  var version = new Buffer([constants[this.networkstr][this.typestr]]);
   var buf = Buffer.concat([version, this.hashbuf]);
   return buf;
 };
diff --git a/lib/identity.js b/lib/identity.js
index f89d2ae6b..03e40acb9 100644
--- a/lib/identity.js
+++ b/lib/identity.js
@@ -30,13 +30,10 @@ Identity.prototype.set = function(obj) {
 Identity.prototype.fromBuffer = function(buf) {
   // Identities are prefix + type + key
   if (buf.length !== 1 + 1 + 20)
-    throw new Error('Identity buffers must be exactly 22 bytes');
+    throw new Error('Identity buffers must be exactly 22 bytes (was '+buf.length+')');
   
   var prefix  = buf[0];
   var version = buf[1];
-  
-  if (prefix !== constants['ephemeral'][ prefix ])
-    throw new Error('Identity buffers must contain an identity prefix (0x0f)');
 
   if (version === constants['ephemeral']['identity']) {
     this.networkstr = 'ephemeral';
@@ -51,6 +48,9 @@ Identity.prototype.fromBuffer = function(buf) {
     this.networkstr = 'unknown';
     this.typestr = 'unknown';
   }
+  
+  if (prefix !== constants['ephemeral']['prefix'])
+    throw new Error('Identity buffers must contain an identity prefix ('+constants['ephemeral']['prefix']+', was '+ prefix.toString() + ')');
 
   this.hashbuf = buf.slice( 2 );
 
@@ -111,9 +111,9 @@ Identity.prototype.validate = function() {
   if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 20)
     throw new Error('hash must be a buffer of 20 bytes');
   if (['ephemeral', 'mainnet', 'testnet'].indexOf( this.networkstr ))
-    throw new Error('networkstr must be "mainnet" or "testnet"');
-  if (this.typestr !== 'identephem' && this.typestr !== 'identpersist')
-    throw new Error('typestr must be "identephem" or "identpersist"');
+    throw new Error('networkstr must be "ephemeral", "mainnet", or "testnet"');
+  if (this.typestr !== 'identity')
+    throw new Error('typestr must be "identity"');
   return this;
 };
 
diff --git a/lib/pubkey.js b/lib/pubkey.js
index a2db15500..3a1bc4457 100644
--- a/lib/pubkey.js
+++ b/lib/pubkey.js
@@ -68,8 +68,9 @@ Pubkey.prototype.fromDER = function(buf) {
   return this;
 };
 
-Pubkey.prototype.fromString = function(str) {
-  this.fromDER(new Buffer(str, 'hex'));
+Pubkey.prototype.fromString = function( str , encoding ) {
+  var encoding = encoding || 'hex';
+  this.fromDER( new Buffer(str, encoding ) );
 };
 
 Pubkey.prototype.fromX = function(odd, x) {
diff --git a/test/identity.js b/test/identity.js
index e3a12f514..6fbf0be1b 100644
--- a/test/identity.js
+++ b/test/identity.js
@@ -1,14 +1,23 @@
 var should = require('chai').should();
 var constants = require('../lib/constants');
-var Pubkey = require('../lib/pubkey');
+var PubKey = require('../lib/pubkey');
 var Identity = require('../lib/identity');
-var Script = require('../lib/script');
 
 describe('Identity', function() {
   
-  var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
-  var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
-  var str = 'sMKQzi3RTDK8zRRimoPZQGw4sfsj9Ttx1';
+  var knownPrivKey = 'L1KL3xHiuBF9YuBKTZMorW6TVDG2QW9UHWdSFEzcVFpLuGxTe9bQ';
+  var knownPubKey = '026006aa5fd6e800e6b529258dbb73b531da735a863c87e6673bf96def1372a59e';
+  var knownIdent = 'Tf8vkF9HPCDbNcLoFHk8ENAwJLQMVmWRz5P';
+  
+  //var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
+  var pubkey = '0348dc031a1499c455eeb593407e0505dfbd95a88411fa78e8cab9cbe89d064048';
+  var key = new PubKey();
+  key.fromString( pubkey );
+
+  //var buf = Buffer.concat([ new Buffer([0]), new Buffer([0]), pubkeyhash ]);
+  // note: key is wrong string until I figure out how to duplicate the generation of short keys
+  var buf = Buffer.concat([ new Buffer( 0x0f ) , new Buffer( 0x02 ) , new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex') ])
+  var str = 'Tf3sWHK314o6hpeUDHpqu8RAxPypoAinbDg';
 
   it('should create a new identity object', function() {
     var identity = new Identity();
@@ -22,7 +31,7 @@ describe('Identity', function() {
   describe('@isValid', function() {
 
     it('should validate this valid identity string', function() {
-      Identity.isValid(str).should.equal(true);
+      Identity.isValid( str ).should.equal( true );
     });
 
     it('should invalidate this valid identity string', function() {
@@ -45,7 +54,7 @@ describe('Identity', function() {
       Identity().fromHashbuf(pubkeyhash).toString().should.equal(str);
       var a = Identity().fromHashbuf(pubkeyhash, 'testnet', 'scripthash');
       a.networkstr.should.equal('testnet');
-      a.typestr.should.equal('identephem');
+      a.typestr.should.equal('scripthash');
     });
 
     it('should throw an error for invalid length hashbuf', function() {
@@ -59,94 +68,52 @@ describe('Identity', function() {
   describe('#fromPubkey', function() {
 
     it('should make this identity from a compressed pubkey', function() {
-      var pubkey = new Pubkey();
-      pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
+      var pubkey = new PubKey();
+      pubkey.fromDER(new Buffer( knownPubKey , 'hex'));
       var identity = new Identity();
       identity.fromPubkey(pubkey);
-      identity.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke');
+      identity.toString().should.equal( knownIdent );
     });
 
     it('should make this identity from an uncompressed pubkey', function() {
-      var pubkey = new Pubkey();
-      pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
+      var pubkey = new PubKey();
+      pubkey.fromDER(new Buffer( knownPubKey , 'hex'));
       var identity = new Identity();
       pubkey.compressed = false;
-      identity.fromPubkey(pubkey, 'mainnet');
-      identity.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
-    });
-
-  });
-
-  describe('#fromScript', function() {
-
-    it('should make this identity from a script', function() {
-      var script = Script().fromString("OP_CHECKMULTISIG");
-      var identity = Identity().fromScript(script);
-      identity.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm');
-    });
-
-    it('should make this identity from other script', function() {
-      var script = Script().fromString("OP_CHECKSIG OP_HASH160");
-      var identity = Identity().fromScript(script);
-      identity.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7');
+      identity.fromPubkey(pubkey, 'ephemeral');
+      identity.toString().should.equal( knownIdent );
     });
 
   });
 
   describe('#fromString', function() {
     
-    it('should derive from this known identity string mainnet', function() {
+    it('should derive from this known ephemeral identity string', function() {
       var identity = new Identity();
-      identity.fromString(str);
+      identity.fromString( str );
       identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
     });
 
-    it('should derive from this known identity string testnet', function() {
-      var identity = new Identity();
-      identity.fromString(str);
-      identity.networkstr = 'testnet';
-      identity.fromString(identity.toString());
-      identity.toString().should.equal('mm1X5M2QWyHVjn7txrF7mmtZDpjCXzoa98');
-    });
-
-    it('should derive from this known identity string mainnet scripthash', function() {
-      var identity = new Identity();
-      identity.fromString(str);
-      identity.networkstr = 'mainnet';
-      identity.typestr = 'identephem';
-      identity.fromString(identity.toString());
-      identity.toString().should.equal('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
-    });
-
-    it('should derive from this known identity string testnet scripthash', function() {
-      var identity = new Identity();
-      identity.fromString(str);
-      identity.networkstr = 'testnet';
-      identity.typestr = 'identephem';
-      identity.fromString(identity.toString());
-      identity.toString().should.equal('2MxjnmaMtsJfyFcyG3WZCzS2RihdNuWqeX4');
-    });
-
   });
 
   describe('#isValid', function() {
     
     it('should describe this valid identity as valid', function() {
       var identity = new Identity();
-      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.fromString( knownIdent );
       identity.isValid().should.equal(true);
     });
 
     it('should describe this identity with unknown network as invalid', function() {
       var identity = new Identity();
-      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.fromString( knownIdent );
       identity.networkstr = 'unknown';
       identity.isValid().should.equal(false);
     });
 
     it('should describe this identity with unknown type as invalid', function() {
       var identity = new Identity();
-      identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
+      identity.fromString( knownIdent );
       identity.typestr = 'unknown';
       identity.isValid().should.equal(false);
     });
@@ -187,7 +154,7 @@ describe('Identity', function() {
       identity.networkstr = 'unknown';
       (function() {
         identity.validate();
-      }).should.throw('networkstr must be "mainnet" or "testnet"');
+      }).should.throw('networkstr must be "ephemeral", "mainnet", or "testnet"');
     });
 
     it('should throw an error on this invalid type', function() {
@@ -196,7 +163,7 @@ describe('Identity', function() {
       identity.typestr = 'unknown';
       (function() {
         identity.validate();
-      }).should.throw('typestr must be "identephem" or "identpersist"');
+      }).should.throw('typestr must be "identity"');
     });
 
   });

From 14748ae2b5b7ae8ec7d46183c3cadbe074d8bd9c Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Mon, 6 Oct 2014 17:54:20 -0400
Subject: [PATCH 11/13] Make more tests pass with Identity().

---
 examples/identity.js |  5 ++++-
 lib/keypair.js       |  8 +++++---
 test/identity.js     | 23 +++++++++++------------
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/examples/identity.js b/examples/identity.js
index 25fc992e4..7990fd95f 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -1,10 +1,13 @@
 var Identity = require('../lib/identity');
 var KeyPair  = require('../lib/keypair');
+var Hash     = require('../lib/hash');
 
 var keypair = new KeyPair().fromRandom();
 
 console.log( 'keypair:' , keypair );
-console.log( 'public key:' , keypair.pubkey.toString() );
+console.log( 'private key:' , keypair.privkey.toString('hex') );
+console.log( 'public key:' , keypair.pubkey.toString('hex') );
+console.log( 'public hash:' , Hash.sha256ripemd160( keypair.pubkey.toBuffer() ).toString('hex') );
 
 var identity = new Identity().fromPubkey( keypair.pubkey );
 
diff --git a/lib/keypair.js b/lib/keypair.js
index 1ba511dd9..037547c1e 100644
--- a/lib/keypair.js
+++ b/lib/keypair.js
@@ -6,11 +6,13 @@ var point = require('./point');
 var Keypair = function Keypair(obj) {  
   if (!(this instanceof Keypair))
     return new Keypair(obj);
-    
-  if (!obj) {
+  
+  // breaks some tests
+  // TODO: allow keys to be created with simply `new Keypair()` (random gen.)
+  /*if (!obj) {
     var privkey = Privkey().fromRandom();
     var obj = this.fromPrivkey( privkey );
-  }
+  }*/
 
   if (obj)
     this.set(obj);
diff --git a/test/identity.js b/test/identity.js
index 6fbf0be1b..8246df044 100644
--- a/test/identity.js
+++ b/test/identity.js
@@ -5,19 +5,18 @@ var Identity = require('../lib/identity');
 
 describe('Identity', function() {
   
-  var knownPrivKey = 'L1KL3xHiuBF9YuBKTZMorW6TVDG2QW9UHWdSFEzcVFpLuGxTe9bQ';
-  var knownPubKey = '026006aa5fd6e800e6b529258dbb73b531da735a863c87e6673bf96def1372a59e';
-  var knownIdent = 'Tf8vkF9HPCDbNcLoFHk8ENAwJLQMVmWRz5P';
+  var knownPrivKey = 'L3qq9TMqq2Wfax48vTsywEtCTCTbr18PuMwkvpLUseCJPBhGhAJj';
+  var knownPubKey = '03663eadf291f099c7c87cf04dc037c49b4d168ff67a0f86d95fa77e525af4dee6';
+  var knownPubKeyHash = 'c3f89d708d24c0eaf5953d103b95dfec87ab66f6';
+  var knownIdent = 'TfFQdYg2BmLVWew1faUytoG3EpZZ8ebTqHr';
   
-  //var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
-  var pubkey = '0348dc031a1499c455eeb593407e0505dfbd95a88411fa78e8cab9cbe89d064048';
-  var key = new PubKey();
-  key.fromString( pubkey );
+  var pubkeyhash = new Buffer( knownPubKeyHash , 'hex');
 
   //var buf = Buffer.concat([ new Buffer([0]), new Buffer([0]), pubkeyhash ]);
   // note: key is wrong string until I figure out how to duplicate the generation of short keys
-  var buf = Buffer.concat([ new Buffer( 0x0f ) , new Buffer( 0x02 ) , new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex') ])
-  var str = 'Tf3sWHK314o6hpeUDHpqu8RAxPypoAinbDg';
+  //var buf = Buffer.concat([ new Buffer( 0x0f ) , new Buffer( 0x02 ) , pubkeyhash ])
+  var buf = Buffer.concat([ new Buffer([0x0f]) , new Buffer([0x02]) , pubkeyhash ])
+  var str = knownIdent;
 
   it('should create a new identity object', function() {
     var identity = new Identity();
@@ -77,7 +76,7 @@ describe('Identity', function() {
 
     it('should make this identity from an uncompressed pubkey', function() {
       var pubkey = new PubKey();
-      pubkey.fromDER(new Buffer( knownPubKey , 'hex'));
+      pubkey.fromDER(new Buffer( knownPubKeyUncomp , 'hex'));
       var identity = new Identity();
       pubkey.compressed = false;
       identity.fromPubkey(pubkey, 'ephemeral');
@@ -91,7 +90,7 @@ describe('Identity', function() {
     it('should derive from this known ephemeral identity string', function() {
       var identity = new Identity();
       identity.fromString( str );
-      identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
+      identity.toBuffer().slice(2).toString('hex').should.equal(pubkeyhash.toString('hex'));
     });
 
   });
@@ -125,7 +124,7 @@ describe('Identity', function() {
     it('should output this known hash', function() {
       var identity = new Identity();
       identity.fromString(str);
-      identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
+      identity.toBuffer().slice(2).toString('hex').should.equal(pubkeyhash.toString('hex'));
     });
 
   });

From 61023748758488323454f80173b7053e75460be6 Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Mon, 6 Oct 2014 18:03:20 -0400
Subject: [PATCH 12/13] Full suite of working tests for Identities.

---
 examples/identity.js |  5 +++++
 package.json         |  3 ++-
 test/identity.js     | 13 +++++++------
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/examples/identity.js b/examples/identity.js
index 7990fd95f..c17bc21c1 100644
--- a/examples/identity.js
+++ b/examples/identity.js
@@ -9,7 +9,12 @@ console.log( 'private key:' , keypair.privkey.toString('hex') );
 console.log( 'public key:' , keypair.pubkey.toString('hex') );
 console.log( 'public hash:' , Hash.sha256ripemd160( keypair.pubkey.toBuffer() ).toString('hex') );
 
+
 var identity = new Identity().fromPubkey( keypair.pubkey );
 
+keypair.pubkey.compressed = false;
+var identityComp = new Identity().fromPubkey( keypair.pubkey );
+
 console.log( 'identity:' , identity );
 console.log( 'identity string:' , identity.toString() );
+console.log( 'identity string, compressed:' , identityComp.toString() );
diff --git a/package.json b/package.json
index 463bf21d6..91feea9d5 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,8 @@
   "author": "BitPay ",
   "main": "index.js",
   "scripts": {
-    "test": "mocha"
+    "test": "mocha",
+    "coverage": "istanbul cover _mocha"
   },
   "contributors": [
     {
diff --git a/test/identity.js b/test/identity.js
index 8246df044..4e2f75b5f 100644
--- a/test/identity.js
+++ b/test/identity.js
@@ -5,10 +5,11 @@ var Identity = require('../lib/identity');
 
 describe('Identity', function() {
   
-  var knownPrivKey = 'L3qq9TMqq2Wfax48vTsywEtCTCTbr18PuMwkvpLUseCJPBhGhAJj';
-  var knownPubKey = '03663eadf291f099c7c87cf04dc037c49b4d168ff67a0f86d95fa77e525af4dee6';
-  var knownPubKeyHash = 'c3f89d708d24c0eaf5953d103b95dfec87ab66f6';
-  var knownIdent = 'TfFQdYg2BmLVWew1faUytoG3EpZZ8ebTqHr';
+  var knownPrivKey    = 'L3e3ZneXzGw2wyyRoUxKGGrHCBhBE3uPMvQDXPaJTom4d4ogRxvC';
+  var knownPubKey     = '02ff0c643214634691e6f1c5044df79f7002c404407c8db1897484017e1082f182';
+  var knownPubKeyHash = 'bceb8b52237d7a6c09e9aaedcf26cf387530d23e';
+  var knownIdent      = 'TfEmMAA5PSQRRJgiZka8y6B5x1pABHe6BVv';
+  var knownIdentComp  = 'TfDBCwB4ciatE4Kx3r1TK5kfCTxrrpG1H8J';
   
   var pubkeyhash = new Buffer( knownPubKeyHash , 'hex');
 
@@ -76,11 +77,11 @@ describe('Identity', function() {
 
     it('should make this identity from an uncompressed pubkey', function() {
       var pubkey = new PubKey();
-      pubkey.fromDER(new Buffer( knownPubKeyUncomp , 'hex'));
+      pubkey.fromDER(new Buffer( knownPubKey , 'hex'));
       var identity = new Identity();
       pubkey.compressed = false;
       identity.fromPubkey(pubkey, 'ephemeral');
-      identity.toString().should.equal( knownIdent );
+      identity.toString().should.equal( knownIdentComp );
     });
 
   });

From 3c74af9266112c270345745676f4e3e381e2c89d Mon Sep 17 00:00:00 2001
From: Eric Martindale 
Date: Mon, 6 Oct 2014 18:16:05 -0400
Subject: [PATCH 13/13] Add exportable class for BitAuth.

---
 index.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/index.js b/index.js
index 7df3dda2a..144b8cd7e 100644
--- a/index.js
+++ b/index.js
@@ -13,6 +13,7 @@ bitcore.BufferWriter = require('./lib/bufferwriter');
 bitcore.Constants = require('./lib/constants');
 bitcore.ECDSA = require('./lib/ecdsa');
 bitcore.Hash = require('./lib/hash');
+bitcore.Identity = require('./lib/identity');
 bitcore.KDF = require('./lib/kdf');
 bitcore.Keypair = require('./lib/keypair');
 bitcore.Message = require('./lib/message');