Merge branch 'master' of github.com:bitpay/bitcore

Conflicts:
	README.md
This commit is contained in:
Jason Dreyzehner 2014-02-07 20:52:02 -05:00
commit bb855e270f
20 changed files with 376 additions and 21 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
build/ build/
browser/bundle.js
browser/vendor.js
node_modules/ node_modules/
*.swp *.swp
*~ *~

39
.jshintrc Normal file
View File

@ -0,0 +1,39 @@
{
"node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"browser": true, // Standard browser globals e.g. `window`, `document`.
"esnext": true, // Allow ES.next specific features such as `const` and `let`.
"bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
"camelcase": false, // Permit only camelcase for `var` and `object indexes`.
"curly": false, // Require {} for every new block or scope.
"eqeqeq": true, // Require triple equals i.e. `===`.
"immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
"latedef": true, // Prohibit variable use before definition.
"newcap": true, // Require capitalization of all constructor functions e.g. `new F()`.
"noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
"quotmark": "single", // Define quotes to string values.
"regexp": true, // Prohibit `.` and `[^...]` in regular expressions.
"undef": true, // Require all non-global variables be declared before they are used.
"unused": true, // Warn unused variables.
"strict": true, // Require `use strict` pragma in every file.
"trailing": true, // Prohibit trailing whitespaces.
"smarttabs": false, // Suppresses warnings about mixed tabs and spaces
"globals": { // Globals variables.
"angular": true
},
"predef": [ // Extra globals.
"define",
"require",
"exports",
"module",
"describe",
"before",
"beforeEach",
"after",
"afterEach",
"requirejs",
"it"
],
"indent": false, // Specify indentation spacing
"devel": true, // Allow development statements e.g. `console.log();`.
"noempty": true // Prohibit use of empty blocks.
}

View File

@ -5,7 +5,7 @@ function ClassSpec(b) {
function Address() { function Address() {
Address.super(this, arguments); Address.super(this, arguments);
}; }
Address.superclass = superclass; Address.superclass = superclass;
superclass.applyEncodingsTo(Address); superclass.applyEncodingsTo(Address);
@ -13,10 +13,10 @@ function ClassSpec(b) {
Address.prototype.validate = function() { Address.prototype.validate = function() {
this.doAsBinary(function() { this.doAsBinary(function() {
Address.super(this, 'validate', arguments); Address.super(this, 'validate', arguments);
if(this.data.length != 21) throw new Error('invalid data length'); if(this.data.length !== 21) throw new Error('invalid data length');
}); });
}; };
return Address; return Address;
}; }
module.defineClass(ClassSpec); module.defineClass(ClassSpec);

48
Gruntfile.js Normal file
View File

@ -0,0 +1,48 @@
'use strict';
module.exports = function(grunt) {
//Load NPM tasks
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-mocha-test');
// Project Configuration
grunt.initConfig({
browserify: {
client: {
src: ['bitcore.js'],
dest: 'browser/bundle.js',
options: {
debug: true,
alias: ['browserify-bignum/bignumber.js:bignum'],
standalone: 'bitcore',
}
},
vendor: {
src: ['browser/vendor_load.js'],
dest: 'browser/vendor.js',
options: {
}
}
},
watch: {
scripts: {
files: ['**/*.js', '**/*.html', '!**/node_modules/**', '!**/bundle.js', '!**/vendor.js'],
tasks: ['browserify'/*, 'mochaTest'*/],
},
},
mochaTest: {
options: {
reporter: 'spec',
},
src: ['test/*.js'],
},
});
grunt.registerTask('default', ['watch']);
};

View File

