github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/cmd/mist/assets/ext/ethereum.js/lib/event.js (about) 1 /* 2 This file is part of ethereum.js. 3 4 ethereum.js is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 ethereum.js is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with ethereum.js. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 /** @file event.js 18 * @authors: 19 * Marek Kotewicz <marek@ethdev.com> 20 * @date 2014 21 */ 22 23 var abi = require('./abi'); 24 var utils = require('./utils'); 25 26 /// filter inputs array && returns only indexed (or not) inputs 27 /// @param inputs array 28 /// @param bool if result should be an array of indexed params on not 29 /// @returns array of (not?) indexed params 30 var filterInputs = function (inputs, indexed) { 31 return inputs.filter(function (current) { 32 return current.indexed === indexed; 33 }); 34 }; 35 36 var inputWithName = function (inputs, name) { 37 var index = utils.findIndex(inputs, function (input) { 38 return input.name === name; 39 }); 40 41 if (index === -1) { 42 console.error('indexed param with name ' + name + ' not found'); 43 return undefined; 44 } 45 return inputs[index]; 46 }; 47 48 var indexedParamsToTopics = function (event, indexed) { 49 // sort keys? 50 return Object.keys(indexed).map(function (key) { 51 var inputs = [inputWithName(filterInputs(event.inputs, true), key)]; 52 53 var value = indexed[key]; 54 if (value instanceof Array) { 55 return value.map(function (v) { 56 return abi.formatInput(inputs, [v]); 57 }); 58 } 59 return abi.formatInput(inputs, [value]); 60 }); 61 }; 62 63 var inputParser = function (address, signature, event) { 64 65 // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.watch' 66 return function (indexed, options) { 67 var o = options || {}; 68 o.address = address; 69 o.topic = []; 70 o.topic.push(signature); 71 if (indexed) { 72 o.topic = o.topic.concat(indexedParamsToTopics(event, indexed)); 73 } 74 return o; 75 }; 76 }; 77 78 var getArgumentsObject = function (inputs, indexed, notIndexed) { 79 var indexedCopy = indexed.slice(); 80 var notIndexedCopy = notIndexed.slice(); 81 return inputs.reduce(function (acc, current) { 82 var value; 83 if (current.indexed) 84 value = indexed.splice(0, 1)[0]; 85 else 86 value = notIndexed.splice(0, 1)[0]; 87 88 acc[current.name] = value; 89 return acc; 90 }, {}); 91 }; 92 93 var outputParser = function (event) { 94 95 return function (output) { 96 var result = { 97 event: utils.extractDisplayName(event.name), 98 number: output.number, 99 args: {} 100 }; 101 102 if (!output.topic) { 103 return result; 104 } 105 106 var indexedOutputs = filterInputs(event.inputs, true); 107 var indexedData = "0x" + output.topic.slice(1, output.topic.length).map(function (topic) { return topic.slice(2); }).join(""); 108 var indexedRes = abi.formatOutput(indexedOutputs, indexedData); 109 110 var notIndexedOutputs = filterInputs(event.inputs, false); 111 var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data); 112 113 result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes); 114 115 return result; 116 }; 117 }; 118 119 var getMatchingEvent = function (events, payload) { 120 for (var i = 0; i < events.length; i++) { 121 var signature = abi.eventSignatureFromAscii(events[i].name); 122 if (signature === payload.topic[0]) { 123 return events[i]; 124 } 125 } 126 return undefined; 127 }; 128 129 130 module.exports = { 131 inputParser: inputParser, 132 outputParser: outputParser, 133 getMatchingEvent: getMatchingEvent 134 }; 135