├── .babelrc ├── .gitignore ├── Readme.md ├── dist └── etherest.min.js ├── lib ├── address.js ├── etherest.js ├── query.js ├── request.browser.js └── request.js ├── package.json └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-object-assign", 4 | ["transform-runtime", { 5 | "helpers": false, 6 | "polyfill": false, 7 | "regenerator": false, 8 | "moduleName": "babel-runtime" 9 | }] 10 | ] 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | *.DS_Store 4 | *.sublime* 5 | 6 | test.js 7 | spec.js -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # ETHEREST JavaScript Client 2 | 3 | [ETHEREST](https://www.etherest.io) provides a simple way to make calls and transactions to the Ethereum blockchain using a REST-like API. This library is a lightweight and flexible interface to the API which can be used in both Node.js and browser based projects. It's a fast way to start getting data from and mutating the blockchain without running your own node. 4 | 5 | # Installation 6 | 7 | ## Node.js 8 | 9 | You can install ETHEREST as an npm module: `npm install etherest` 10 | 11 | As well as using server side, it's safe to webpack or browserify the npm module for use in browsers. 12 | 13 | ## Browsers 14 | 15 | A standalone library for web browsers is also provided which can be embeded onto your page using jsdlvr's npm cdn: 16 | 17 | `` 18 | 19 | The browser script defines a global variable `Etherest` which is the same as the entry point of the default export of the npm module. 20 | 21 | # Example Usage 22 | 23 | ## Call Without an ABI ([Sandiwch Shop](https://www.etherest.io/main/0x4dc924EeB4D87ab938f5a72fC0ef4460f6b35a8A/getSandwichInfoCaloriesPrice/2)) 24 | 25 | ```javascript 26 | Etherest 27 | .address('0x4dc924EeB4D87ab938f5a72fC0ef4460f6b35a8A') 28 | .method('getSandwichInfoCaloriesPrice') 29 | .param(2, 'uint') 30 | .returns(['string', 'string', 'string', 'uint256']) 31 | .call() 32 | .then(function (result) { 33 | console.log("Got info from the sandwich shop!"); 34 | console.log(result); 35 | }); 36 | ``` 37 | 38 | ## Transaction ([Rouleth](https://www.etherest.io/main/0x91A57B2F6FA86B373Bce5716eb26C81cbb004223/betOnNumber/7)) 39 | 40 | ```javascript 41 | Etherest 42 | .address('0x91A57B2F6FA86B373Bce5716eb26C81cbb004223') 43 | .method('betOnNumber') 44 | .param(7, 'uint') 45 | .sendTransaction({ 46 | from: '0xd3c14E7E6Feb41d8210412fc77ef94a72d8B089b', 47 | privateKey: '5172eb05eb9b27e15d4fe963157967b2d6e13e128e79d9b6dc27acf4dcf654ab', 48 | value: 0.01 49 | }) 50 | .then(function (txid) { 51 | console.log("Transaction ID: " + txid); 52 | }); 53 | ``` 54 | 55 | ## Call Using a Public ABI ([Basic Attention Token](https://www.etherest.io/main/0x0D8775F648430679A709E98d2b0Cb6250d2887EF/tokenExchangeRate)) 56 | 57 | ```javascript 58 | Etherest 59 | .address('0x0D8775F648430679A709E98d2b0Cb6250d2887EF') 60 | .loadAbi() 61 | .then(function (basicAttentionToken) { 62 | basicAttentionToken 63 | .tokenExchangeRate() 64 | .then(function (rate) { 65 | console.log("1 ETH = " + rate + " Basic Attention Tokens"); 66 | }); 67 | }); 68 | ``` 69 | 70 | Got a private abi you want to use instead? Just provide it by calling `Etherest.address(...).abi([...])`. See the full documentation below for a deep dive into the library's full functionality. 71 | 72 | ## Etherest API 73 | 74 | To learn more about the ETHEREST API check out some of our getting started guides: 75 | 76 | * [Introducing ΞTHEREST — the easiest way to interact with the Ethereum Blockchain](https://blog.w3k.it/introducing-%CE%BEtherest-the-easiest-way-to-interact-with-the-ethereum-blockchain-fab0235f2180) 77 | * [Automate your ÐICE dividend collection every quarter with ΞTHEREST](https://blog.w3k.it/automate-your-%C3%B0ice-dividend-collection-every-quarter-without-hassle-48bee072b2f7) 78 | * [Making a call to Ethereum’s pre-eminent eating establishment](https://blog.w3k.it/making-a-call-to-ethereums-pre-eminent-eating-establishment-1545cd44c240) 79 | 80 | # Full Documentation 81 | 82 | 83 | 84 | ## Etherest 85 | **Kind**: global class 86 | 87 | * [Etherest](#Etherest) 88 | * [new Etherest([options])](#new_Etherest_new) 89 | * [.address(address, [network])](#Etherest+address) ⇒ Address 90 | * [.request([options])](#Etherest+request) ⇒ Promise 91 | * [.call([path])](#Etherest+call) ⇒ Promise 92 | * [.sendTransaction([path], options)](#Etherest+sendTransaction) ⇒ Promise 93 | 94 | 95 | 96 | ### new Etherest([options]) 97 | The main entry point to the client library, can be instantiated or used as a static class upon which all instance methods are available 98 | 99 | **Returns**: [Etherest](#Etherest) - new Etherest instance 100 | 101 | | Param | Type | Description | 102 | | --- | --- | --- | 103 | | [options] | Object | options to pass in to a new etherest instance | 104 | | [options.server] | string | url for the api server to use, allows you to roll your own Etherest instance with our open source code | 105 | | [options.apiKey] | string | api key to send with requests | 106 | 107 | 108 | 109 | ### etherest.address(address, [network]) ⇒ Address 110 | Creates a new address object linked to this etherest instance for executing queries against 111 | 112 | **Kind**: instance method of [Etherest](#Etherest) 113 | **Returns**: Address - new address instance 114 | 115 | | Param | Type | Description | 116 | | --- | --- | --- | 117 | | address | string | the address to instantiate the object with | 118 | | [network] | string | network the address is associated with (ie main, ropsten etc) | 119 | 120 | 121 | 122 | ### etherest.request([options]) ⇒ Promise 123 | Executes a request against this instance's etherest server 124 | 125 | **Kind**: instance method of [Etherest](#Etherest) 126 | **Returns**: Promise - promise which resolves when the request is complete with the response from etherest 127 | 128 | | Param | Type | Description | 129 | | --- | --- | --- | 130 | | [options] | Object | custom options for the request (see request and browser-request for supported options) | 131 | 132 | 133 | 134 | ### etherest.call([path]) ⇒ Promise 135 | Executes a call request against the etherest server 136 | 137 | **Kind**: instance method of [Etherest](#Etherest) 138 | **Returns**: Promise - promise which resolves when the call is completed with the data returned from etherest 139 | 140 | | Param | Type | Description | 141 | | --- | --- | --- | 142 | | [path] | string | path to call relative to the base URL of the server | 143 | 144 | 145 | 146 | ### etherest.sendTransaction([path], options) ⇒ Promise 147 | Sends a transaction to the etherest server 148 | 149 | **Kind**: instance method of [Etherest](#Etherest) 150 | **Returns**: Promise - a promise which resolves when the transaction has been submitted with an Ethereum txid 151 | 152 | | Param | Type | Description | 153 | | --- | --- | --- | 154 | | [path] | string | path to send the transaction to relative to the base URL of the server | 155 | | options | Object | options for the transaction, see options argument of Query.options | 156 | 157 | 158 | 159 | ## Address 160 | **Kind**: global class 161 | 162 | * [Address](#Address) 163 | * [new Address(etherest, address, [network])](#new_Address_new) 164 | * [.query(method, params)](#Address+query) ⇒ Query 165 | * [.method(name, ...param)](#Address+method) ⇒ Query 166 | * [.defineMethod(name, params, returns)](#Address+defineMethod) ⇒ function 167 | * [.defineCall(name, params, returns)](#Address+defineCall) ⇒ function 168 | * [.defineTransaction(name, params)](#Address+defineTransaction) ⇒ function 169 | * [.abi(abi)](#Address+abi) ⇒ [Address](#Address) 170 | * [.loadAbi()](#Address+loadAbi) ⇒ Promise 171 | * [.urlEncode(suffix)](#Address+urlEncode) ⇒ string 172 | * [.call(path)](#Address+call) ⇒ Promise 173 | * [.sendTransaction(path, options)](#Address+sendTransaction) ⇒ Promise 174 | 175 | 176 | 177 | ### new Address(etherest, address, [network]) 178 | Represents an address on the blockchain 179 | 180 | **Returns**: [Address](#Address) - new Address instance 181 | 182 | | Param | Type | Default | Description | 183 | | --- | --- | --- | --- | 184 | | etherest | Etherest | | etherest connection instance associated with this address | 185 | | address | string | | the ethereum address for this instance | 186 | | [network] | string | "main" | the network identifier this instance uses (ie main, ropsten, etc) | 187 | 188 | 189 | 190 | ### address.query(method, params) ⇒ Query 191 | Creates a new query object which is linked to this address instance 192 | 193 | **Kind**: instance method of [Address](#Address) 194 | **Returns**: Query - new query instance 195 | 196 | | Param | Type | Description | 197 | | --- | --- | --- | 198 | | method | string | name of the method which the query will call/sendTransaction against | 199 | | params | Array | array of params which will be passed with this query, can take the form of an array of values or value/type pairs. See constructor of Query | 200 | 201 | 202 | 203 | ### address.method(name, ...param) ⇒ Query 204 | Creates a new query object for a method with params passed in as arguments 205 | 206 | **Kind**: instance method of [Address](#Address) 207 | **Returns**: Query - new query instance 208 | 209 | | Param | Type | Description | 210 | | --- | --- | --- | 211 | | name | string | the name of the method to be used for this query | 212 | | ...param | \* | params to be passed to the query | 213 | 214 | 215 | 216 | ### address.defineMethod(name, params, returns) ⇒ function 217 | Add a method to this instance with a given name and list of param types which returns a query when invoked 218 | 219 | **Kind**: instance method of [Address](#Address) 220 | **Returns**: function - reference to the function defined 221 | 222 | | Param | Type | Description | 223 | | --- | --- | --- | 224 | | name | string | the name of the method to be used for this query | 225 | | params | Array | array of types of the params to be passed to this method as arguments | 226 | | returns | string | the return type of the method | 227 | 228 | 229 | 230 | ### address.defineCall(name, params, returns) ⇒ function 231 | Add a method to this instance with a given name and list of param types which performs a call when invoked 232 | 233 | **Kind**: instance method of [Address](#Address) 234 | **Returns**: function - reference to the function defined 235 | 236 | | Param | Type | Description | 237 | | --- | --- | --- | 238 | | name | string | the name of the method to be used for this query | 239 | | params | Array | array of types of the params to be passed to this method as arguments | 240 | | returns | string | the return type of the method | 241 | 242 | 243 | 244 | ### address.defineTransaction(name, params) ⇒ function 245 | Add a method to this instance with a given name and list of param types which creates a transaction when invoked 246 | 247 | **Kind**: instance method of [Address](#Address) 248 | **Returns**: function - reference to the function defined 249 | 250 | | Param | Type | Description | 251 | | --- | --- | --- | 252 | | name | string | the name of the method to be used for this query | 253 | | params | Array | array of types of the params to be passed to this method as arguments | 254 | 255 | 256 | 257 | ### address.abi(abi) ⇒ [Address](#Address) 258 | Create methods on this instance which match the definitions from a contract abi 259 | 260 | **Kind**: instance method of [Address](#Address) 261 | **Returns**: [Address](#Address) - reference to this object for chaining calls 262 | 263 | | Param | Type | Description | 264 | | --- | --- | --- | 265 | | abi | Array | application binary interface for this address | 266 | 267 | 268 | 269 | ### address.loadAbi() ⇒ Promise 270 | Load the abi publically associated with this address on etherest 271 | 272 | **Kind**: instance method of [Address](#Address) 273 | **Returns**: Promise - promise which resolves when the abi has been loaded with a reference to this address instance 274 | 275 | 276 | ### address.urlEncode(suffix) ⇒ string 277 | Gets the data for a request against an address encoded as a URL to send to etherest 278 | 279 | **Kind**: instance method of [Address](#Address) 280 | **Returns**: string - the encoded URL part to execute this query 281 | 282 | | Param | Type | Description | 283 | | --- | --- | --- | 284 | | suffix | string | additional string data to add to the end of the URL | 285 | 286 | 287 | 288 | ### address.call(path) ⇒ Promise 289 | Executes a call against this address 290 | 291 | **Kind**: instance method of [Address](#Address) 292 | **Returns**: Promise - a promise which resolves when the call has been completed with the value returned 293 | 294 | | Param | Type | Description | 295 | | --- | --- | --- | 296 | | path | string | a relative path from this address to execute the call against | 297 | 298 | 299 | 300 | ### address.sendTransaction(path, options) ⇒ Promise 301 | Sends a transaction to the etherest server 302 | 303 | **Kind**: instance method of [Address](#Address) 304 | **Returns**: Promise - a promise which resolves when the transaction has been submitted with an Ethereum txid 305 | 306 | | Param | Type | Description | 307 | | --- | --- | --- | 308 | | path | string | path to send the transaction to relative to this address | 309 | | options | Object | options for the transaction, see options argument of Query.options | 310 | 311 | 312 | 313 | ## Query 314 | **Kind**: global class 315 | 316 | * [Query](#Query) 317 | * [new Query([address], [method], params)](#new_Query_new) 318 | * [.param(value, [type])](#Query+param) ⇒ [Query](#Query) 319 | * [.returns(type)](#Query+returns) ⇒ [Query](#Query) 320 | * [.urlEncode()](#Query+urlEncode) ⇒ string 321 | * [.call(address)](#Query+call) ⇒ Promise 322 | * [.sendTransaction(address, options)](#Query+sendTransaction) ⇒ Promise 323 | 324 | 325 | 326 | ### new Query([address], [method], params) 327 | Represents a single instance of an interaction with the blockchain, can be executed as a transaction or call 328 | 329 | **Returns**: [Query](#Query) - new Query instance 330 | 331 | | Param | Type | Description | 332 | | --- | --- | --- | 333 | | [address] | Address | address instance associated with this query | 334 | | [method] | string | the contract method this query will target | 335 | | params | Array | either a flat array of values which are the parameters or an array of type/value pairs | 336 | | params[].value | string | the value of a param | 337 | | params[].type | string | the type of a param | 338 | 339 | 340 | 341 | ### query.param(value, [type]) ⇒ [Query](#Query) 342 | Adds a param to the call/transaction to be sent 343 | 344 | **Kind**: instance method of [Query](#Query) 345 | **Returns**: [Query](#Query) - instance of this query to chain method calls from 346 | 347 | | Param | Type | Description | 348 | | --- | --- | --- | 349 | | value | mixed | the value of the parameter in this query | 350 | | [type] | string | the type of the the parameter if we are not aware of it | 351 | 352 | 353 | 354 | ### query.returns(type) ⇒ [Query](#Query) 355 | Set the return type for a query 356 | 357 | **Kind**: instance method of [Query](#Query) 358 | **Returns**: [Query](#Query) - instance of this query to chain method calls from 359 | 360 | | Param | Type | Description | 361 | | --- | --- | --- | 362 | | type | string | the type of the data returned by the query | 363 | 364 | 365 | 366 | ### query.urlEncode() ⇒ string 367 | Gets the data for this query encoded as a URL to send to etherest against a particular address 368 | 369 | **Kind**: instance method of [Query](#Query) 370 | **Returns**: string - the encoded URL part to execute this query 371 | 372 | 373 | ### query.call(address) ⇒ Promise 374 | Executes this query as a call 375 | 376 | **Kind**: instance method of [Query](#Query) 377 | **Returns**: Promise - a promise which resolves when the call has been completed with the value returned 378 | 379 | | Param | Type | Description | 380 | | --- | --- | --- | 381 | | address | Address | the address to execute the call against, required if the query was not constructed with one | 382 | 383 | 384 | 385 | ### query.sendTransaction(address, options) ⇒ Promise 386 | Executes this query as a transaction 387 | 388 | **Kind**: instance method of [Query](#Query) 389 | **Returns**: Promise - a promise which resolves when the transaction has been submitted to the blockchain with a transaction id string 390 | 391 | | Param | Type | Default | Description | 392 | | --- | --- | --- | --- | 393 | | address | Address | | the address to send the transaction to, required if the query was not constructed with one | 394 | | options | Object | | options for the transaction | 395 | | options.from | string | | the address this transaction is being sent from | 396 | | options.privateKey | string | | the private key of the address this transaction is being sent from | 397 | | [options.value] | number | 0 | the amount ot eth to send with this transaction (1 = 1.0 Ether sent) | 398 | | [options.gasPrice] | number | 20 | the price to pay for gas for this transaction in gwei | 399 | | [options.gasLimit] | number | 200000 | the maximum amount of gas this transaction is allowed to use | -------------------------------------------------------------------------------- /dist/etherest.min.js: -------------------------------------------------------------------------------- 1 | !function(t,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define("Etherest",[],r):"object"==typeof exports?exports.Etherest=r():t.Etherest=r()}(this,function(){return function(t){function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var e={};return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},r.p="",r(r.s=40)}([function(t,r){var e=Array.isArray;t.exports=e},function(t,r,e){var n=e(22),o="object"==typeof self&&self&&self.Object===Object&&self,i=n||o||Function("return this")();t.exports=i},function(t,r,e){function n(t,r){var e=i(t,r);return o(e)?e:void 0}var o=e(77),i=e(80);t.exports=n},function(t,r,e){function n(t){return null==t?void 0===t?c:a:s&&s in Object(t)?i(t):u(t)}var o=e(5),i=e(52),u=e(53),a="[object Null]",c="[object Undefined]",s=o?o.toStringTag:void 0;t.exports=n},function(t,r){function e(t){return null!=t&&"object"==typeof t}t.exports=e},function(t,r,e){var n=e(1),o=n.Symbol;t.exports=o},function(t,r,e){function n(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1&&t%1==0&&t<=n}var n=9007199254740991;t.exports=e},function(t,r,e){function n(t){return null!=t&&i(t.length)&&!o(t)}var o=e(27),i=e(12);t.exports=n},function(t,r){function e(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}t.exports=e},function(t,r,e){var n=e(2),o=e(1),i=n(o,"Map");t.exports=i},function(t,r,e){function n(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1&&t%1==0&&tl))return!1;var d=f.get(t);if(d&&f.get(r))return d==r;var v=-1,y=!0,b=e&c?new o:void 0;for(f.set(t,r),f.set(r,t);++v>18&63,i=c>>12&63,u=c>>6&63,a=63&c,h[p++]=s.charAt(o)+s.charAt(i)+s.charAt(u)+s.charAt(a)}while(f299)&&e.error){t=new Error("CouchDB error: "+(e.error.reason||e.error.error));for(var o in e)t[o]=e[o];return n(t,r,e)}return n(t,r,e)}return"string"==typeof r&&(r={uri:r}),r.json=!0,r.body&&(r.json=r.body),delete r.body,n=n||e,t(r,o)},t})},function(t,r,e){function n(t,r,e){return r||(e=r,r=t,t=null),e=e||"main",this.address=r,this.etherest=t,this.network=e,this}function o(t){return u(t,function(t){return t.type})}var i=e(19),u=e(29),a=e(130);n.prototype.query=function(t,r){return new a(this,t)},n.prototype.method=function(t){var r=Array.prototype.slice.call(arguments),t=r.shift();return this.query(t,r)},n.prototype.defineMethod=function(t,r,e){return this[t]=function(){var n=Array.prototype.slice.call(arguments),o=this.query(t);return e&&o.returns(e),i(r,function(t,r){o.param(n[r],t)}),o},this[t]},n.prototype.defineCall=function(t,r,e){var n=this.defineMethod(t,r,e);return this[t]=function(){return n.apply(this,Array.prototype.slice.call(arguments)).call()},this[t]},n.prototype.defineTransaction=function(t,r){var e=this.defineMethod(t,r);return this[t]=function(){var t=Array.prototype.slice.call(arguments),r=t[t.length-1];return e.apply(this,t.slice(0,t.length-1)).sendTransaction(r)},this[t]},n.prototype.abi=function(t){var r=this.defineTransaction,e=this.defineCall,n=this;return i(t,function(t){if("function"===t.type){(t.constant?e:r).call(n,t.name,o(t.inputs),o(t.outputs))}}),this},n.prototype.loadAbi=function(){var t=this;return this.call().then(function(r){return r.abi&&r.abi&&t.abi(r.abi),t})},n.prototype.urlEncode=function(t){return t=t||"",this.network+"/"+this.address+"/"+t},n.prototype.call=function(t){var r=this.urlEncode(t);return this.etherest.call(r)},n.prototype.sendTransaction=function(t,r){var e=this.urlEncode(t);return this.etherest.sendTransaction(e,r)},t.exports=n},function(t,r){function e(t,r){for(var e=-1,n=null==t?0:t.length;++e-1}var o=e(7);t.exports=n},function(t,r,e){function n(t,r){var e=this.__data__,n=o(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this}var o=e(7);t.exports=n},function(t,r,e){function n(){this.__data__=new o,this.size=0}var o=e(6);t.exports=n},function(t,r){function e(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e}t.exports=e},function(t,r){function e(t){return this.__data__.get(t)}t.exports=e},function(t,r){function e(t){return this.__data__.has(t)}t.exports=e},function(t,r,e){function n(t,r){var e=this.__data__;if(e instanceof o){var n=e.__data__;if(!i||n.length