Add documentation
This commit is contained in:
parent
c9951be2dc
commit
db4561f834
|
@ -0,0 +1,44 @@
|
||||||
|
# URI
|
||||||
|
|
||||||
|
Represents a bitcoin payment uri. Bitcoin URI strings became the most popular
|
||||||
|
way to share payment request, sometimes as a bitcoin link and others using a QR code.
|
||||||
|
|
||||||
|
URI Examples:
|
||||||
|
```
|
||||||
|
bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu
|
||||||
|
bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2
|
||||||
|
bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2&message=Payment&label=Satoshi&extra=other-param
|
||||||
|
```
|
||||||
|
|
||||||
|
The main use that we expect you'll have for the `URI` class in bitcore is
|
||||||
|
validating and parsing bitcoin URIs. A `URI` instance exposes the address as a
|
||||||
|
bitcore `Address` object and the amount in Satoshis, if present.
|
||||||
|
|
||||||
|
The code for validating uris looks like this:
|
||||||
|
```javascript
|
||||||
|
var uriString = 'bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2';
|
||||||
|
var valid = URI.isValid(uriString);
|
||||||
|
var uri = new URI(uriString);
|
||||||
|
console.log(uri.address.network, uri.amount); // 'livenet', 120000000
|
||||||
|
```
|
||||||
|
|
||||||
|
All standard parameters can be found as members of the `URI` instance. However
|
||||||
|
a bitcoin uri may contain other non-standard parameters, all those can be found
|
||||||
|
under the `extra` namespace.
|
||||||
|
|
||||||
|
See [the official BIP21 spec](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki)
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
Other usecase important usecase for the `URI` class is creating a bitcoin URI for
|
||||||
|
sharing a payment request. That can be acomplished by using an Object to create
|
||||||
|
an instance of URI.
|
||||||
|
|
||||||
|
The code for creating an URI from an Object looks like this:
|
||||||
|
```javascript
|
||||||
|
var uriString = new URI({
|
||||||
|
address: '12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu',
|
||||||
|
amount : 10000, // in satoshis
|
||||||
|
message: 'My payment request'
|
||||||
|
});
|
||||||
|
var uriString = uri.toString();
|
||||||
|
```
|
|
@ -329,7 +329,7 @@ Address.getValidationError = function(data, network, type) {
|
||||||
* @param {String} data - The encoded data
|
* @param {String} data - The encoded data
|
||||||
* @param {String} network - The network: 'mainnet' or 'testnet'
|
* @param {String} network - The network: 'mainnet' or 'testnet'
|
||||||
* @param {String} type - The type of address: 'script' or 'pubkey'
|
* @param {String} type - The type of address: 'script' or 'pubkey'
|
||||||
* @returns {null|Error} The corresponding error message
|
* @returns {boolean} The corresponding error message
|
||||||
*/
|
*/
|
||||||
Address.isValid = function(data, network, type) {
|
Address.isValid = function(data, network, type) {
|
||||||
return !Address.getValidationError(data, network, type);
|
return !Address.getValidationError(data, network, type);
|
||||||
|
|
98
lib/uri.js
98
lib/uri.js
|
@ -1,34 +1,79 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var URL = require('url');
|
var URL = require('url');
|
||||||
|
|
||||||
var Address = require('./address');
|
var Address = require('./address');
|
||||||
|
|
||||||
var URI = function(arg, knownArgs) {
|
/**
|
||||||
|
*
|
||||||
|
* Bitcore URI
|
||||||
|
*
|
||||||
|
* Instantiate an URI from a bitcoin URI String or an Object. An URI instance
|
||||||
|
* can be created with a bitcoin uri string or an object. All instances of
|
||||||
|
* URI are valid, the static method isValid allows checking before instanciation.
|
||||||
|
*
|
||||||
|
* All standard parameters can be found as members of the class, the address
|
||||||
|
* is represented using an {Address} instance and the amount is represented in
|
||||||
|
* satoshis. Any other non-standard parameters can be found under the extra member.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* var uri = new URI('bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu?amount=1.2');
|
||||||
|
* console.log(uri.address, uri.amount);
|
||||||
|
*
|
||||||
|
* @param {string|Object} data - A bitcoin URI string or an Object
|
||||||
|
* @param {Array.<string>} [knownParams] - Required non-standard params
|
||||||
|
* @throws {TypeError} Invalid bitcoin address
|
||||||
|
* @throws {TypeError} Invalid amount
|
||||||
|
* @throws {Error} Unknown required argument
|
||||||
|
* @returns {URI} A new valid and frozen instance of URI
|
||||||
|
*/
|
||||||
|
var URI = function(data, knownParams) {
|
||||||
this.extras = {};
|
this.extras = {};
|
||||||
this.knownArgs = knownArgs || [];
|
this.knownParams = knownParams || [];
|
||||||
this.address = this.network = this.amount = this.message = null;
|
this.address = this.network = this.amount = this.message = null;
|
||||||
|
|
||||||
if (typeof(arg) == 'string') {
|
if (typeof(data) == 'string') {
|
||||||
var params = URI.parse(arg);
|
var params = URI.parse(data);
|
||||||
this._fromObject(params);
|
this._fromObject(params);
|
||||||
} else if (typeof(arg) == 'object') {
|
} else if (typeof(data) == 'object') {
|
||||||
this._fromObject(arg);
|
this._fromObject(data);
|
||||||
} else {
|
} else {
|
||||||
throw new TypeError('Unrecognized data format.');
|
throw new TypeError('Unrecognized data format.');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
URI.isValid = function(arg, knownArgs) {
|
/**
|
||||||
|
*
|
||||||
|
* Check if an bitcoin URI string is valid
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* var valid = URI.isValid('bitcoin:12A1MyfXbW6RhdRAZEqofac5jCQQjwEPBu');
|
||||||
|
* // true
|
||||||
|
*
|
||||||
|
* @param {string|Object} data - A bitcoin URI string or an Object
|
||||||
|
* @param {Array.<string>} [knownParams] - Required non-standard params
|
||||||
|
* @returns {boolean} Result of uri validation
|
||||||
|
*/
|
||||||
|
URI.isValid = function(arg, knownParams) {
|
||||||
try {
|
try {
|
||||||
var uri = new URI(arg, knownArgs);
|
var uri = new URI(arg, knownParams);
|
||||||
return true;
|
return true;
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Convert a bitcoin URI string into a simple object.
|
||||||
|
*
|
||||||
|
* @param {string} uri - A bitcoin URI string
|
||||||
|
* @throws {TypeError} Invalid bitcoin URI
|
||||||
|
* @returns {Object} An object with the parsed params
|
||||||
|
*/
|
||||||
URI.parse = function(uri) {
|
URI.parse = function(uri) {
|
||||||
var info = URL.parse(uri, true);
|
var info = URL.parse(uri, true);
|
||||||
|
|
||||||
|
@ -43,9 +88,17 @@ URI.parse = function(uri) {
|
||||||
return info.query;
|
return info.query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Internal function to load the URI instance with an object.
|
||||||
|
*
|
||||||
|
* @param {Object} amount - Amount BTC string
|
||||||
|
* @throws {TypeError} Invalid bitcoin address
|
||||||
|
* @throws {TypeError} Invalid amount
|
||||||
|
* @throws {Error} Unknown required argument
|
||||||
|
*/
|
||||||
URI.prototype._fromObject = function(obj) {
|
URI.prototype._fromObject = function(obj) {
|
||||||
var members = ['address', 'amount', 'message', 'label'];
|
var members = ['address', 'amount', 'message', 'label', 'r'];
|
||||||
|
|
||||||
if (!Address.isValid(obj.address)) throw new TypeError('Invalid bitcoin address');
|
if (!Address.isValid(obj.address)) throw new TypeError('Invalid bitcoin address');
|
||||||
|
|
||||||
|
@ -57,7 +110,7 @@ URI.prototype._fromObject = function(obj) {
|
||||||
for (var key in obj) {
|
for (var key in obj) {
|
||||||
if (key === 'address' || key === 'amount') continue;
|
if (key === 'address' || key === 'amount') continue;
|
||||||
|
|
||||||
if (/^req-/.exec(key) && this.knownArgs.indexOf(key) === -1) {
|
if (/^req-/.exec(key) && this.knownParams.indexOf(key) === -1) {
|
||||||
throw Error('Unknown required argument ' + key);
|
throw Error('Unknown required argument ' + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,13 +119,26 @@ URI.prototype._fromObject = function(obj) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Internal function to transform a BTC string amount into satoshis
|
||||||
|
*
|
||||||
|
* @param {String} amount - Amount BTC string
|
||||||
|
* @throws {TypeError} Invalid amount
|
||||||
|
* @returns {Object} Amount represented in satoshis
|
||||||
|
*/
|
||||||
URI.prototype._parseAmount = function(amount) {
|
URI.prototype._parseAmount = function(amount) {
|
||||||
var amount = Number(amount);
|
var amount = Number(amount);
|
||||||
if (isNaN(amount)) throw new TypeError('Invalid amount');
|
if (isNaN(amount)) throw new TypeError('Invalid amount');
|
||||||
return amount; // TODO: Convert to Satoshis (yemel)
|
return amount; // TODO: Convert to Satoshis (yemel)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return a the string representation of the URI
|
||||||
|
*
|
||||||
|
* @returns {String} Bitcoin URI string
|
||||||
|
*/
|
||||||
URI.prototype.toString = function() {
|
URI.prototype.toString = function() {
|
||||||
var query = _.clone(this.extras);
|
var query = _.clone(this.extras);
|
||||||
if (this.amount) query.amount = this.amount; // TODO: Convert to BTC (yemel)
|
if (this.amount) query.amount = this.amount; // TODO: Convert to BTC (yemel)
|
||||||
|
@ -85,6 +151,12 @@ URI.prototype.toString = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return a string formatted for the console
|
||||||
|
*
|
||||||
|
* @returns {String} Bitcoin URI
|
||||||
|
*/
|
||||||
URI.prototype.inspect = function() {
|
URI.prototype.inspect = function() {
|
||||||
return '<URI: ' + this.toString()+ '>';
|
return '<URI: ' + this.toString()+ '>';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue