web3.js/lib/web3/filter.js

186 lines
5.7 KiB
JavaScript
Raw Normal View History

2015-01-13 18:28:49 +01:00
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file filter.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
2015-03-12 16:33:19 +01:00
* Fabian Vogelsteller <fabian@ethdev.com>
2015-01-13 18:28:49 +01:00
* Gav Wood <g@ethdev.com>
* @date 2014
*/
2015-03-08 18:18:52 +01:00
var utils = require('../utils/utils');
2015-02-05 23:11:16 +01:00
/// Should be called to check if filter implementation is valid
/// @returns true if it is, otherwise false
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
typeof i.getLogs === 'function' &&
2015-02-05 23:11:16 +01:00
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
2015-01-13 18:28:49 +01:00
};
2015-02-05 23:11:16 +01:00
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
/// @param should be string or object
/// @returns options string or object
var getOptions = function (options) {
2015-02-05 23:11:16 +01:00
if (typeof options === 'string') {
return options;
}
2015-01-13 18:28:49 +01:00
2015-02-05 23:11:16 +01:00
options = options || {};
2015-01-13 18:28:49 +01:00
2015-03-10 14:49:23 +01:00
if (options.topic) {
console.warn('"topic" is deprecated, is "topics" instead');
options.topics = options.topic;
}
if (options.earliest) {
console.warn('"earliest" is deprecated, is "fromBlock" instead');
options.fromBlock = options.earliest;
}
if (options.latest) {
console.warn('"latest" is deprecated, is "toBlock" instead');
options.toBlock = options.latest;
}
if (options.skip) {
console.warn('"skip" is deprecated, is "offset" instead');
options.offset = options.skip;
}
if (options.max) {
console.warn('"max" is deprecated, is "limit" instead');
options.limit = options.max;
}
// make sure topics, get converted to hex
2015-03-10 14:49:23 +01:00
if(options.topics instanceof Array) {
options.topics = options.topics.map(function(topic){
return utils.toHex(topic);
});
2015-01-13 18:28:49 +01:00
}
2015-03-24 11:16:21 +01:00
var filterOptions = {};
if(options.topics)
filterOptions.topics = options.topics;
if(options.to)
filterOptions.to = options.to;
if(options.address)
filterOptions.address = options.address;
if(typeof options.fromBlock !== 'undefined')
filterOptions.fromBlock = utils.toHex(options.fromBlock);
if(typeof options.toBlock !== 'undefined')
filterOptions.toBlock = utils.toHex(options.toBlock);
return filterOptions;
2015-01-13 18:28:49 +01:00
};
2015-02-05 23:11:16 +01:00
/// Should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// @param options are filter options
/// @param implementation, an abstract polling implementation
/// @param formatter (optional), callback function which formats output before 'real' callback
var filter = function(options, implementation, formatter) {
if (!implementationIsValid(implementation)) {
console.error('filter implemenation is invalid');
return;
}
2015-01-13 18:28:49 +01:00
2015-02-05 23:11:16 +01:00
options = getOptions(options);
var callbacks = [];
var filterId = implementation.newFilter(options);
2015-02-27 12:41:07 +01:00
// call the callbacks
2015-02-05 23:11:16 +01:00
var onMessages = function (messages) {
messages.forEach(function (message) {
message = formatter ? formatter(message) : message;
2015-02-05 23:11:16 +01:00
callbacks.forEach(function (callback) {
callback(message);
});
});
};
var watch = function(callback) {
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
2015-02-05 23:11:16 +01:00
callbacks.push(callback);
};
var stopWatching = function() {
implementation.stopPolling(filterId);
callbacks = [];
};
var uninstall = function() {
2015-02-05 23:11:16 +01:00
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
var get = function () {
2015-03-10 17:07:16 +01:00
var results = implementation.getLogs(filterId);
2015-03-11 10:24:03 +01:00
return utils.isArray(results) ? results.map(function(message){
2015-03-10 17:07:16 +01:00
return formatter ? formatter(message) : message;
2015-03-11 10:24:03 +01:00
}) : results;
};
2015-02-05 23:11:16 +01:00
return {
watch: watch,
stopWatching: stopWatching,
get: get,
uninstall: uninstall,
// DEPRECATED methods
changed: function(){
2015-02-25 17:01:23 +01:00
console.warn('watch().changed() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
arrived: function(){
2015-02-25 17:01:23 +01:00
console.warn('watch().arrived() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
happened: function(){
2015-02-25 17:01:23 +01:00
console.warn('watch().happened() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
messages: function(){
2015-02-25 17:01:23 +01:00
console.warn('watch().messages() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
},
logs: function(){
2015-02-25 17:01:23 +01:00
console.warn('watch().logs() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
}
2015-02-05 23:11:16 +01:00
};
2015-01-13 18:28:49 +01:00
};
2015-02-05 23:11:16 +01:00
module.exports = filter;