From ccaf9d5a1e19816c16c483328af7438c8b34b2e7 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Sun, 10 Feb 2019 20:39:53 -0400 Subject: [PATCH] Updating README and examples - pt 1 --- README.md | 237 +++++++++++++++++- test-mailserver.js => examples/mailserver.js | 2 +- .../private-messages.js | 26 +- examples/public-messages.js | 23 ++ src/index.ts | 13 + test-public-messages.js | 29 --- 6 files changed, 271 insertions(+), 59 deletions(-) rename test-mailserver.js => examples/mailserver.js (96%) rename test-private-messages.js => examples/private-messages.js (82%) create mode 100644 examples/public-messages.js delete mode 100644 test-public-messages.js diff --git a/README.md b/README.md index a7146a9..44bf8c2 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,230 @@ Javascript client for sending / receiving messages in Status


-## Install -clone the repo via git: + + +## Installation + +``` +npm install status-js-api +``` +Alternatively, you can use `yarn`. + +## Usage + +### Requirements +This package requires `geth`, `status-go`, or `murmur` to be able to connect to Whisper v6. + +#### Using `geth` + +Use the following command and flags to start `geth` + +``` +$ geth --testnet --syncmode=light --ws --wsport=8546 --wsaddr=localhost --wsorigins=statusjs --rpc --maxpeers=25 --shh --shh.pow=0.002 --wsapi=web3,shh,admin +``` + +Also, due to the lack of nodes with Whisper enabled, you need to create a [static-nodes.json](https://github.com/status-im/status-js/blob/master/static-nodes.json) file, that must be placed in a specific path (if using `ropsten` in a linux environment, `~/.ethereum/testnet/geth/static-nodes.json` + +#### Using `murmur` +``` +$ murmur-client --ws --no-bridge +``` +See `murmur` [documentation](https://github.com/status-im/murmur) for additional details. + +#### Using `status-go` +``` +$ /path/to/status-go/statusd +``` +See `status-go` [documentation](https://github.com/status-im/status-go) for additional details. + + +## API +**constructor** +Constructs a new status client object + +```javascript +new StatusJS(); +``` +```javascript +// basic instantiation +const StatusJS = require('status-js-api'); +const status = new StatusJS(); +``` + + + +**connect** +Connect to a web3 whisper provider + +```javascript +status.connect(url, [privateKey]); +``` + +```javascript +await status.connect("ws://localhost:8546", "0x1122...9900"); +``` + +Arguments +* _url_ - an address of a valid http, websocket or ipc provider. +* _privateKey_ - private key of the user that will send / receive messages. It will be added to the whisper node. Default: random private key. Optional + + + +**connectToProvider** +Connect to a custom web3 whisper provider + +```javascript +status.connectToProvider(provider, [privateKey]); +``` + +```javascript +await status.connect(murmurClient.provider, "0x1122...9900"); +``` + +Arguments +* _provider_ - Custom web3 provider +* _privateKey_ - private key of the user that will send / receive messages. It will be added to the whisper node. Default: random private key. Optional + + + +**isListening** +Checks if the node is listening for peers. + +```javascript +status.isListening() +``` + +```javascript +if (status.isListening()) { + // Do something +} +``` + + + +**joinChat** +Joins a public channel + +```javascript +status.joinChat(channel); +``` + +```javascript +await status.joinChat("#mytest"); +``` + +Arguments +* _channel_ - public channel name. + + + +**onMessage** +Process incoming public and private messages + +```javascript +status.onMessage(channel, cb); // public messages +status.onMessage(cb); // private messages +``` + +```javascript +status.onMessage("#mytest", (err, data) => { + if(err) + console.error(err); + else + console.dir(data); // message information +}); +``` + +Arguments +* _channel_ - public channel name. Optional +* _cb_ - a callback that will be called, possibly with an error, when a message is received. If there is no error, the first argument will be null. + + + +**isSubscribedTo** +Check if client has joined a channel + +```javascript +status.isSubscribedTo(channel); +``` + +```javascript +if (status.isSubscribedTo("#mytest")) { + // Do something +} +``` + +Arguments +* _channel_ - public channel name. + + + +**leaveChat** +Leaves a public channel + +```javascript +status.leaveChat(channel); +``` + +```javascript +status.leaveChat("#mytest"); +``` + +Arguments +* _channel_ - public channel name. + + + +**getPublicKey** +Returns a string with the public key + +```javascript +status.getPublicKey(); +``` + +```javascript +await status.getPublicKey(); // "0x1122...9900" +``` + + + +**getUserName** +Returns the random username for the public key + +```javascript +status.getUserName([pubKey]); +``` + +```javascript +await status.getUserName(); // "Adjective1 Adjective2 Animal" +await status.getUserName("0x1122...9900"); +``` + +Arguments +* _pubKey_ - public key to obtain the username. Default: generate username for the current user. Optional. + + +### TODO +* addContact(contactCode, cb) +* removeContact(contactCode) +* onChatRequest(cb) +* onChannelMessage(channelName, cb) +* onUserMessage(cb) +* sendUserMessage(contactCode, msg, [cb]) +* sendGroupMessage(channelName, msg, [cb]) +* sendJsonMessage(destination, msg, [cb]) +* sendMessage(destination, msg, [cb]) +* mailservers.useMailserver(enode, [cb]) +* mailservers.requestUserMessages(options, cb) +* mailservers.requestChannelMessages(topic, options, cb) + + +See the examples for usage in the meantime + + + +## Development +Clone the repo via git: ``` $ git clone https://github.com/status-im/status-js.git ``` @@ -26,17 +248,6 @@ $ yarn run start $ yarn run lint ```` -`status-js` requires `geth` or `murmur` to be able to connect to Whisper. If using `geth`, you may start it with the following flags. - -`geth --testnet --syncmode=light --ws --wsport=8546 --wsaddr=localhost --wsorigins=statusjs --rpc --maxpeers=25 --shh --shh.pow=0.002 --wsapi=eth,web3,net,shh,debug,admin` - -Also, due to the lack of nodes with Whisper enabled, you need to create a [static-nodes.json](https://github.com/status-im/murmur/blob/master/src/data/static-nodes.json) file, that must be placed in a specific path (if using testnet and Linux, `~/.ethereum/testnet/geth/static-nodes.json` - -## API -*TODO* -See test files for use in the meantime - - ## Contribution Thank you for considering to help out with the source code! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! diff --git a/test-mailserver.js b/examples/mailserver.js similarity index 96% rename from test-mailserver.js rename to examples/mailserver.js index d000b03..c74b3d3 100644 --- a/test-mailserver.js +++ b/examples/mailserver.js @@ -1,4 +1,4 @@ -var StatusJS = require('./dist/index.js'); +var StatusJS = require('../dist/index.js'); (async () => { var status = new StatusJS(); diff --git a/test-private-messages.js b/examples/private-messages.js similarity index 82% rename from test-private-messages.js rename to examples/private-messages.js index 5c4ee65..b4a3cb6 100644 --- a/test-private-messages.js +++ b/examples/private-messages.js @@ -1,14 +1,12 @@ -const StatusJS = require('./dist/index.js'); +const StatusJS = require('../dist/index.js'); const Web3 = require('web3'); -const { utils: { asciiToHex, hexToAscii } } = Web3; (async () => { let status1 = new StatusJS(); - await status1.connect("ws://localhost:8546"); - let status2 = new StatusJS(); - await status2.connect("ws://localhost:8546"); + await status1.connect("ws://localhost:8546"); + await status2.connect("ws://localhost:8546"); const user1pubKey = await status1.getPublicKey(); const user2pubKey = await status2.getPublicKey(); @@ -17,25 +15,21 @@ const { utils: { asciiToHex, hexToAscii } } = Web3; console.log("user2 (" + await status2.getUserName() + "):\n" + user2pubKey); console.log("\n") - const receivedMessageCb = (username) => (err, data) => { + if(err){ + console.error("Error: " + err); + return; + } + console.log( username + " received a message from " + data.username); console.log(data.data.sig); console.log(data.payload) }; - - + status1.onMessage(receivedMessageCb('user1')); status2.onMessage(receivedMessageCb('user2')); status1.addContact(user2pubKey); status1.sendMessage(user2pubKey, "hello user2!"); - status2.sendMessage(user1pubKey, "hello user1!"); - - - // Text someone at status - //status1.sendMessage("0xcontact_code_here", "hello!"); - - -})() +})(); diff --git a/examples/public-messages.js b/examples/public-messages.js new file mode 100644 index 0000000..8ac2a82 --- /dev/null +++ b/examples/public-messages.js @@ -0,0 +1,23 @@ +const StatusJS = require('./dist/index.js'); + +(async () => { + const status = new StatusJS(); + + await status.connect("ws://localhost:8546"); + + await status.joinChat("mytest"); + + status.onMessage("mytest", (err, data) => { + if(err) { + console.error("Error: " + err); + return; + } + + console.log("message received:"); + console.dir(data); + }); + + setInterval(() => { + status.sendMessage("#mytest", "hello world!"); + }, 3000); +})(); diff --git a/src/index.ts b/src/index.ts index 2f912de..03731d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -109,7 +109,14 @@ class StatusJS { return utils.generateUsernameFromSeed(pubKey); } + private cleanChannelName(c: string) { + if(c.startsWith('#')) return c.substr(1); + return c; + } + public async joinChat(channelName: string, cb?: any) { + channelName = this.cleanChannelName(channelName); + const channelKey = await this.shh.generateSymKeyFromPassword(channelName); this.channels[channelName] = { channelCode: Web3.utils.sha3(channelName).slice(0, 10), @@ -133,6 +140,8 @@ class StatusJS { } public leaveChat(channelName: string) { + channelName = this.cleanChannelName(channelName); + if (!this.isHttpProvider) { this.channels[channelName].subscription.unsubscribe(); } else { @@ -149,6 +158,7 @@ class StatusJS { } public isSubscribedTo(channelName: string) { + channelName = this.cleanChannelName(channelName); return !!this.channels[channelName]; } @@ -165,6 +175,8 @@ class StatusJS { } public onChannelMessage(channelName: string, cb: any) { + channelName = this.cleanChannelName(channelName); + if (!this.channels[channelName]) { return cb("unknown channel: " + channelName); } @@ -297,6 +309,7 @@ class StatusJS { } public sendGroupMessage(channelName: string, msg: string, cb?: any) { + channelName = this.cleanChannelName(channelName); if (!this.channels[channelName]) { if (!cb) { return; diff --git a/test-public-messages.js b/test-public-messages.js deleted file mode 100644 index afd48bb..0000000 --- a/test-public-messages.js +++ /dev/null @@ -1,29 +0,0 @@ -var StatusJS = require('./dist/index.js'); - -(async () => { -var status = new StatusJS(); - await status.connect("ws://localhost:8546"); - - await status.joinChat("mytest"); - await status.joinChat("mytest2"); - - status.onMessage("mytest", (err, data) => { - console.dir("received from api"); - console.dir("message received!"); - console.dir(data); - }); - - status.onMessage("mytest2", (err, data) => { - console.dir("received from mytest2"); - console.dir("message received!"); - console.dir(data); - }); - - status.sendMessage("mytest", "hello world!"); - - setInterval(() => { - status.sendMessage("mytest", "hello world!"); - status.sendMessage("mytest2", "hello world!2"); - }, 3000); - -})()