├── .nvmrc ├── test ├── mocha.opts └── index.spec.js ├── .travis.yml ├── .babelrc ├── src ├── index.js ├── wallet.js ├── connection-handler.js ├── messaging.js └── connection.js ├── .editorconfig ├── README.md ├── .npmignore ├── .gitignore ├── LICENSE ├── webpack.config.js ├── package.json └── .eslintrc /.nvmrc: -------------------------------------------------------------------------------- 1 | v6.10 2 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | -r jsdom-global/register -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | - "7" 5 | - "6" 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"], 3 | "plugins": ["babel-plugin-add-module-exports"] 4 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { registerApp, connectApp } from './connection-handler.js'; 2 | 3 | export default { registerApp, connectApp }; 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = LF 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED 2 | 3 | # radixdlt-js-lite 4 | 5 | A Javascript lite Client library for interacting with a [Radix](https://www.radixdlt.com) Distributed Ledger through the Desktop Wallet. 6 | 7 | # Usage Guide 8 | 9 | **NOTE:** Is higly recommended to use [NVM](https://github.com/creationix/nvm) 10 | 11 | 1. Make sure you have NodeJS 8 installed 12 | 13 | ``` 14 | $ nvm install v8 15 | $ nvm use v8 16 | ``` 17 | 18 | 2. Add the library to your project with the following command using `npm` or `yarn` 19 | 20 | ``` 21 | $ npm install --save radixdlt-js-lite 22 | ``` 23 | 24 | ``` 25 | $ yarn add radixdlt-js-lite 26 | ``` 27 | 28 | # Documentation 29 | 30 | - [Wiki](https://github.com/radixdlt/radixdlt-js-lite/wiki) 31 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # Remove some common IDE working directories 30 | .idea 31 | .vscode 32 | 33 | # Source Compiled 34 | src 35 | 36 | # Tests 37 | test 38 | 39 | .DS_Store 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # Remove some common IDE working directories 30 | .idea 31 | .vscode 32 | 33 | .DS_Store 34 | 35 | # Generated lib 36 | lib 37 | 38 | # Leftovers 39 | package-lock.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Radix DLT 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* global __dirname, require, module*/ 2 | 3 | const webpack = require('webpack'); 4 | const path = require('path'); 5 | const env = require('yargs').argv.env; // use --env with webpack 2 6 | const pkg = require('./package.json'); 7 | 8 | let libraryName = pkg.name; 9 | 10 | let outputFile, mode; 11 | 12 | if (env === 'build') { 13 | mode = 'production'; 14 | outputFile = libraryName + '.min.js'; 15 | } else { 16 | mode = 'development'; 17 | outputFile = libraryName + '.js'; 18 | } 19 | 20 | const config = { 21 | mode: mode, 22 | entry: __dirname + '/src/index.js', 23 | devtool: 'source-map', 24 | target: 'node', 25 | output: { 26 | path: __dirname + '/lib', 27 | filename: outputFile, 28 | library: libraryName, 29 | libraryTarget: 'umd', 30 | globalObject: 'typeof self !== \'undefined\' ? self : this' 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /(\.jsx|\.js)$/, 36 | loader: 'babel-loader' 37 | }, 38 | { 39 | test: /(\.jsx|\.js)$/, 40 | loader: 'eslint-loader' 41 | } 42 | ] 43 | }, 44 | resolve: { 45 | modules: [path.resolve('./node_modules'), path.resolve('./src')], 46 | extensions: ['.json', '.js'] 47 | } 48 | }; 49 | 50 | module.exports = config; 51 | -------------------------------------------------------------------------------- /src/wallet.js: -------------------------------------------------------------------------------- 1 | export default class Wallet { 2 | constructor(connection) { 3 | this._connection = connection; 4 | } 5 | /** 6 | * Get the balance. 7 | * @returns {Subject} 8 | */ 9 | getBalance() { 10 | // Method: 'balance' 11 | // Permissions: ['balance'] 12 | const params = {}; 13 | 14 | this._connection.pushRequest({ 15 | 'jsonrpc': '2.0', 16 | 'method': 'balance', 17 | 'params': params, 18 | 'id': 2 19 | }); 20 | 21 | return this._connection.getBalance; 22 | } 23 | /** 24 | * Send a transaction. 25 | * @param {string} recipient - Destination address. 26 | * @param {string} asset - Asset ISO. 27 | * @param {number} quantity - Amount to be sent (up to 5 decimals). 28 | * @returns {Subject} 29 | */ 30 | sendTransaction(recipient, asset, quantity, message) { 31 | // Method: 'send_transaction' 32 | // Permisions: ['send_transactions'] 33 | const params = { 34 | 'recipient': recipient, 35 | 'asset': asset, 36 | 'quantity': quantity, 37 | 'message': message 38 | }; 39 | 40 | this._connection.pushRequest({ 41 | 'jsonrpc': '2.0', 42 | 'method': 'send_transaction', 43 | 'params': params, 44 | 'id': 3 45 | }); 46 | 47 | return this._connection.sendTransaction; 48 | } 49 | /** 50 | * Get old and future transactions. 51 | * @returns {Subject} 52 | */ 53 | getTransactions() { 54 | // Method: 'transactions' 55 | // Permissions: ['transactions'] 56 | const params = {}; 57 | 58 | this._connection.pushRequest({ 59 | 'jsonrpc': '2.0', 60 | 'method': 'transactions', 61 | 'params': params, 62 | 'id': 4 63 | }); 64 | 65 | return this._connection.getTransactions; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "radixdlt-js-lite", 3 | "version": "0.1.8", 4 | "description": "A Javascript lite Client library for interacting with a RADIX Distributed Ledger through the Desktop Wallet.", 5 | "main": "lib/radixdlt-js-lite.js", 6 | "scripts": { 7 | "build": "webpack --env dev && webpack --env build && npm run test", 8 | "dev": "webpack --progress --colors --watch --env dev", 9 | "test": "mocha --require babel-register --colors ./test/*.spec.js", 10 | "test:watch": "mocha --require babel-register --colors -w ./test/*.spec.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/radixdlt/radixdlt-js-lite.git" 15 | }, 16 | "keywords": [ 17 | "webpack", 18 | "es6", 19 | "starter", 20 | "library", 21 | "universal", 22 | "umd", 23 | "commonjs" 24 | ], 25 | "author": "Mauricio Urraco ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/radixdlt/radixdlt-js-lite/issues" 29 | }, 30 | "homepage": "https://github.com/radixdlt/radixdlt-js-lite", 31 | "devDependencies": { 32 | "@babel/cli": "^7.0.0-beta.51", 33 | "@babel/core": "^7.0.0-beta.51", 34 | "@babel/preset-env": "^7.0.0-beta.51", 35 | "babel-eslint": "^8.0.3", 36 | "babel-loader": "^8.0.0-beta.4", 37 | "babel-plugin-add-module-exports": "^0.2.1", 38 | "babel-preset-env": "^7.0.0-beta.3", 39 | "babel-register": "^7.0.0-beta.3", 40 | "chai": "^4.1.2", 41 | "eslint": "^5.0.1", 42 | "eslint-loader": "^2.0.0", 43 | "fs": "0.0.1-security", 44 | "jsdom-global": "3.0.2", 45 | "mocha": "^4.0.1", 46 | "net": "^1.0.2", 47 | "tls": "0.0.1", 48 | "uglifyjs-webpack-plugin": "^1.2.7", 49 | "webpack": "^4.12.2", 50 | "webpack-cli": "^3.0.8", 51 | "yargs": "^10.0.3" 52 | }, 53 | "dependencies": { 54 | "jsdom": "^11.11.0", 55 | "request": "^2.87.0", 56 | "rxjs": "^6.2.1", 57 | "rxjs-compat": "^6.2.1", 58 | "ws": "^5.2.1" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/index.spec.js: -------------------------------------------------------------------------------- 1 | /* global describe, it, before */ 2 | 3 | import chai from 'chai'; 4 | import { registerApp } from '../src/index'; 5 | 6 | const name = 'Cashgrab'; 7 | const description = 'Takes all your money, I don\'t even know why you would accept this'; 8 | const permissions = [ 9 | 'address', 10 | 'balance', 11 | 'send_transaction', 12 | 'send_message', 13 | 'transactions', 14 | 'messages', 15 | 'application_messages' 16 | ]; 17 | 18 | let connection = null; 19 | let wallet = null; 20 | let messaging = null; 21 | 22 | describe('When I register my App', () => { 23 | it('should resolve the promise', (done) => { 24 | const resolvingPromise = registerApp(name, description, permissions); 25 | 26 | resolvingPromise.then((result) => { 27 | connection = result; 28 | done(); 29 | }); 30 | }); 31 | }); 32 | 33 | describe('Given an instance of my Wallet library', () => { 34 | before(() => { 35 | wallet = connection.getWallet(); 36 | }); 37 | describe('when I need all the transactions', () => { 38 | it('should return a Subject object with a subscribe method', () => { 39 | chai.expect(wallet.getTransactions().subscribe).to.exist; 40 | }); 41 | }); 42 | describe('when I want to get the balance', () => { 43 | it('should return a Subject object with a subscribe method', () => { 44 | chai.expect(wallet.getBalance().subscribe).to.exist; 45 | }); 46 | }); 47 | }); 48 | 49 | describe('Given an instance of my Messaging library', () => { 50 | before(() => { 51 | messaging = connection.getMessaging(); 52 | }); 53 | describe('when I need all the messages', () => { 54 | it('should return a Subject object with a subscribe method', () => { 55 | chai.expect(messaging.getMessages().subscribe).to.exist; 56 | }); 57 | }); 58 | }); 59 | 60 | describe('When I deregister my App', () => { 61 | before(() => { 62 | connection.deregister(); 63 | }); 64 | it('should close the connection properly', () => { 65 | setTimeout(() => { 66 | chai.expect(connection._connection._socket.readyState).to.not.be.equal(1); 67 | }, 2000); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /src/connection-handler.js: -------------------------------------------------------------------------------- 1 | import Wallet from './wallet.js'; 2 | import Messaging from './messaging.js'; 3 | import Connection from './connection.js'; 4 | 5 | class ConnectionHandler { 6 | constructor(connection) { 7 | this._connection = connection; 8 | } 9 | get token() { 10 | return this._connection.token; 11 | } 12 | /** 13 | * Close the web-socket connection. 14 | */ 15 | deregister() { 16 | this._connection.close(); 17 | } 18 | /** 19 | * Return a Wallet instance. 20 | * @returns {Wallet} 21 | */ 22 | getWallet() { 23 | if (this._connection) { 24 | return new Wallet(this._connection); 25 | } 26 | return null; 27 | } 28 | /** 29 | * Return a Messaging instance. 30 | * @returns {Messaging} 31 | */ 32 | getMessaging() { 33 | if (this._connection) { 34 | return new Messaging(this._connection); 35 | } 36 | return null; 37 | } 38 | /** 39 | * Get the address of the current wallet. 40 | * @returns {Subject} 41 | */ 42 | getAddress() { 43 | // Method: 'address' 44 | // Permissions: ['address'] 45 | const params = {}; 46 | 47 | this._connection.pushRequest({ 48 | 'jsonrpc': '2.0', 49 | 'method': 'address', 50 | 'params': params, 51 | 'id': 1 52 | }); 53 | 54 | return this._connection.getAddress; 55 | } 56 | } 57 | 58 | /** 59 | * Register an App. 60 | * @param {string} name - App's name. 61 | * @param {string} description - App's description. 62 | * @param {string[]} permissions - Permissions requested by this App. 63 | * @returns {Promise} 64 | */ 65 | function registerApp(name, description, permissions) { 66 | const CONNECTION = new Connection(); 67 | 68 | return new Promise((resolve, reject) => { 69 | CONNECTION.register(name, description, permissions) 70 | .then(() => resolve(new ConnectionHandler(CONNECTION))) 71 | .catch((error) => reject(error)); 72 | }); 73 | } 74 | 75 | /** 76 | * Re-connects an App with a valid token. 77 | * @param {string} token - Auth token. 78 | * @returns {Promise} 79 | */ 80 | function connectApp(token) { 81 | const CONNECTION = new Connection(); 82 | 83 | return new Promise((resolve, reject) => { 84 | CONNECTION.connect(token) 85 | .then(() => resolve(new ConnectionHandler(CONNECTION))) 86 | .catch((error) => reject(error)); 87 | }); 88 | } 89 | 90 | export default { registerApp, connectApp }; 91 | -------------------------------------------------------------------------------- /src/messaging.js: -------------------------------------------------------------------------------- 1 | export default class Messaging { 2 | constructor(connection) { 3 | this._connection = connection; 4 | } 5 | /** 6 | * Send a message. 7 | * @param {string} recipient - Destination address. 8 | * @param {string} message - Message to be sent. 9 | * @returns {Subject} 10 | */ 11 | sendMessage(recipient, message) { 12 | // Method: 'send_message' 13 | // Permissions: ['send_messages'] 14 | const params = { 15 | 'recipient': recipient, 16 | 'message': message 17 | }; 18 | 19 | this._connection.pushRequest({ 20 | 'jsonrpc': '2.0', 21 | 'method': 'send_message', 22 | 'params': params, 23 | 'id': 5 24 | }); 25 | 26 | return this._connection.sendMessage; 27 | } 28 | /** 29 | * Get old and future messages. 30 | * @returns {Subject} 31 | */ 32 | getMessages() { 33 | // Method: 'messages' 34 | // Permissions: ['messages'] 35 | const params = {}; 36 | 37 | this._connection.pushRequest({ 38 | 'jsonrpc': '2.0', 39 | 'method': 'messages', 40 | 'params': params, 41 | 'id': 6 42 | }); 43 | 44 | return this._connection.getMessages; 45 | } 46 | /** 47 | * Send an application message. 48 | * @param {string} applicationId - The application id. 49 | * @param {string[]} recipients - Destination addresses. 50 | * @param {Object} payload - Custom message. 51 | * @returns {Subject} 52 | */ 53 | sendApplicationMessage(applicationId, recipients, payload, encrypted) { 54 | // Method: 'send_application_message' 55 | // Permissions: ['send_application_messages'] 56 | const params = { 57 | 'application_id': applicationId, 58 | 'recipients': recipients, 59 | 'payload': payload, 60 | 'encrypted': encrypted 61 | }; 62 | 63 | this._connection.pushRequest({ 64 | 'jsonrpc': '2.0', 65 | 'method': 'send_application_message', 66 | 'params': params, 67 | 'id': 7 68 | }); 69 | 70 | return this._connection.sendApplicationMessage; 71 | } 72 | /** 73 | * Gets old and future application messages for a given application id. 74 | * @param {string} applicationId - The application id. 75 | * @returns {Subject} 76 | */ 77 | getApplicationMessages(applicationId) { 78 | // Method: 'application_messages' 79 | // Permissions: ['application_messages'] 80 | const params = { 81 | 'application_id': applicationId 82 | }; 83 | 84 | this._connection.pushRequest({ 85 | 'jsonrpc': '2.0', 86 | 'method': 'application_messages', 87 | 'params': params, 88 | 'id': 8 89 | }); 90 | 91 | return this._connection.getApplicationMessages; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "env": { 4 | "browser": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | 9 | "globals": { 10 | "document": false, 11 | "escape": false, 12 | "navigator": false, 13 | "unescape": false, 14 | "window": false, 15 | "describe": true, 16 | "before": true, 17 | "it": true, 18 | "expect": true, 19 | "sinon": true 20 | }, 21 | 22 | "parser": "babel-eslint", 23 | 24 | "plugins": [ 25 | 26 | ], 27 | 28 | "rules": { 29 | "block-scoped-var": 2, 30 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 31 | "camelcase": [2, { "properties": "always" }], 32 | "comma-dangle": [2, "never"], 33 | "comma-spacing": [2, { "before": false, "after": true }], 34 | "comma-style": [2, "last"], 35 | "complexity": 0, 36 | "consistent-return": 2, 37 | "consistent-this": 0, 38 | "curly": [2, "multi-line"], 39 | "default-case": 0, 40 | "dot-location": [2, "property"], 41 | "dot-notation": 0, 42 | "eol-last": 2, 43 | "eqeqeq": [2, "allow-null"], 44 | "func-names": 0, 45 | "func-style": 0, 46 | "generator-star-spacing": [2, "both"], 47 | "guard-for-in": 0, 48 | "handle-callback-err": [2, "^(err|error|anySpecificError)$" ], 49 | "indent": [2, 2, { "SwitchCase": 1 }], 50 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 51 | "keyword-spacing": [2, {"before": true, "after": true}], 52 | "linebreak-style": 0, 53 | "max-depth": 0, 54 | "max-len": [2, 120, 4], 55 | "max-nested-callbacks": 0, 56 | "max-params": 0, 57 | "max-statements": 0, 58 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 59 | "newline-after-var": [2, "always"], 60 | "new-parens": 2, 61 | "no-alert": 0, 62 | "no-array-constructor": 2, 63 | "no-bitwise": 0, 64 | "no-caller": 2, 65 | "no-catch-shadow": 0, 66 | "no-cond-assign": 2, 67 | "no-console": 0, 68 | "no-constant-condition": 0, 69 | "no-continue": 0, 70 | "no-control-regex": 2, 71 | "no-debugger": 2, 72 | "no-delete-var": 2, 73 | "no-div-regex": 0, 74 | "no-dupe-args": 2, 75 | "no-dupe-keys": 2, 76 | "no-duplicate-case": 2, 77 | "no-else-return": 2, 78 | "no-empty": 0, 79 | "no-empty-character-class": 2, 80 | "no-eq-null": 0, 81 | "no-eval": 2, 82 | "no-ex-assign": 2, 83 | "no-extend-native": 2, 84 | "no-extra-bind": 2, 85 | "no-extra-boolean-cast": 2, 86 | "no-extra-parens": 0, 87 | "no-extra-semi": 0, 88 | "no-extra-strict": 0, 89 | "no-fallthrough": 2, 90 | "no-floating-decimal": 2, 91 | "no-func-assign": 2, 92 | "no-implied-eval": 2, 93 | "no-inline-comments": 0, 94 | "no-inner-declarations": [2, "functions"], 95 | "no-invalid-regexp": 2, 96 | "no-irregular-whitespace": 2, 97 | "no-iterator": 2, 98 | "no-label-var": 2, 99 | "no-labels": 2, 100 | "no-lone-blocks": 0, 101 | "no-lonely-if": 0, 102 | "no-loop-func": 0, 103 | "no-mixed-requires": 0, 104 | "no-mixed-spaces-and-tabs": [2, false], 105 | "no-multi-spaces": 2, 106 | "no-multi-str": 2, 107 | "no-multiple-empty-lines": [2, { "max": 1 }], 108 | "no-native-reassign": 2, 109 | "no-negated-in-lhs": 2, 110 | "no-nested-ternary": 0, 111 | "no-new": 2, 112 | "no-new-func": 2, 113 | "no-new-object": 2, 114 | "no-new-require": 2, 115 | "no-new-wrappers": 2, 116 | "no-obj-calls": 2, 117 | "no-octal": 2, 118 | "no-octal-escape": 2, 119 | "no-path-concat": 0, 120 | "no-plusplus": 0, 121 | "no-process-env": 0, 122 | "no-process-exit": 0, 123 | "no-proto": 2, 124 | "no-redeclare": 2, 125 | "no-regex-spaces": 2, 126 | "no-reserved-keys": 0, 127 | "no-restricted-modules": 0, 128 | "no-return-assign": 2, 129 | "no-script-url": 0, 130 | "no-self-compare": 2, 131 | "no-sequences": 2, 132 | "no-shadow": 0, 133 | "no-shadow-restricted-names": 2, 134 | "no-spaced-func": 2, 135 | "no-sparse-arrays": 2, 136 | "no-sync": 0, 137 | "no-ternary": 0, 138 | "no-throw-literal": 2, 139 | "no-trailing-spaces": 2, 140 | "no-undef": 2, 141 | "no-undef-init": 2, 142 | "no-undefined": 0, 143 | "no-underscore-dangle": 0, 144 | "no-unneeded-ternary": 2, 145 | "no-unreachable": 2, 146 | "no-unused-expressions": 0, 147 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 148 | "no-use-before-define": 2, 149 | "no-var": 0, 150 | "no-void": 0, 151 | "no-warning-comments": 0, 152 | "no-with": 2, 153 | "one-var": 0, 154 | "operator-assignment": 0, 155 | "operator-linebreak": [2, "after"], 156 | "padded-blocks": 0, 157 | "quote-props": 0, 158 | "quotes": [2, "single", "avoid-escape"], 159 | "radix": 2, 160 | "semi": [2, "always"], 161 | "semi-spacing": 0, 162 | "sort-vars": 0, 163 | "space-before-blocks": [2, "always"], 164 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], 165 | "space-in-brackets": 0, 166 | "space-in-parens": [2, "never"], 167 | "space-infix-ops": 2, 168 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 169 | "spaced-comment": [2, "always"], 170 | "strict": 0, 171 | "use-isnan": 2, 172 | "valid-jsdoc": 0, 173 | "valid-typeof": 2, 174 | "vars-on-top": 2, 175 | "wrap-iife": [2, "any"], 176 | "wrap-regex": 0, 177 | "yoda": [2, "never"] 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/connection.js: -------------------------------------------------------------------------------- 1 | import { Subject } from 'rxjs/Subject'; 2 | 3 | const WS = global.WebSocket || global.MozWebSocket || require('ws'); 4 | 5 | class Queue extends Subject { 6 | constructor() { 7 | super(); 8 | this._items = []; 9 | } 10 | add(item) { 11 | if (this.observers.length > 0) { 12 | this.next(item); 13 | } else { 14 | this._items.push(item); 15 | } 16 | } 17 | subscribe(observer) { 18 | let s = super.subscribe(observer); 19 | 20 | this._items.forEach(item => this.next(item)); 21 | this._items = []; 22 | return s; 23 | } 24 | }; 25 | 26 | export default class Connection { 27 | constructor() { 28 | this._token = new Subject(); 29 | this._messages = new Queue(); 30 | 31 | this._getAddress = new Subject(); 32 | this._getBalance = new Subject(); 33 | this._sendTransaction = new Subject(); 34 | this._getTransactions = new Subject(); 35 | this._sendMessage = new Subject(); 36 | this._getMessages = new Subject(); 37 | this._sendApplicationMessage = new Subject(); 38 | this._getApplicationMessages = new Subject(); 39 | } 40 | get getAddress() { 41 | return this._getAddress; 42 | } 43 | get getBalance() { 44 | return this._getBalance; 45 | } 46 | get sendTransaction() { 47 | return this._sendTransaction; 48 | } 49 | get getTransactions() { 50 | return this._getTransactions; 51 | } 52 | get sendMessage() { 53 | return this._sendMessage; 54 | } 55 | get getMessages() { 56 | return this._getMessages; 57 | } 58 | get sendApplicationMessage() { 59 | return this._sendApplicationMessage; 60 | } 61 | get getApplicationMessages() { 62 | return this._getApplicationMessages; 63 | } 64 | get token() { 65 | return this._tokenValue; 66 | } 67 | register(name, description, permissions) { 68 | const request = JSON.stringify({ 69 | jsonrpc: '2.0', 70 | method: 'register', 71 | params: { 72 | 'name': name, 73 | 'description': description, 74 | 'permissions': permissions 75 | }, 76 | id: 0 77 | }); 78 | 79 | return new Promise((resolve, reject) => { 80 | this._socket = new WS('ws://localhost:54345'); 81 | this._socket.onopen = () => this.handleOpen(request, resolve, reject); 82 | this._socket.onmessage = (evt) => this.handleResponse(evt.data); 83 | this._socket.onerror = (error) => reject(`WebSocket Error: ${JSON.stringify(error)}`); 84 | this._socket.onclose = () => this.handleClose(); 85 | }); 86 | } 87 | connect(token) { 88 | const request = JSON.stringify({ 89 | jsonrpc: '2.0', 90 | method: 'ping', 91 | params: { 92 | 'token': token 93 | }, 94 | id: 9 95 | }); 96 | 97 | this._tokenValue = token; 98 | 99 | return new Promise((resolve, reject) => { 100 | this._socket = new WS('ws://localhost:54345'); 101 | this._socket.onopen = () => this.handleOpen(request, resolve, reject); 102 | this._socket.onmessage = (evt) => this.handleResponse(evt.data); 103 | this._socket.onerror = (error) => reject(`WebSocket Error: ${JSON.stringify(error)}`); 104 | this._socket.onclose = () => this.handleClose(); 105 | }); 106 | } 107 | handleOpen(request, resolve, reject) { 108 | this._socket.send(request); 109 | this._token.subscribe( 110 | token => { 111 | resolve(); 112 | this._tokenValue = token; 113 | this._messages.subscribe(message => { 114 | message.params.token = token; 115 | message = JSON.stringify(message); 116 | this._socket.send(message); 117 | }); 118 | }, 119 | error => reject(error) 120 | ); 121 | } 122 | handleResponse(response) { 123 | response = JSON.parse(response); 124 | if (response.hasOwnProperty('result') || response.hasOwnProperty('params')) { 125 | this.getResponse(response); 126 | } else { 127 | this.getError(response); 128 | } 129 | } 130 | getResponse(response) { 131 | switch (response.id) { 132 | case 0: // register 133 | this._token.next(response.result.token); 134 | break; 135 | case 1: // getAddress 136 | this._getAddress.next(response.result); 137 | break; 138 | case 2: // getBalance 139 | case 4: // getTransactions 140 | case 6: // getMessages 141 | case 8: // getApplicationMessages 142 | // console.log(response.result); 143 | break; 144 | case 3: // sendTransaction 145 | this._sendTransaction.next(response.result); 146 | break; 147 | case 5: // sendMessage 148 | this._sendMessage.next(response.result); 149 | break; 150 | case 7: // sendApplicationMessage 151 | this._sendApplicationMessage.next(response.result); 152 | break; 153 | case 9: // connect 154 | this._token.next(this._tokenValue); 155 | break; 156 | default: 157 | switch (response.method) { 158 | case 'balance.update': 159 | this._getBalance.next(response.params.TEST); 160 | break; 161 | case 'transaction.update': 162 | this._getTransactions.next(response.params); 163 | break; 164 | case 'message.update': 165 | this._getMessages.next(response.params); 166 | break; 167 | case 'application_message.update': 168 | this._getApplicationMessages.next(response.params); 169 | break; 170 | default: 171 | console.log('The method is not supported'); 172 | break; 173 | } 174 | break; 175 | } 176 | } 177 | getError(response) { 178 | switch (response.id) { 179 | case 0: // register 180 | this._token.error(response.error); 181 | break; 182 | case 1: // getAddress 183 | this._getAddress.error(response.error); 184 | break; 185 | case 2: // getBalance 186 | case 4: // getTransactions 187 | case 6: // getMessages 188 | case 8: // getApplicationMessages 189 | // console.log(response.result); 190 | break; 191 | case 3: // sendTransaction 192 | this._sendTransaction.error(response.error); 193 | break; 194 | case 5: // sendMessage 195 | this._sendMessage.error(response.error); 196 | break; 197 | case 7: // sendApplicationMessage 198 | this._sendApplicationMessage.error(response.error); 199 | break; 200 | case 9: // connect 201 | this._token.error(response.error); 202 | break; 203 | default: 204 | console.log('The method is not supported'); 205 | break; 206 | } 207 | } 208 | handleClose() { 209 | this._token.unsubscribe(); 210 | this._messages.unsubscribe(); 211 | } 212 | pushRequest(request) { 213 | this._messages.add(request); 214 | } 215 | close() { 216 | setTimeout(() => { 217 | if (this._socket.readyState === 1) { 218 | this._socket.close(); 219 | } 220 | }, 2000); 221 | } 222 | } 223 | --------------------------------------------------------------------------------