@ -4,7 +4,8 @@ function spec(b) {
var config = b.config || require('./config'); var config = b.config || require('./config');
var log = b.log || require('./util/log'); var log = b.log || require('./util/log');
var network = b.network || require('./networks')[config.network]; var network = b.network || require('./networks')[config.network];
var Connection = b.Connection || require('./Connection').createClass({config: config}); var Connection = b.Connection || require('./Connection').createClass(
{config: config, network: network});
var Peer = b.Peer || require('./Peer').class(); var Peer = b.Peer || require('./Peer').class();
var noop = function() {}; var noop = function() {};

View File

@ -6,7 +6,7 @@ A pure, powerful core for your bitcoin project.
Bitcore is a complete, native interface to the Bitcoin network, and provides the core functionality needed to develop apps for bitcoin. Bitcore is a complete, native interface to the Bitcoin network, and provides the core functionality needed to develop apps for bitcoin.
#Principles #Principles
Bitcoin is a powerful new peer-to-peer platform for the next generation of financial technology. The decentralized nature of the Bitcoin network allows for highly resilient bitcoin infrastructure, but the developer community needs reliable, open-source tools to implement bitcoin apps and services. Bitcoin is a powerful new peer-to-peer platform for the next generation of financial technology. The decentralized nature of the Bitcoin network allows for highly resilient bitcoin infrastructure, and the developer community needs reliable, open-source tools to implement bitcoin apps and services.
**Bitcore unchains developers from fallible, centralized APIs, and provides the tools to interact with the real Bitcoin network.** **Bitcore unchains developers from fallible, centralized APIs, and provides the tools to interact with the real Bitcoin network.**
@ -17,7 +17,7 @@ Bitcore runs on [node](http://nodejs.org/), and can be installed via [npm](https
npm install bitcore npm install bitcore
``` ```
It's is a collection of objects useful to bitcoin applications; class-like idioms are enabled via [Classtool](https://github.com/gasteve/classtool). In most cases, a developer will require the object's class directly: It is a collection of objects useful to bitcoin applications; class-like idioms are enabled via [Classtool](https://github.com/gasteve/classtool). In most cases, a developer will require the object's class directly:
``` ```
var Address = require('bitcore/Address').class(); var Address = require('bitcore/Address').class();
``` ```
@ -46,7 +46,11 @@ Bitcore is still under heavy development and not quite ready for "drop-in" produ
#Contributing #Contributing
Bitcore needs some developer love. Please send pull requests for bug fixes, code optimization, and ideas for improvement. Bitcore needs some developer love. Please send pull requests for bug fixes, code optimization, and ideas for improvement.
To build bitcore for the browser:
```
npm install -g grunt-cli
grunt browserify
```
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/bitpay/bitcore/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/dreyzehner/bitcore/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

View File

@ -164,9 +164,14 @@ function ClassSpec(b) {
}); });
res.on('end', function() { res.on('end', function() {
if(res.statusCode == 401) { if(res.statusCode == 401) {
callback(new Error('bitcoin JSON-RPC connection rejected: unauthorized')); callback(new Error('bitcoin JSON-RPC connection rejected: 401 unauthorized'));
return; return;
} }
if(res.statusCode == 403) {
callback(new Error('bitcoin JSON-RPC connection rejected: 403 forbidden'));
return;
}
if(err) { if(err) {
callback(err); callback(err);
return; return;
@ -176,6 +181,7 @@ function ClassSpec(b) {
} catch(e) { } catch(e) {
log.err(e.stack); log.err(e.stack);
log.err(buf); log.err(buf);
log.err('HTTP Status code:' + res.statusCode);
callback(e); callback(e);
return; return;
} }

16
bitcore.js Normal file
View File

@ -0,0 +1,16 @@
/*
* Bitcore bindings for the browser
*/
module.exports.bignum = require('bignum');
module.exports.base58 = require('base58-native');
module.exports.EncodedData = require('./util/EncodedData');
module.exports.VersionedData = require('./util/VersionedData');
module.exports.Address= require('./Address');
if (typeof process.versions === 'undefined') {
module.exports.bignum.config({EXPONENTIAL_AT: 9999999, DECIMAL_PLACES: 0, ROUNDING_MODE: 1});
}

12
browser/sample.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="bundle.js"></script>
</head>
<body>
<script type="text/javascript">
</script>
</body>
</html>

5
browser/vendor_load.js Normal file
View File

@ -0,0 +1,5 @@
// load modules needed for testing in the browser
var fs = require('fs');

View File

@ -7,9 +7,15 @@
"email": "stephen@bitpay.com" "email": "stephen@bitpay.com"
}, },
"contributors": [ "contributors": [
{"name": "Stefan Thomas", "email": "moon@justmoon.net"}, {
{"name": "Jeff Garzik", "email": "jgarzik@bitpay.com"} "name": "Stefan Thomas",
], "email": "moon@justmoon.net"
},
{
"name": "Jeff Garzik",
"email": "jgarzik@bitpay.com"
}
],
"keywords": [ "keywords": [
"bitcoin", "bitcoin",
"btc", "btc",
@ -25,16 +31,22 @@
"scripts": {}, "scripts": {},
"dependencies": { "dependencies": {
"classtool": "=1.0.0", "classtool": "=1.0.0",
"base58-native": "=0.1.1", "base58-native": "=0.1.3",
"bindings": "=1.1.0", "bindings": "=1.1.1",
"bufferput": "=0.1.1", "bufferput": "=0.1.1",
"bignum": "=0.6.1", "bignum": "=0.6.1",
"binary": "=0.3.0", "binary": "=0.3.0",
"step": "=0.0.4", "step": "=0.0.4",
"buffers": "=0.1.1", "buffers": "=0.1.1",
"buffertools": "=1.1.1", "buffertools": "=1.1.1",
"mocha": ">=1.15.1" "mocha": ">=1.15.1",
"browserify-bignum": "git://github.com/maraoz/browserify-bignum.git"
},
"devDependencies": {
"grunt-contrib-watch": "~0.5.3",
"grunt-mocha-test": "~0.8.2",
"grunt-browserify": "~1.3.0",
"chai": "~1.9.0"
}, },
"devDependencies": {},
"license": "MIT" "license": "MIT"
} }

23
test/adapter.js Normal file
View File

@ -0,0 +1,23 @@
'use strict';
if (typeof require === 'undefined') {
var that = this;
that.require = function(name) {
var split = name.split('/');
if (split.length > 0) {
name = split.pop();
}
var module = that[name];
if (!module) {
throw new Error('Cannot find module "'+name+'"');
}
return module;
};
}
if (typeof module === 'undefined') {
var that = this;
that.module = bitcore.module;
}

27
test/index.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>Mocha</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script src="../browser/vendor.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../browser/bundle.js"></script>
<script src="adapter.js"></script>
<script src="test.main.js"></script>
<script src="test.base58.js"></script>
<script src="test.EncodedData.js"></script>
<script src="test.VersionedData.js"></script>
<script src="test.Address.js"></script>
<script>
mocha.run();
</script>
</body>
</html>

36
test/test.Address.js Normal file
View File

@ -0,0 +1,36 @@
'use strict';
var chai = require('chai');
var bitcore = require('../bitcore');
var should = chai.should();
var AddressModule = bitcore.Address;
var Address;
describe('Address', function() {
it('should initialze the main object', function() {
should.exist(AddressModule);
});
it('should be able to create class', function() {
Address = AddressModule.class();
should.exist(Address);
});
it('should be able to create Address object', function() {
var a = new Address('1KfyjCgBSMsLqiCbakfSdeoBUqMqLUiu3T');
should.exist(a);
});
it('should validate correctly', function() {
var a = new Address("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa");
var m = new Address("32QBdjycLwbDTuGafUwaU5p5GxzSLPYoF6");
var b = new Address("11111111111111111111111111122222234");
a.validate.bind(a).should.not.throw(Error);
m.validate.bind(m).should.not.throw(Error);
b.validate.bind(b).should.throw(Error);
});
});

28
test/test.EncodedData.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
var chai = require('chai');
var bitcore = require('../bitcore');
var should = chai.should();
var EncodedDataModule = bitcore.EncodedData;
var EncodedData;
describe('EncodedData', function() {
it('should initialze the main object', function() {
should.exist(EncodedDataModule);
});
it('should be able to create class', function() {
EncodedData = EncodedDataModule.class();
should.exist(EncodedData);
});
it('should be able to create an instance', function() {
var ed = new EncodedData('1GMx4HdDmN78xzGvdQYkwrVqkmLDG1aMNT');
should.exist(ed);
});
});

View File

@ -0,0 +1,34 @@
'use strict';
var chai = require('chai');
var bitcore = require('../bitcore');
var should = chai.should();
var VersionedDataModule = bitcore.VersionedData;
var VersionedData;
describe('VersionedData', function() {
it('should initialze the main object', function() {
should.exist(VersionedDataModule);
});
it('should be able to create class', function() {
VersionedData = VersionedDataModule.class();
should.exist(VersionedData);
});
it('should be able to create an instance', function() {
var vd = new VersionedData();
should.exist(vd);
});
it('should get correct version', function() {
var vda = new VersionedData('1GMx4HdDmN78xzGvdQYkwrVqkmLDG1aMNT');
var vdb = new VersionedData('3746djr32k2Lp23UUbdkCTQ6zhMJ7d8MD7');
vda.version().should.equal(0);
vdb.version().should.equal(5);
});
});

45
test/test.base58.js Normal file
View File

@ -0,0 +1,45 @@
'use strict';
var chai = require('chai');
var bitcore = require('../bitcore');
var expect = chai.expect;
var should = chai.should();
var bignum = bitcore.bignum;
var base58 = bitcore.base58;
var base58Check = base58.base58Check;
describe('bignum module basics', function() {
it('should initialze the main object', function() {
should.exist(bitcore.bignum);
});
it('should create a bignum from string', function() {
var n = bignum('9832087987979879879879879879879879879879879879');
should.exist(n);
});
it('should perform basic math operations', function() {
var b = bignum('782910138827292261791972728324982')
.sub('182373273283402171237474774728373')
.div(13);
b.toNumber().should.equal(46195143503376160811884457968969);
});
});
describe('base58 module', function() {
it('should initialze the main object', function() {
should.exist(bitcore.base58);
});
it('should obtain the same string in base58 roundtrip', function() {
var m = 'mqqa8xSMVDyf9QxihGnPtap6Mh6qemUkcu';
base58.encode(base58.decode(m)).should.equal(m);
});
it('should obtain the same string in base58Check roundtrip', function() {
var m = '1QCJj1gPZKx2EwzGo9Ri8mMBs39STvDYcv';
base58Check.encode(base58Check.decode(m)).should.equal(m);
});
});

View File

@ -1,3 +1,4 @@
'use strict';
var assert = require('assert'); var assert = require('assert');
var fs = require('fs'); var fs = require('fs');

13
test/test.main.js Normal file
View File

@ -0,0 +1,13 @@
'use strict';
var chai = require('chai');
var bitcore = require('../bitcore');
var expect = chai.expect;
var should = chai.should();
describe('Initialization of bitcore', function() {
it('should initialze the main object', function() {
should.exist(bitcore);
});
});

View File

@ -130,17 +130,20 @@ function ClassSpec(b) {
}, },
}; };
var no_conversion = function() {return this.data;};
for(var k in encodings) { for(var k in encodings) {
if(!encodings[k].converters[k]) if(encodings.hasOwnProperty(k)){
encodings[k].converters[k] = function() {return this.data;}; if(!encodings[k].converters[k])
encodings[k]._encoding = k; encodings[k].converters[k] = no_conversion;
encodings[k]._encoding = k;
}
} }
EncodedData.applyEncodingsTo = function(aClass) { EncodedData.applyEncodingsTo = function(aClass) {
var tmp = {}; var tmp = {};
for(var k in encodings) { for(var k in encodings) {
var enc = encodings[k]; var enc = encodings[k];
var obj = {}; var obj = {};
for(var j in enc) { for(var j in enc) {
obj[j] = enc[j]; obj[j] = enc[j];
} }
@ -152,5 +155,5 @@ function ClassSpec(b) {
EncodedData.applyEncodingsTo(EncodedData); EncodedData.applyEncodingsTo(EncodedData);
return EncodedData; return EncodedData;
}; }
module.defineClass(ClassSpec); module.defineClass(ClassSpec);