├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── example.js ├── lib ├── js │ ├── monerod-js.js │ ├── monerod-js.js.map │ └── test │ │ ├── test.spec.js │ │ └── test.spec.js.map └── ts │ ├── monerod-js.ts │ └── test │ └── test.spec.ts ├── package.json ├── spec └── support │ └── jasmine.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | TODO.md 2 | 3 | ### Linux ### 4 | *~ 5 | 6 | # temporary files which can be created if a process still has a handle open of a deleted file 7 | .fuse_hidden* 8 | 9 | # KDE directory preferences 10 | .directory 11 | 12 | # Linux trash folder which might appear on any partition or disk 13 | .Trash-* 14 | 15 | # .nfs files are created when an open file is removed but is still being accessed 16 | .nfs* 17 | 18 | ### VisualStudioCode ### 19 | .vscode/* 20 | #!.vscode/settings.json 21 | #!.vscode/tasks.json 22 | #!.vscode/launch.json 23 | #!.vscode/extensions.json 24 | 25 | ### Node ### 26 | # Logs 27 | logs 28 | *.log 29 | npm-debug.log* 30 | 31 | # Runtime data 32 | pids 33 | *.pid 34 | *.seed 35 | *.pid.lock 36 | 37 | # Directory for instrumented libs generated by jscoverage/JSCover 38 | lib-cov 39 | 40 | # Coverage directory used by tools like istanbul 41 | coverage 42 | 43 | # nyc test coverage 44 | .nyc_output 45 | 46 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 47 | .grunt 48 | 49 | # Bower dependency directory (https://bower.io/) 50 | bower_components 51 | 52 | # node-waf configuration 53 | .lock-wscript 54 | 55 | # Compiled binary addons (http://nodejs.org/api/addons.html) 56 | build/Release 57 | 58 | # Dependency directories 59 | node_modules 60 | jspm_packages 61 | 62 | # Optional npm cache directory 63 | .npm 64 | 65 | # Optional eslint cache 66 | .eslintcache 67 | 68 | # Optional REPL history 69 | .node_repl_history 70 | 71 | # Output of 'npm pack' 72 | *.tgz 73 | 74 | # Yarn Integrity file 75 | .yarn-integrity 76 | 77 | # dotenv environment variables file 78 | .env -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.1.1 4 | 5 | ### `getTransactions()` supports `missed_tx` return value 6 | - Add optional return attribute `missed_tx?: string[]`. If for one of the requested tx ids no information can be found the array contains the missed transactions ids. 7 | - Return attribute `txs_as_hex` is optional. 8 | - Return attribute `txs_as_json` is optional. 9 | - Fix bug that leads to crash when no tx information can be found and parameter `decodeAsJson` is `true` 10 | - Add unit test that expects `missed_tx` 11 | 12 | ### Updated dependencies 13 | - @types/jasmine@2.6.2 14 | - @types/node@7.0.46 15 | - jasmine@2.8.0 -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2017 cryptoshrimpi 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NodeJS RPC Client for Monero Daemon 2 | 3 | Monerod-js is a NodeJS RPC Client for Monero Daemon. 4 | 5 | It is written in Typescript and transpiled to Javascript. Using Typescript for development comes with the benefit that all the return values are typed and errors may be spotted earlier. 6 | 7 | The official Monero Daemon RPC documentation can be found [here](https://getmonero.org/knowledge-base/developer-guides/daemon-rpc). 8 | 9 | Developed for / Last tested with Monerod v0.10.3.1. 10 | 11 | Checkout the [CHANGELOG](CHANGELOG.md) to keep track of the latest changes. 12 | 13 | ## Install 14 | ``` 15 | npm install cryptoshrimpi/monerod-js 16 | ``` 17 | 18 | ## Test 19 | You need to install the dev dependencies to run the test suite: 20 | 21 | ``` 22 | cd node_modules/monerod-js 23 | npm install 24 | npm test 25 | ``` 26 | 27 | The test's default daemon is `monero.whattheserver.me:8081`. In order to use your local node please edit `test.spec.ts` or `test.spec.js`. Some tests may fail if your daemon is configured to restrict access to certain RPC calls. 28 | 29 | ## Usage 30 | 31 | ### Example (Typescript) 32 | 33 | ```typescript 34 | import { MoneroDaemon } from "node_modules/monerod-js/lib/ts/monerod-js"; 35 | 36 | var monerod = new MoneroDaemon("monero.whattheserver.me", 8081); 37 | 38 | monerod.getBlockCount().then((result) => { 39 | console.log("Block count: " + result.count); 40 | }).catch((f) => { 41 | console.log("Something went wrong: " + f); 42 | }); 43 | ``` 44 | 45 | ### Example (Javascript) 46 | 47 | ```javascript 48 | const m = require("./node_modules/monerod-js/lib/js/monerod-js"); 49 | 50 | var monerod = new m.MoneroDaemon("monero.whattheserver.me", 8081); 51 | 52 | monerod.getBlockCount().then((result) => { 53 | console.log("Block count: " + result.count); 54 | }).catch((f) => { 55 | console.log("Something went wrong: " + f); 56 | }); 57 | ``` 58 | 59 | Run the example code: 60 | ``` 61 | cd node_modules/monerod-js 62 | node example.js 63 | ``` 64 | 65 | ### Available methods 66 | Please see [monerod-js.ts](lib/ts/monerod-js.ts) for a list of the specific return values of each method. 67 | 68 | 69 | ``` 70 | getBlockCount() 71 | 72 | onGetBlockHash(blockHeight: number) 73 | 74 | getBlockTemplate(walletAddress: string, reserveSize: number) 75 | 76 | getLastBlockHeader() 77 | 78 | getBlockHeaderByHash(hash: string) 79 | 80 | getBlockHeaderByHeight(height: number) 81 | 82 | getBlock(height: number, hash: string) 83 | 84 | getConnections() 85 | 86 | getInfo() 87 | 88 | getHardFork() 89 | 90 | setBans(bans: BansList) 91 | 92 | getBans() 93 | 94 | getHeight() 95 | 96 | getTransactions(txsHashes: string[], decodeAsJson: boolean) 97 | 98 | sendRawTransaction(txAsHex: string) 99 | 100 | getTransactionPool() 101 | 102 | submitBlock(blockBlobData: string) 103 | 104 | getVersion() 105 | 106 | getFeeEstimate() 107 | ``` 108 | 109 | ## Beer 110 | It is highly appreciated if you want to tip me with a beer. 111 | 112 | Monero: ```4ATwquCmjnUTuDcF2Yce4YMLexuyFMKF96W7gEA6QU8S5pffgFDi9i29R8yyvHq1MzBVNVXZXUuEtdqpgVRC2hTc7Vtuahu``` 113 | 114 | ## License 115 | MIT. See [LICENSE.md](LICENSE.md). -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | const m = require("./lib/js/monerod-js"); 2 | 3 | var monerod = new m.MoneroDaemon("monero.whattheserver.me", 8081); 4 | 5 | monerod.getBlockCount().then((result) => { 6 | console.log("Block count: " + result.count); 7 | }).catch((f) => { 8 | console.log("Something went wrong: " + f); 9 | }); -------------------------------------------------------------------------------- /lib/js/monerod-js.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var http = require('http'); 3 | var SpentStatus; 4 | (function (SpentStatus) { 5 | SpentStatus[SpentStatus["unspent"] = 0] = "unspent"; 6 | SpentStatus[SpentStatus["spentInBlockchain"] = 1] = "spentInBlockchain"; 7 | SpentStatus[SpentStatus["spentInTransactionPool"] = 2] = "spentInTransactionPool"; 8 | })(SpentStatus = exports.SpentStatus || (exports.SpentStatus = {})); 9 | class MoneroDaemon { 10 | constructor(hostname = '127.0.0.1', port = 18081) { 11 | this.hostname = hostname; 12 | this.port = port; 13 | } 14 | defaultRequest(requestBody) { 15 | return this.request(requestBody, "/json_rpc"); 16 | } 17 | request(requestBody, path) { 18 | let requestJSON = JSON.stringify(requestBody); 19 | let isDefaultPath = (path == "/json_rpc"); 20 | let headers = {}; 21 | headers["Content-Type"] = 'application/json'; 22 | headers["Content-Length"] = Buffer.byteLength(requestJSON, 'utf8'); 23 | let options = { 24 | hostname: this.hostname, 25 | port: this.port, 26 | path: path, 27 | method: 'POST', 28 | headers: headers 29 | }; 30 | return new Promise((resolve, reject) => { 31 | let data = ''; 32 | let req = http.request(options, (res) => { 33 | res.setEncoding('utf8'); 34 | res.on('data', (chunk) => { data += chunk; }); 35 | res.on('end', function () { 36 | let body = JSON.parse(data); 37 | if (isDefaultPath && body && body.result) { 38 | resolve(body.result); 39 | } 40 | else if (!isDefaultPath && body) { 41 | resolve(body); 42 | } 43 | else if (body && body.error) { 44 | reject("Daemon response error. Code: " + body.error.code + ", Message: " + body.error.message); 45 | } 46 | else { 47 | reject("Daemon response error"); 48 | } 49 | }); 50 | }); 51 | req.on('error', (e) => reject("Daemon response error: " + e.message)); 52 | req.write(requestJSON); 53 | req.end(); 54 | }); 55 | } 56 | buildDefaultRequestBody(method, params) { 57 | return { 58 | jsonrpc: '2.0', 59 | id: '0', 60 | method: method, 61 | params: params 62 | }; 63 | } 64 | getBlockCount() { 65 | let body = this.buildDefaultRequestBody("getblockcount", null); 66 | return this.defaultRequest(body); 67 | } 68 | onGetBlockHash(blockHeight) { 69 | let body = this.buildDefaultRequestBody("on_getblockhash", [blockHeight]); 70 | return this.defaultRequest(body); 71 | } 72 | getBlockTemplate(walletAddress, reserveSize) { 73 | let body = this.buildDefaultRequestBody("getblocktemplate", { 74 | "wallet_address": walletAddress, 75 | "reserve_size": reserveSize 76 | }); 77 | return this.defaultRequest(body); 78 | } 79 | getLastBlockHeader() { 80 | let body = this.buildDefaultRequestBody("getlastblockheader", null); 81 | return this.defaultRequest(body); 82 | } 83 | getBlockHeaderByHash(hash) { 84 | let body = this.buildDefaultRequestBody("getblockheaderbyhash", { 85 | "hash": hash 86 | }); 87 | return this.defaultRequest(body); 88 | } 89 | getBlockHeaderByHeight(height) { 90 | let body = this.buildDefaultRequestBody("getblockheaderbyheight", { 91 | "height": height 92 | }); 93 | return this.defaultRequest(body); 94 | } 95 | getBlock(height, hash) { 96 | let body = this.buildDefaultRequestBody("getblock", { 97 | "height": height, 98 | "hash": hash 99 | }); 100 | return new Promise((resolve, reject) => { 101 | this.defaultRequest(body).then((a) => { 102 | a.json = JSON.parse(a.json); 103 | resolve(a); 104 | }).catch((f) => { 105 | reject(f); 106 | }); 107 | }); 108 | } 109 | getConnections() { 110 | let body = this.buildDefaultRequestBody("get_connections", null); 111 | return this.defaultRequest(body); 112 | } 113 | getInfo() { 114 | let body = this.buildDefaultRequestBody("get_info", null); 115 | return this.defaultRequest(body); 116 | } 117 | getHardFork() { 118 | let body = this.buildDefaultRequestBody("hard_fork_info", null); 119 | return this.defaultRequest(body); 120 | } 121 | setBans(bans) { 122 | let body = this.buildDefaultRequestBody("setbans", { "bans": bans }); 123 | return this.defaultRequest(body); 124 | } 125 | getBans() { 126 | let body = this.buildDefaultRequestBody("getbans", null); 127 | return this.defaultRequest(body); 128 | } 129 | getHeight() { 130 | return this.request({}, "/getheight"); 131 | } 132 | getTransactions(txsHashes, decodeAsJson) { 133 | let body = { txs_hashes: txsHashes, decode_as_json: decodeAsJson }; 134 | return new Promise((resolve, reject) => { 135 | this.request(body, "/gettransactions").then((a) => { 136 | if (decodeAsJson && a.hasOwnProperty("txs_as_json")) { 137 | a.txs_as_json = JSON.parse(a.txs_as_json); 138 | } 139 | resolve(a); 140 | }).catch((f) => { 141 | reject(f); 142 | }); 143 | }); 144 | } 145 | isKeyImageSpent(keyImages) { 146 | return this.request({ key_images: keyImages }, "/is_key_image_spent"); 147 | } 148 | sendRawTransaction(txAsHex) { 149 | return this.request({ tx_as_hex: txAsHex }, "/sendrawtransaction"); 150 | } 151 | getTransactionPool() { 152 | return new Promise((resolve, reject) => { 153 | this.request({}, "/get_transaction_pool").then((a) => { 154 | /* 155 | Monero returns invalid JSON 156 | for (var key in a.transactions) { 157 | a.transactions[key].tx_json = JSON.parse(a.transactions[key].tx_json); 158 | }*/ 159 | resolve(a); 160 | }).catch((f) => { 161 | reject(f); 162 | }); 163 | }); 164 | } 165 | submitBlock(blockBlobData) { 166 | let body = this.buildDefaultRequestBody("submitblock", [blockBlobData]); 167 | return this.defaultRequest(body); 168 | } 169 | getVersion() { 170 | let body = this.buildDefaultRequestBody("get_version", null); 171 | return this.defaultRequest(body); 172 | } 173 | getFeeEstimate() { 174 | let body = this.buildDefaultRequestBody("get_fee_estimate", null); 175 | return this.defaultRequest(body); 176 | } 177 | } 178 | exports.MoneroDaemon = MoneroDaemon; 179 | //# sourceMappingURL=monerod-js.js.map -------------------------------------------------------------------------------- /lib/js/monerod-js.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"monerod-js.js","sourceRoot":"","sources":["../ts/monerod-js.ts"],"names":[],"mappings":";AAAA,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAoL3B,IAAY,WAIX;AAJD,WAAY,WAAW;IACnB,mDAAW,CAAA;IACX,uEAAqB,CAAA;IACrB,iFAA0B,CAAA;AAC9B,CAAC,EAJW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAItB;AAyGD;IAKI,YAAY,WAAmB,WAAW,EAAE,OAAe,KAAK;QAC5D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAEO,cAAc,CAAC,WAAwB;QAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;IAEO,OAAO,CAAC,WAAgB,EAAE,IAAY;QAE1C,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,aAAa,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC;QAE1C,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC7C,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAEnE,IAAI,OAAO,GAAG;YACV,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,OAAO;SACnB,CAAC;QAEF,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YAC/B,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG;gBAChC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBACxB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;oBACV,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAE5B,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;wBACvC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACzB,CAAC;oBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;wBAChC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAClB,CAAC;oBAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;wBAC5B,MAAM,CAAC,+BAA+B,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACnG,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACJ,MAAM,CAAC,uBAAuB,CAAC,CAAC;oBACpC,CAAC;gBAEL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,yBAAyB,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACtE,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACvB,GAAG,CAAC,GAAG,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,uBAAuB,CAAC,MAAc,EAAE,MAAW;QACvD,MAAM,CAAC;YACH,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,GAAG;YACP,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,MAAM;SACjB,CAAC;IACN,CAAC;IAEM,aAAa;QAChB,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAyB,CAAC;IAC7D,CAAC;IAEM,cAAc,CAAC,WAAmB;QACrC,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAA0B,CAAC;IAC9D,CAAC;IAEM,gBAAgB,CAAC,aAAqB,EAAE,WAAmB;QAC9D,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,kBAAkB,EAAE;YACxD,gBAAgB,EAAE,aAAa;YAC/B,cAAc,EAAE,WAAW;SAC9B,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAA4B,CAAC;IAChE,CAAC;IAEM,kBAAkB;QACrB,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAA8B,CAAC;IAClE,CAAC;IAEM,oBAAoB,CAAC,IAAY;QACpC,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,sBAAsB,EAAE;YAC5D,MAAM,EAAE,IAAI;SACf,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAgC,CAAC;IACpE,CAAC;IAEM,sBAAsB,CAAC,MAAc;QACxC,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,wBAAwB,EAAE;YAC9D,QAAQ,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAkC,CAAC;IACtE,CAAC;IAEM,QAAQ,CAAC,MAAc,EAAE,IAAY;QACxC,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,EAAE;YAChD,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC7B,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC5B,OAAO,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACP,MAAM,CAAC,CAAC,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAAoB,CAAC;IAC1B,CAAC;IAEM,cAAc;QACjB,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAA0B,CAAC;IAC9D,CAAC;IAEM,OAAO;QACV,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAmB,CAAC;IACvD,CAAC;IAEM,WAAW;QACd,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAuB,CAAC;IAC3D,CAAC;IAEM,OAAO,CAAC,IAAc;QACzB,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAmB,CAAC;IACvD,CAAC;IAEM,OAAO;QACV,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAmB,CAAC;IACvD,CAAC;IAEM,SAAS;QACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,CAAqB,CAAC;IAC9D,CAAC;IAEM,eAAe,CAAC,SAAmB,EAAE,YAAqB;QAC7D,IAAI,IAAI,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;QAEnE,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM;gBAC/C,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;oBAClD,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBAC9C,CAAC;gBACD,OAAO,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACP,MAAM,CAAC,CAAC,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAA2B,CAAC;IACjC,CAAC;IAEM,eAAe,CAAC,SAAmB;QACtC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,qBAAqB,CAA2B,CAAC;IACpG,CAAC;IAEM,kBAAkB,CAAC,OAAe;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,qBAAqB,CAA8B,CAAC;IACpG,CAAC;IAEM,kBAAkB;QACrB,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM;YAC/B,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAE7C;;;;mBAIG;gBAEH,OAAO,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACP,MAAM,CAAC,CAAC,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAA8B,CAAC;IACpC,CAAC;IAEM,WAAW,CAAC,aAAqB;QACpC,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;QACxE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAuB,CAAC;IAC3D,CAAC;IAEM,UAAU;QACb,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAsB,CAAC;IAC1D,CAAC;IAEM,cAAc;QACjB,IAAI,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAA0B,CAAC;IAC9D,CAAC;CAEJ;AA3MD,oCA2MC"} -------------------------------------------------------------------------------- /lib/js/test/test.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const monerod_js_1 = require("../monerod-js"); 3 | describe("Testing RPC call: ", function () { 4 | var monerod = new monerod_js_1.MoneroDaemon("monero.whattheserver.me", 8081); 5 | it("getHardFork", function (done) { 6 | monerod.getHardFork().then((test) => { 7 | expect(test.status).toBeDefined(); 8 | done(); 9 | }).catch((f) => { 10 | fail(f); 11 | done(); 12 | }); 13 | }); 14 | it("getBlock", function (done) { 15 | monerod.getBlock(1, null).then((test) => { 16 | expect(test.json).toBeDefined(); 17 | expect(test.json.timestamp).toBe(1397818193); 18 | done(); 19 | }).catch((f) => { 20 | fail(f); 21 | done(); 22 | }); 23 | }); 24 | it("getBlockCount", function (done) { 25 | monerod.getBlockCount().then((test) => { 26 | expect(test.count).toBeGreaterThan(1); 27 | done(); 28 | }).catch((f) => { 29 | fail(f); 30 | done(); 31 | }); 32 | }); 33 | it("onGetBlockHash", function (done) { 34 | monerod.onGetBlockHash(1).then((test) => { 35 | expect(test).toBe("771fbcd656ec1464d3a02ead5e18644030007a0fc664c0a964d30922821a8148"); 36 | done(); 37 | }).catch((f) => { 38 | fail(f); 39 | done(); 40 | }); 41 | }); 42 | it("getBlockTemplate", function (done) { 43 | monerod.getBlockTemplate("44GBHzv6ZyQdJkjqZje6KLZ3xSyN1hBSFAnLP6EAqJtCRVzMzZmeXTC2AHKDS9aEDTRKmo6a6o9r9j86pYfhCWDkKjbtcns", 3).then((test) => { 44 | expect(test.reserved_offset).toBe(130); 45 | done(); 46 | }).catch((f) => { 47 | fail(f); 48 | done(); 49 | }); 50 | }); 51 | it("getLastBlockHeader", function (done) { 52 | monerod.getLastBlockHeader().then((test) => { 53 | expect(test.block_header.timestamp).toBeGreaterThan(1486583838); 54 | done(); 55 | }).catch((f) => { 56 | fail(f); 57 | done(); 58 | }); 59 | }); 60 | it("getBlockHeaderByHash", function (done) { 61 | monerod.getBlockHeaderByHash("e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6").then((test) => { 62 | expect(test.block_header.timestamp).toBe(1452793716); 63 | done(); 64 | }).catch((f) => { 65 | fail(f); 66 | done(); 67 | }); 68 | }); 69 | it("getBlockHeaderByHeight", function (done) { 70 | monerod.getBlockHeaderByHeight(1).then((test) => { 71 | expect(test.block_header.timestamp).toBe(1397818193); 72 | done(); 73 | }).catch((f) => { 74 | fail(f); 75 | done(); 76 | }); 77 | }); 78 | it("getConnections", function (done) { 79 | monerod.getConnections().then((test) => { 80 | expect(test.connections.length).toBeGreaterThan(0); 81 | done(); 82 | }).catch((f) => { 83 | fail(f); 84 | done(); 85 | }); 86 | }); 87 | it("getInfo - Incoming connections", function (done) { 88 | monerod.getInfo().then((test) => { 89 | expect(test.incoming_connections_count).toBeGreaterThan(0); 90 | done(); 91 | }).catch((f) => { 92 | fail(f); 93 | done(); 94 | }); 95 | }); 96 | it("setBan", function (done) { 97 | monerod.setBans([{ ip: "0.0.0.0", ban: true, seconds: 10 }]).then((test) => { 98 | expect(test.status).toBeDefined(); 99 | done(); 100 | }).catch((f) => { 101 | fail(f); 102 | done(); 103 | }); 104 | }); 105 | it("getBan", function (done) { 106 | monerod.getBans().then((test) => { 107 | expect(test.bans.length).toBeDefined(); 108 | }).catch((f) => { 109 | fail(f); 110 | done(); 111 | }); 112 | }); 113 | it("getHeight", function (done) { 114 | monerod.getHeight().then((test) => { 115 | expect(test.height).toBeGreaterThan(0); 116 | done(); 117 | }).catch((f) => { 118 | fail(f); 119 | done(); 120 | }); 121 | }); 122 | // Should return only missing tx 123 | it("getTransactions should return missing tx, true)", function (done) { 124 | monerod.getTransactions(['f061d04308f89fd3b18a86f1cb28ab62b1e5aa79364c83ad7ce11a0c7d08fbcb'], true).then(txInfo => { 125 | expect(txInfo.status).toEqual("OK"); 126 | expect(txInfo.missed_tx[0]).toEqual('f061d04308f89fd3b18a86f1cb28ab62b1e5aa79364c83ad7ce11a0c7d08fbcb'); 127 | expect(txInfo.txs_as_json).toBeUndefined(); 128 | expect(txInfo.txs_as_hex).toBeUndefined(); 129 | done(); 130 | }).catch((f) => { 131 | fail(f); 132 | done(); 133 | }); 134 | }); 135 | it("getTransactions(['d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408'], false)", function (done) { 136 | monerod.getTransactions(["d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408"], false).then((test) => { 137 | expect(test.status).toEqual("OK"); 138 | expect(test.txs_as_hex).toBeDefined(); 139 | expect(test.txs_as_json).toBeUndefined(); 140 | done(); 141 | }).catch((f) => { 142 | fail(f); 143 | done(); 144 | }); 145 | }); 146 | it("getTransactions(['d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408'], true)", function (done) { 147 | monerod.getTransactions(["d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408"], true).then((test) => { 148 | expect(test.status).toEqual("OK"); 149 | expect(test.txs_as_hex).toBeDefined(); 150 | expect(test.txs_as_json).toBeDefined(); 151 | // expect(test.txs_as_json.vin[0].key.amount).toEqual(9999999999); 152 | done(); 153 | }).catch((f) => { 154 | fail(f); 155 | done(); 156 | }); 157 | }); 158 | it("isKeyImageSpent", function (done) { 159 | monerod.isKeyImageSpent(["8d1bd8181bf7d857bdb281e0153d84cd55a3fcaa57c3e570f4a49f935850b5e3", "7319134bfc50668251f5b899c66b005805ee255c136f0e1cecbb0f3a912e09d4"]).then((test) => { 160 | expect(test.status).toEqual("OK"); 161 | expect(test.spent_status).toEqual([monerod_js_1.SpentStatus.spentInBlockchain, monerod_js_1.SpentStatus.spentInBlockchain]); 162 | done(); 163 | }).catch((f) => { 164 | fail(f); 165 | done(); 166 | }); 167 | }); 168 | /* 169 | 170 | /sendrawtransaction is a critical rpc call. therefore this test should be activated by explicitly uncommenting it. 171 | 172 | it("sendRawTransaction should fail", function (done) { 173 | monerod.sendRawTransaction("abc").then((test) => { 174 | expect(test.status).toEqual("Failed"); 175 | expect(test.double_spend).toEqual(false); 176 | done(); 177 | }).catch((f) => { 178 | fail(f); 179 | done(); 180 | }); 181 | });*/ 182 | it("getTransactionPool", function (done) { 183 | monerod.getTransactionPool().then((test) => { 184 | expect(test.status).toEqual("OK"); 185 | done(); 186 | }).catch((f) => { 187 | fail(f); 188 | done(); 189 | }); 190 | }); 191 | it("submitBlock", function (done) { 192 | monerod.submitBlock("notablockblob").then((test) => { 193 | }).catch((f) => { 194 | // We expect a specific error msg for this rpc call cause we don't have any blocks to submit 195 | expect(f).toEqual("Daemon response error. Code: -6, Message: Wrong block blob"); 196 | done(); 197 | }); 198 | }); 199 | it("getVersion", function (done) { 200 | monerod.getVersion().then((data) => { 201 | expect(data.version).toBeGreaterThan(10); 202 | expect(data.status).toEqual("OK"); 203 | done(); 204 | }).catch((f) => { 205 | fail(f); 206 | done(); 207 | }); 208 | }); 209 | it("getFeeEstimate", function (done) { 210 | monerod.getFeeEstimate().then((data) => { 211 | expect(data.status).toEqual("OK"); 212 | expect(data.fee).toBeGreaterThan(0); 213 | done(); 214 | }).catch((f) => { 215 | fail(f); 216 | done(); 217 | }); 218 | }); 219 | }); 220 | //# sourceMappingURL=test.spec.js.map -------------------------------------------------------------------------------- /lib/js/test/test.spec.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"test.spec.js","sourceRoot":"","sources":["../../ts/test/test.spec.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/ts/monerod-js.ts: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | type GetVersionPromise = Promise<{ 4 | status: string, 5 | version: number 6 | }> 7 | 8 | type GetBlockCountPromise = Promise<{ 9 | count: number, 10 | status: string 11 | }> 12 | 13 | type SubmitBlockPromise = Promise<{ 14 | status: string 15 | }> 16 | 17 | type OnGetBlockHashPromise = Promise; 18 | 19 | type GetBlockTemplatePromise = Promise<{ 20 | blocktemplate_blob: string, 21 | difficulty: number, 22 | height: number, 23 | prev_hash: string, 24 | reserved_offset: number, 25 | status: string 26 | }>; 27 | 28 | type BlockHeader = { 29 | depth: number; 30 | difficulty: number; 31 | hash: string; 32 | height: number; 33 | major_version: number; 34 | minor_version: number; 35 | nonce: number; 36 | orphan_status: boolean; 37 | prev_hash: string; 38 | reward: number; 39 | timestamp: number; 40 | }; 41 | 42 | type GetFeeEstimatePromise = Promise<{ 43 | status: string, 44 | fee: number 45 | }>; 46 | 47 | type GetLastBlockHeaderPromise = Promise<{ 48 | block_header: BlockHeader 49 | }>; 50 | 51 | type GetHeightPromise = Promise<{ 52 | height: number; 53 | status: string; 54 | }>; 55 | 56 | type GetBlockHeaderByHashPromise = GetLastBlockHeaderPromise; 57 | 58 | type GetBlockHeaderByHeightPromise = GetLastBlockHeaderPromise; 59 | 60 | type GetBlockPromise = Promise<{ 61 | blob: string; 62 | block_header: BlockHeader; 63 | // json: GetBlockJSON.Root; 64 | json: any; 65 | status: string; 66 | }>; 67 | 68 | module GetBlockJSON { 69 | 70 | type Gen = { 71 | height: number; 72 | } 73 | 74 | type Vin = { 75 | gen: Gen; 76 | } 77 | 78 | type Target = { 79 | key: string; 80 | } 81 | 82 | type Vout = { 83 | amount: any; 84 | target: Target; 85 | } 86 | 87 | type MinerTx = { 88 | version: number; 89 | unlock_time: number; 90 | vin: Vin[]; 91 | vout: Vout[]; 92 | extra: number[]; 93 | signatures: any[]; 94 | } 95 | 96 | export type Root = { 97 | major_version: number; 98 | minor_version: number; 99 | timestamp: number; 100 | prev_id: string; 101 | nonce: number; 102 | miner_tx: MinerTx; 103 | tx_hashes: any[]; 104 | } 105 | 106 | } 107 | 108 | type GetConnectionsPromise = Promise<{ 109 | connections: { 110 | avg_download: number; 111 | avg_upload: number; 112 | current_download: number; 113 | current_upload: number; 114 | incoming: boolean; 115 | ip: string; 116 | live_time: number; 117 | local_ip: boolean; 118 | localhost: boolean; 119 | peer_id: string; 120 | port: string; 121 | recv_count: number; 122 | recv_idle_time: number; 123 | send_count: number; 124 | send_idle_time: number; 125 | state: string; 126 | }[]; 127 | status: string; 128 | }>; 129 | 130 | 131 | type GetInfoPromise = Promise<{ 132 | alt_blocks_count: number; 133 | difficulty: number; 134 | grey_peerlist_size: number; 135 | height: number; 136 | incoming_connections_count: number; 137 | outgoing_connections_count: number; 138 | status: string; 139 | target: number; 140 | target_height: number; 141 | testnet: boolean; 142 | top_block_hash: string; 143 | tx_count: number; 144 | tx_pool_size: number; 145 | white_peerlist_size: number; 146 | }>; 147 | 148 | 149 | type GetHardForkPromise = Promise<{ 150 | earliest_height: number; 151 | enabled: boolean; 152 | state: number; 153 | status: string; 154 | threshold: number; 155 | version: number; 156 | votes: number; 157 | voting: number; 158 | window: number; 159 | }>; 160 | 161 | type BansList = { ip: string, ban: Boolean, seconds: number }[]; 162 | 163 | type SetBansPromise = Promise<{ 164 | status: string; 165 | }>; 166 | 167 | type GetBansPromise = Promise<{ 168 | bans: { ip: string, seconds: number }[]; 169 | status: string; 170 | }>; 171 | 172 | type RequestBody = { jsonrpc: string, id: string, method: string, params: any }; 173 | 174 | type GetTransactionsPromise = Promise<{ 175 | status: string, 176 | txs_as_hex?: string, 177 | txs_as_json?: any, 178 | missed_tx?: string[]; 179 | }> 180 | 181 | export enum SpentStatus { 182 | unspent = 0, 183 | spentInBlockchain = 1, 184 | spentInTransactionPool = 2 185 | } 186 | 187 | type SendRawTransactionPromise = Promise<{ 188 | double_spend: boolean; 189 | fee_too_low: boolean; 190 | invalid_input: boolean; 191 | invalid_output: boolean; 192 | low_mixin: boolean; 193 | not_rct: boolean; 194 | not_relayed: boolean; 195 | overspend: boolean; 196 | reason: string; 197 | status: string; 198 | too_big: boolean; 199 | }> 200 | 201 | type IsKeyImageSpentPromise = Promise<{ spent_status: SpentStatus[], status: string }>; 202 | 203 | type GetTransactionPoolPromise = Promise<{ 204 | spent_key_images: { 205 | id_hash: string; 206 | txs_hashes: string[] 207 | }[]; 208 | status: string; 209 | transactions: { 210 | blob_size: number; 211 | fee: any; 212 | id_hash: string; 213 | kept_by_block: boolean; 214 | last_failed_height: number; 215 | last_failed_id_hash: string; 216 | max_used_block_height: number; 217 | max_used_block_id_hash: string; 218 | receive_time: number; 219 | relayed: boolean; 220 | // tx_json: GetTransactionPoolTransaction; 221 | tx_json: string; // monero returns invalid json... 222 | }[]; 223 | }>; 224 | 225 | 226 | type GetTransactionPoolTransaction = { 227 | version: number; 228 | unlock_time: number; 229 | vin: { 230 | key: { 231 | amount: number; 232 | key_offsets: number[]; 233 | k_image: string; 234 | } 235 | }[]; 236 | vout: { 237 | amount: number; 238 | target: { key: string; } 239 | }[]; 240 | extra: number[]; 241 | rct_signatures: { 242 | type: number; 243 | txnFee: number; 244 | ecdhInfo: { 245 | mask: string; 246 | amount: string; 247 | }[]; 248 | outPk: string[]; 249 | }; 250 | rctsig_prunable: { 251 | rangeSigs: { 252 | asig: string; 253 | Ci: string; 254 | }[]; 255 | MGs: { 256 | ss: string[][]; 257 | cc: string; 258 | }[]; 259 | }; 260 | } 261 | 262 | declare module getTransactionsTxsAsJson { 263 | 264 | type Key = { 265 | amount: number; 266 | key_offsets: number[]; 267 | k_image: string; 268 | } 269 | 270 | type Vin = { 271 | key: Key; 272 | } 273 | 274 | type Vout = { 275 | amount: number; 276 | target: { key: string }; 277 | } 278 | 279 | export type Root = { 280 | version: number; 281 | unlock_time: number; 282 | vin: Vin[]; 283 | vout: Vout[]; 284 | extra: number[]; 285 | signatures: string[]; 286 | } 287 | 288 | } 289 | 290 | export class MoneroDaemon { 291 | 292 | private hostname; 293 | private port; 294 | 295 | constructor(hostname: string = '127.0.0.1', port: number = 18081) { 296 | this.hostname = hostname; 297 | this.port = port; 298 | } 299 | 300 | private defaultRequest(requestBody: RequestBody): Promise { 301 | return this.request(requestBody, "/json_rpc"); 302 | } 303 | 304 | private request(requestBody: any, path: String): Promise { 305 | 306 | let requestJSON = JSON.stringify(requestBody); 307 | let isDefaultPath = (path == "/json_rpc"); 308 | 309 | let headers = {}; 310 | headers["Content-Type"] = 'application/json'; 311 | headers["Content-Length"] = Buffer.byteLength(requestJSON, 'utf8'); 312 | 313 | let options = { 314 | hostname: this.hostname, 315 | port: this.port, 316 | path: path, 317 | method: 'POST', 318 | headers: headers 319 | }; 320 | 321 | return new Promise((resolve, reject) => { 322 | let data = ''; 323 | let req = http.request(options, (res) => { 324 | res.setEncoding('utf8'); 325 | res.on('data', (chunk) => { data += chunk; }); 326 | res.on('end', function () { 327 | let body = JSON.parse(data); 328 | 329 | if (isDefaultPath && body && body.result) { 330 | resolve(body.result); 331 | } else if (!isDefaultPath && body) { 332 | resolve(body); 333 | } else if (body && body.error) { 334 | reject("Daemon response error. Code: " + body.error.code + ", Message: " + body.error.message); 335 | } else { 336 | reject("Daemon response error"); 337 | } 338 | 339 | }); 340 | }); 341 | req.on('error', (e) => reject("Daemon response error: " + e.message)); 342 | req.write(requestJSON); 343 | req.end(); 344 | }); 345 | } 346 | 347 | private buildDefaultRequestBody(method: string, params: any): RequestBody { 348 | return { 349 | jsonrpc: '2.0', 350 | id: '0', 351 | method: method, 352 | params: params 353 | }; 354 | } 355 | 356 | public getBlockCount(): GetBlockCountPromise { 357 | let body = this.buildDefaultRequestBody("getblockcount", null); 358 | return this.defaultRequest(body) as GetBlockCountPromise; 359 | } 360 | 361 | public onGetBlockHash(blockHeight: number): OnGetBlockHashPromise { 362 | let body = this.buildDefaultRequestBody("on_getblockhash", [blockHeight]); 363 | return this.defaultRequest(body) as OnGetBlockHashPromise; 364 | } 365 | 366 | public getBlockTemplate(walletAddress: string, reserveSize: number): GetBlockTemplatePromise { 367 | let body = this.buildDefaultRequestBody("getblocktemplate", { 368 | "wallet_address": walletAddress, 369 | "reserve_size": reserveSize 370 | }); 371 | return this.defaultRequest(body) as GetBlockTemplatePromise; 372 | } 373 | 374 | public getLastBlockHeader(): GetLastBlockHeaderPromise { 375 | let body = this.buildDefaultRequestBody("getlastblockheader", null); 376 | return this.defaultRequest(body) as GetLastBlockHeaderPromise; 377 | } 378 | 379 | public getBlockHeaderByHash(hash: string): GetBlockHeaderByHashPromise { 380 | let body = this.buildDefaultRequestBody("getblockheaderbyhash", { 381 | "hash": hash 382 | }); 383 | return this.defaultRequest(body) as GetBlockHeaderByHashPromise; 384 | } 385 | 386 | public getBlockHeaderByHeight(height: number): GetBlockHeaderByHeightPromise { 387 | let body = this.buildDefaultRequestBody("getblockheaderbyheight", { 388 | "height": height 389 | }); 390 | return this.defaultRequest(body) as GetBlockHeaderByHeightPromise; 391 | } 392 | 393 | public getBlock(height: number, hash: string): GetBlockPromise { 394 | let body = this.buildDefaultRequestBody("getblock", { 395 | "height": height, 396 | "hash": hash 397 | }); 398 | 399 | return new Promise((resolve, reject) => { 400 | this.defaultRequest(body).then((a) => { 401 | a.json = JSON.parse(a.json); 402 | resolve(a); 403 | }).catch((f) => { 404 | reject(f); 405 | }); 406 | }) as GetBlockPromise; 407 | } 408 | 409 | public getConnections(): GetConnectionsPromise { 410 | let body = this.buildDefaultRequestBody("get_connections", null); 411 | return this.defaultRequest(body) as GetConnectionsPromise; 412 | } 413 | 414 | public getInfo(): GetInfoPromise { 415 | let body = this.buildDefaultRequestBody("get_info", null); 416 | return this.defaultRequest(body) as GetInfoPromise; 417 | } 418 | 419 | public getHardFork(): GetHardForkPromise { 420 | let body = this.buildDefaultRequestBody("hard_fork_info", null); 421 | return this.defaultRequest(body) as GetHardForkPromise; 422 | } 423 | 424 | public setBans(bans: BansList): SetBansPromise { 425 | let body = this.buildDefaultRequestBody("setbans", { "bans": bans }); 426 | return this.defaultRequest(body) as SetBansPromise; 427 | } 428 | 429 | public getBans(): GetBansPromise { 430 | let body = this.buildDefaultRequestBody("getbans", null); 431 | return this.defaultRequest(body) as GetBansPromise; 432 | } 433 | 434 | public getHeight(): GetHeightPromise { 435 | return this.request({}, "/getheight") as GetHeightPromise; 436 | } 437 | 438 | public getTransactions(txsHashes: string[], decodeAsJson: boolean): GetTransactionsPromise { 439 | let body = { txs_hashes: txsHashes, decode_as_json: decodeAsJson }; 440 | 441 | return new Promise((resolve, reject) => { 442 | this.request(body, "/gettransactions").then((a: any) => { 443 | if (decodeAsJson && a.hasOwnProperty("txs_as_json")) { 444 | a.txs_as_json = JSON.parse(a.txs_as_json); 445 | } 446 | resolve(a); 447 | }).catch((f) => { 448 | reject(f); 449 | }); 450 | }) as GetTransactionsPromise; 451 | } 452 | 453 | public isKeyImageSpent(keyImages: string[]): IsKeyImageSpentPromise { 454 | return this.request({ key_images: keyImages }, "/is_key_image_spent") as IsKeyImageSpentPromise; 455 | } 456 | 457 | public sendRawTransaction(txAsHex: string): SendRawTransactionPromise { 458 | return this.request({ tx_as_hex: txAsHex }, "/sendrawtransaction") as SendRawTransactionPromise; 459 | } 460 | 461 | public getTransactionPool(): GetTransactionPoolPromise { 462 | return new Promise((resolve, reject) => { 463 | this.request({}, "/get_transaction_pool").then((a) => { 464 | 465 | /* 466 | Monero returns invalid JSON 467 | for (var key in a.transactions) { 468 | a.transactions[key].tx_json = JSON.parse(a.transactions[key].tx_json); 469 | }*/ 470 | 471 | resolve(a); 472 | }).catch((f) => { 473 | reject(f); 474 | }); 475 | }) as GetTransactionPoolPromise; 476 | } 477 | 478 | public submitBlock(blockBlobData: string): SubmitBlockPromise { 479 | let body = this.buildDefaultRequestBody("submitblock", [blockBlobData]); 480 | return this.defaultRequest(body) as SubmitBlockPromise; 481 | } 482 | 483 | public getVersion(): GetVersionPromise { 484 | let body = this.buildDefaultRequestBody("get_version", null); 485 | return this.defaultRequest(body) as GetVersionPromise; 486 | } 487 | 488 | public getFeeEstimate(): GetFeeEstimatePromise { 489 | let body = this.buildDefaultRequestBody("get_fee_estimate", null); 490 | return this.defaultRequest(body) as GetFeeEstimatePromise; 491 | } 492 | 493 | } -------------------------------------------------------------------------------- /lib/ts/test/test.spec.ts: -------------------------------------------------------------------------------- 1 | import { MoneroDaemon, SpentStatus } from "../monerod-js"; 2 | 3 | describe("Testing RPC call: ", function () { 4 | 5 | var monerod = new MoneroDaemon("monero.whattheserver.me", 8081); 6 | 7 | it("getHardFork", function (done) { 8 | monerod.getHardFork().then((test) => { 9 | expect(test.status).toBeDefined(); 10 | done(); 11 | }).catch((f) => { 12 | fail(f); 13 | done(); 14 | }); 15 | }); 16 | 17 | it("getBlock", function (done) { 18 | monerod.getBlock(1, null).then((test) => { 19 | expect(test.json).toBeDefined(); 20 | expect(test.json.timestamp).toBe(1397818193); 21 | done(); 22 | }).catch((f) => { 23 | fail(f); 24 | done(); 25 | }); 26 | }); 27 | 28 | it("getBlockCount", function (done) { 29 | monerod.getBlockCount().then((test) => { 30 | expect(test.count).toBeGreaterThan(1); 31 | done(); 32 | }).catch((f) => { 33 | fail(f); 34 | done(); 35 | }); 36 | }); 37 | 38 | it("onGetBlockHash", function (done) { 39 | monerod.onGetBlockHash(1).then((test) => { 40 | expect(test).toBe("771fbcd656ec1464d3a02ead5e18644030007a0fc664c0a964d30922821a8148"); 41 | done(); 42 | }).catch((f) => { 43 | fail(f); 44 | done(); 45 | }); 46 | }); 47 | 48 | it("getBlockTemplate", function (done) { 49 | monerod.getBlockTemplate("44GBHzv6ZyQdJkjqZje6KLZ3xSyN1hBSFAnLP6EAqJtCRVzMzZmeXTC2AHKDS9aEDTRKmo6a6o9r9j86pYfhCWDkKjbtcns", 3).then((test) => { 50 | expect(test.reserved_offset).toBe(130); 51 | done(); 52 | }).catch((f) => { 53 | fail(f); 54 | done(); 55 | }); 56 | }); 57 | 58 | it("getLastBlockHeader", function (done) { 59 | monerod.getLastBlockHeader().then((test) => { 60 | expect(test.block_header.timestamp).toBeGreaterThan(1486583838); 61 | done(); 62 | }).catch((f) => { 63 | fail(f); 64 | done(); 65 | }); 66 | }); 67 | 68 | it("getBlockHeaderByHash", function (done) { 69 | monerod.getBlockHeaderByHash("e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6").then((test) => { 70 | expect(test.block_header.timestamp).toBe(1452793716); 71 | done(); 72 | }).catch((f) => { 73 | fail(f); 74 | done(); 75 | }); 76 | }); 77 | 78 | it("getBlockHeaderByHeight", function (done) { 79 | monerod.getBlockHeaderByHeight(1).then((test) => { 80 | expect(test.block_header.timestamp).toBe(1397818193); 81 | done(); 82 | }).catch((f) => { 83 | fail(f); 84 | done(); 85 | }); 86 | }); 87 | 88 | it("getConnections", function (done) { 89 | monerod.getConnections().then((test) => { 90 | expect(test.connections.length).toBeGreaterThan(0); 91 | done(); 92 | }).catch((f) => { 93 | fail(f); 94 | done(); 95 | }); 96 | }); 97 | 98 | it("getInfo - Incoming connections", function (done) { 99 | monerod.getInfo().then((test) => { 100 | expect(test.incoming_connections_count).toBeGreaterThan(0); 101 | done(); 102 | }).catch((f) => { 103 | fail(f); 104 | done(); 105 | }); 106 | }); 107 | 108 | it("setBan", function (done) { 109 | monerod.setBans([{ ip: "0.0.0.0", ban: true, seconds: 10 }]).then((test) => { 110 | expect(test.status).toBeDefined(); 111 | done(); 112 | }).catch((f) => { 113 | fail(f); 114 | done(); 115 | }); 116 | }); 117 | 118 | it("getBan", function (done) { 119 | monerod.getBans().then((test) => { 120 | expect(test.bans.length).toBeDefined(); 121 | }).catch((f) => { 122 | fail(f); 123 | done(); 124 | }); 125 | }); 126 | 127 | it("getHeight", function (done) { 128 | monerod.getHeight().then((test) => { 129 | expect(test.height).toBeGreaterThan(0); 130 | done(); 131 | }).catch((f) => { 132 | fail(f); 133 | done(); 134 | }); 135 | }); 136 | 137 | // Should return only missing tx 138 | it("getTransactions should return missing tx, true)", function (done) { 139 | monerod.getTransactions(['f061d04308f89fd3b18a86f1cb28ab62b1e5aa79364c83ad7ce11a0c7d08fbcb'], true).then(txInfo =>{ 140 | expect(txInfo.status).toEqual("OK"); 141 | expect(txInfo.missed_tx[0]).toEqual('f061d04308f89fd3b18a86f1cb28ab62b1e5aa79364c83ad7ce11a0c7d08fbcb'); 142 | expect(txInfo.txs_as_json).toBeUndefined(); 143 | expect(txInfo.txs_as_hex).toBeUndefined(); 144 | done(); 145 | }).catch((f) => { 146 | fail(f); 147 | done(); 148 | }); 149 | }); 150 | 151 | it("getTransactions(['d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408'], false)", function (done) { 152 | monerod.getTransactions(["d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408"], false).then((test) => { 153 | expect(test.status).toEqual("OK"); 154 | expect(test.txs_as_hex).toBeDefined(); 155 | expect(test.txs_as_json).toBeUndefined(); 156 | done(); 157 | }).catch((f) => { 158 | fail(f); 159 | done(); 160 | }); 161 | }); 162 | 163 | it("getTransactions(['d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408'], true)", function (done) { 164 | monerod.getTransactions(["d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408"], true).then((test) => { 165 | expect(test.status).toEqual("OK"); 166 | expect(test.txs_as_hex).toBeDefined(); 167 | expect(test.txs_as_json).toBeDefined(); 168 | // expect(test.txs_as_json.vin[0].key.amount).toEqual(9999999999); 169 | done(); 170 | }).catch((f) => { 171 | fail(f); 172 | done(); 173 | }); 174 | }); 175 | 176 | it("isKeyImageSpent", function (done) { 177 | monerod.isKeyImageSpent(["8d1bd8181bf7d857bdb281e0153d84cd55a3fcaa57c3e570f4a49f935850b5e3","7319134bfc50668251f5b899c66b005805ee255c136f0e1cecbb0f3a912e09d4"]).then((test) => { 178 | expect(test.status).toEqual("OK"); 179 | expect(test.spent_status).toEqual([SpentStatus.spentInBlockchain, SpentStatus.spentInBlockchain]); 180 | done(); 181 | }).catch((f) => { 182 | fail(f); 183 | done(); 184 | }); 185 | }); 186 | 187 | /* 188 | 189 | /sendrawtransaction is a critical rpc call. therefore this test should be activated by explicitly uncommenting it. 190 | 191 | it("sendRawTransaction should fail", function (done) { 192 | monerod.sendRawTransaction("abc").then((test) => { 193 | expect(test.status).toEqual("Failed"); 194 | expect(test.double_spend).toEqual(false); 195 | done(); 196 | }).catch((f) => { 197 | fail(f); 198 | done(); 199 | }); 200 | });*/ 201 | 202 | 203 | it("getTransactionPool", function (done) { 204 | monerod.getTransactionPool().then((test) => { 205 | expect(test.status).toEqual("OK"); 206 | done(); 207 | }).catch((f) => { 208 | fail(f); 209 | done(); 210 | }); 211 | }); 212 | 213 | it("submitBlock", function (done) { 214 | monerod.submitBlock("notablockblob").then((test) => { 215 | }).catch((f) => { 216 | // We expect a specific error msg for this rpc call cause we don't have any blocks to submit 217 | expect(f).toEqual("Daemon response error. Code: -6, Message: Wrong block blob"); 218 | done(); 219 | }); 220 | }); 221 | 222 | it("getVersion", function (done) { 223 | monerod.getVersion().then((data) => { 224 | expect(data.version).toBeGreaterThan(10) 225 | expect(data.status).toEqual("OK") 226 | done() 227 | }).catch((f) => { 228 | fail(f); 229 | done(); 230 | }); 231 | }); 232 | 233 | it("getFeeEstimate", function (done) { 234 | monerod.getFeeEstimate().then((data) => { 235 | expect(data.status).toEqual("OK") 236 | expect(data.fee).toBeGreaterThan(0) 237 | done() 238 | }).catch((f) => { 239 | fail(f); 240 | done(); 241 | }); 242 | }); 243 | 244 | }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monerod-js", 3 | "version": "2.1.1", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "jasmine --noStackTrace" 7 | }, 8 | "devDependencies": { 9 | "@types/jasmine": "^2.5.41", 10 | "@types/node": "^7.0.5", 11 | "jasmine": "^2.5.3" 12 | }, 13 | "author": "cryptoshrimpi", 14 | "repository" : 15 | { "type" : "git" 16 | , "url" : "https://github.com/cryptoshrimpi/monerod-js.git" 17 | }, 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "lib/js/test", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ], 9 | "stopSpecOnExpectationFailure": false, 10 | "random": false 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "removeComments": false, 8 | "noImplicitAny": false, 9 | "outDir": "lib/js" 10 | }, 11 | "include": [ 12 | "lib/ts/**/*" 13 | ] 14 | } --------------------------------------------------------------------------------