/ archive / Status_API.md
Status_API.md
  1  [<https://github.com/status-im/status-react/blob/develop/resources/js/status.js#L216>](https://github.com/status-im/status-react/blob/develop/resources/js/status.js#L234)
  2  
  3  ### status
  4  
  5  Remember, this is all about Ethereum. Anywhere.
  6  
  7  Below you will find the formal API specification from which you can
  8  glean all the information you need to make your DApp truly mobile, with
  9  native mobile commands and an intuitive chat interface through which
 10  users can actually see, interact with, and pay for the services you
 11  offer.
 12  
 13  #### status.command
 14  
 15  ##### Examples
 16  
 17  A really simple template:
 18  
 19      status.command({
 20          name: 'hello',
 21          title: 'HelloBot',
 22          description: 'Helps you say hello',
 23          color: '#7099e6',
 24          preview: function () {
 25              return status.components.text({}, 'you’re saying hello');
 26          }
 27      });
 28  
 29  It is important to note that params are available for any
 30  `status.command()`, including in params itself. For instance, if your
 31  user sends /hello whatsup, the input "whatsup" will be available in your
 32  command under params.hello. You can add additional params to - for
 33  instance - preview like so:
 34  
 35      params: [{
 36          name: 'hello',
 37          type: status.types.TEXT
 38          placeholder: 'Why not say hello'
 39      }],
 40  
 41  The placeholder parameter above only applies if your users haven’t input
 42  anything into the command, not even the name. You can use it to include
 43  helpful guidance where necessary, i.e. "Type your password".
 44  Alternatively, you can also include suggestions for your users’ input.
 45  This should return a component to be rendered. For instance, if you are
 46  using the Console DApp and you select the `/faucet` command, you’ll see
 47  two suggestions to choose from.
 48  
 49  Example validator function (this specific example will raise an error if
 50  your user doesn’t input a string. Notice that you should return your
 51  message inside one of the status.components):
 52  
 53      validator: function(params) {
 54          if (!params.hello) {
 55              return status.components.text({}, "Say hello");
 56          }
 57      }
 58  
 59  Example of the request command to get a user send some amount of Ether
 60  somewhere:
 61  
 62      handler: function (params) {
 63          return {
 64              event: 'request',
 65              params: [params.amount],
 66              request: {
 67                  command: 'send',
 68                  params: {
 69                      amount: params.amount
 70                  }
 71              }
 72          };
 73      },
 74  
 75  Full example of pretty much all the status.command stuff in action:
 76  
 77      status.command({
 78          name: 'faucet',
 79          title: I18n.t('faucet_title'),
 80          description: I18n.t('faucet_description'),
 81          color: '#7099e6',
 82          registeredOnly: true,
 83          params: [{
 84              name: 'url',
 85              type: status.types.TEXT,
 86              suggestions: faucetSuggestions,
 87              placeholder: I18n.t('faucet_placeholder')
 88          }],
 89          preview: function (params) {
 90              return {
 91                  markup: status.components.text(
 92                      {},
 93                      params.url
 94                  )
 95              };
 96          },
 97          shortPreview: function (params) {
 98              return {
 99                  markup: status.components.text(
100                      {},
101                      I18n.t('faucet_title') + ': ' + params.url
102                  )
103              };
104          },
105          validator: function (params, context) {
106              var f = faucets.map(function (entry) {
107                  return entry.url;
108              });
109  
110              if (f.indexOf(params.url) == -1) {
111                  var error = status.components.validationMessage(
112                      I18n.t('faucet_incorrect_title'),
113                      I18n.t('faucet_incorrect_description')
114                  );
115  
116                  return {markup: error};
117              }
118          }
119      });
120  
121  ##### Parameters
122  
123  | Argument                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
124  | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
125  | name                         | What your users will type in following a forward slash to invoke the command. For instance, if you wrote `name: "hello"`, your user might invoke `/hell`o. There is an additional `params` object available on any of the below commands, including in params itself.                                                                                                                                                                                                                                                                                                                                                                                                 |
126  | title                        | This is what will appear in the list of suggestions when a user starts typing a command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
127  | description                  | Appears below the `title` in the list of suggestions and allows you to provide a description of the command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
128  | validator                    | Allows you to check your users’ input before sending off the command. It takes a function, which should return an error if the input is invalid.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
129  | color                        | Defines the background color of the name of your command as it appears in the list of suggestions. Give commands different colors to help your users distinguish commands easily, and to harmonize with your DApp’s brand and color scheme.                                                                                                                                                                                                                                                                                                                                                                                                                           |
130  | icon                         | Define which icon will appear next to action messages, such as sending Ether or requesting a location. Think an arrow for sending, a pin for location etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
131  | params                       | Defines all the possible inputs to your command. Requires an array holding an object, with possible parameters name, `placeholder`, `suggestions`, and one of the `status.types`, which are: `status.types.TEXT`, `status.types.NUMBER`, `status.types.PHONE`, and `status.types.PASSWORD`.                                                                                                                                                                                                                                                                                                                                                                           |
132  | preview                      | Defines what your user will see as a result of \*their\* action, before any other response. The preview parameter takes a function, which should return a `status.component`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
133  | shortPreview                 | While `preview` controls how your command appears within your DApp’s chat interface, `short-preview` controls how your commands get shown in the list of chats, before your users tap on your chat. `short-prview` expects two params: `icon` and `params`.                                                                                                                                                                                                                                                                                                                                                                                                           |
134  | onSend                       | A self-explanatory param that takes a function which will be executed when the user presses the "send" button. It will return a map that should contain the markup value. If you specify this function, there will be no way to send a command to the chat and, in this case, the area (it’s called the `result-box`) with a specified markup will be displayed instead.                                                                                                                                                                                                                                                                                              |
135  | fullscreen                   | If your command has suggestions, this param controls whether that list of suggestions expands to fill the entire screen. See the interactive suggestion area tutorial for more.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
136  | request                      | This will allow you to request any action from the user, such as a phone number, password, confirmation to send Ether etc. Used with the `executeImmediately` option set to `true`, it will create a message the user can tap on an execute immediately.                                                                                                                                                                                                                                                                                                                                                                                                              |
137  | executeImmediately (Boolean) | If true, this means that the `response` will be executed immediately when you press on it. For instance, when you see a response in a chat, you don’t have to type something — you just need to press on a response and it will be executed right after that.                                                                                                                                                                                                                                                                                                                                                                                                         |
138  | sequentialParams (Boolean)   | Specifies the way command arguments will be "requested". The default approach (`sequentialParams = false`) is to type a command this way: `/send 0.1 ETH somebody`, where `0.1`, `ETH` and `somebody` are arguments. However, there may be situations when you want to ask each argument separately. You can see the difference by executing `/password` command; it asks you for a password and, only after the user has provided one, requests confirmation. Currently there is one limitation — you can use argument types (`type` value) only for `sequentialParams`, and if you want to (for example) hide the argument input, you should use `sequentialParams` |
139  | handler (\!= null)           | Of course, you probably want the command to do something when your users call it\! The `handler` parameter takes a function to accomplish this. For instance, suppose your user inputs `/hello howdy`. "Howdy" is a valid string, and will pass the `hello` validator. From there, your handler could take over to send this greeting to another user: `handler: web3.shh.post(params.hello)`.                                                                                                                                                                                                                                                                        |
140  
141  #### status.response
142  
143  An example response for a confirmation code sent via SMS:
144  
145      status.response({
146          name: 'confirmation-code',
147          color: '#7099e6',
148          description: I18n.t('confirm_description'),
149          sequentialParams: true,
150          params: [{
151              name: 'code',
152              type: status.types.NUMBER
153          }],
154          validator: function (params) {
155              if (!/^[\d]{4}$/.test(params.code)) {
156                  var error = status.components.validationMessage(
157                      I18n.t('confirm_validation_title'),
158                      I18n.t('confirm_validation_description')
159                  );
160  
161                  return {markup: error};
162              }
163          }
164      });
165  
166  Now that you’ve covered all the parameters for `status.command()`, you
167  can easily understand `status.response()`. This method takes the same
168  parameters that `status.command()` does. The difference is that, with
169  this method, you can actively ask a user to issue a command of their
170  own.
171  
172  For example, the Status DApp Wallet allows you to `/request` money. In
173  that case, the person you’re requesting money from will see the result
174  of `status.response(send)`. In other words, they’ll be asked to give a
175  command, `/send`, in response to your `/request` command. Please check
176  line 77-158
177  [here](https://github.com/status-im/status-react/blob/30596f743f0a6ac0b7aec575cc1483dd306cc1ef/bots/wallet/bot.js#L77)
178  for more code.
179  
180  The Wallet example illustrates that, as a DApp developer, you may wish
181  to use `status.command()` and `status.response()` together to create
182  dialogues of commands. You can also just use `status.response()` by
183  itself to prompt your users to enter necessary information as part of
184  the onboarding process for your DApp.
185  
186  Because `status.command()` and `status.response()` take the same
187  parameters, you can sometimes use nearly the same code for both of them.
188  You simply have to consider when you want to ask a user to issue a
189  command, and when you want to just make the command available. Most of
190  the time, you’ll use `status.command()`.
191  
192  #### status.on
193  
194      status.on('init', function(params, context) {
195        status.sendMessage("Hello, man!");
196      });
197  
198  This method allows your DApp to respond to events. It requires an event
199  name as a string, and a callback function. With the "init" option shown
200  here, your DApp will trigger `status.sendMessage()` when the Status app
201  loads your DApp — your DApp will greet your users even before they have
202  clicked on it. Other options include "text-change" and "message"
203  
204  #### status.addListener
205  
206  ##### Examples
207  
208      status.addListener('on-message-input-change',
209       function (params, context) {
210          return jsSuggestions({code: params.message}, context);
211      });
212  
213      status.addListener('init',
214       function (params, context) {
215          return {'text-message': 'Hey, man!'};
216      });
217  
218      status.addListener('on-message-send', function (params, context) {
219          if (isNaN(params.message)) {
220              return {'text-message': 'Seems that you don't want to send money :('};
221          }
222  
223          var balance = web3.eth.getBalance(context.from);
224          var value = parseFloat(params.message);
225          var weiValue = web3.toWei(value, 'ether');
226          if (bn(weiValue).greaterThan(bn(balance))) {
227              return {'text-message': 'No way man, you don't have enough money! :)'};
228          }
229          try {
230              web3.eth.sendTransaction({
231                  from: context.from,
232                  to: context.from,
233                  value: weiValue
234              });
235              return {'text-message': 'You are the hero, you sent ' + value + ' ETH to yourself!'};
236          } catch (err) {
237              return {'text-message': 'Something went wrong :('};
238          }
239      });
240  
241  ##### Listeners
242  
243  | Listener                | Description                                                                                                                                                                                                                                                                                                                       |
244  | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
245  | on-message-input-change | This is analogous to a `text-change` event, except that it targets the chat’s input. You can find the jsSuggestions that are passed in in the example [here](https://github.com/status-im/status-react/blob/develop/resources/js/bots/console/bot.js#L316).                                                                       |
246  | init                    | Is called once, when a new session begins ("session" is currently taken to mean the interval between login and logout from a user's account). In the example provided the bot will just send the "Hey, man\!" message to the user, but it could also it could return \`markup\` which will be shown in the suggestions area, etc. |
247  | on-message-send         | Will be called when any (not command) message is sent. The example provided shows you how to send ether to yourself as a neat way of testing the functionality.                                                                                                                                                                   |
248  
249  #### status.localizeNumber
250  
251  ```
252  preview: function (params, context) {
253          return {
254              markup: status.components.text(
255                  {},
256                  I18n.t('request_requesting') + ' '
257                  + status.localizeNumber(params.amount, context.delimiter, context.separator)
258                  + ' ETH'
259              )
260          };
261      },
262  
263  ```
264  
265  A simple method to try and ensure that whatever number the user inputs,
266  is put into a usable format. The example provided shows it in use to
267  make sure the number requesting ETH is handled correctly. This is part
268  of a larger `status.command()` object that can be found
269  [here](https://github.com/status-im/status-react/blob/30596f743f0a6ac0b7aec575cc1483dd306cc1ef/bots/wallet/bot.js#L182).
270  
271  #### status.types
272  
273      types: {
274          TEXT: 'text',
275          NUMBER: 'number',
276          PHONE: 'phone',
277          PASSWORD: 'password'
278      }
279  
280  Types dictate what sort of data your users may input. The type you
281  specify will determine what kind of keyboard gets shown to the user (if
282  you have not already defined a custom one) so that they can input their
283  response easily. It is important to specify them for a smooth, easy, and
284  intuitive UI.
285  
286  ##### status.types.TEXT
287  
288      status.command({
289          name: 'faucet',
290          title: I18n.t('faucet_title'),
291          description: I18n.t('faucet_description'),
292          color: '#7099e6',
293          registeredOnly: true,
294          params: [{
295              name: 'url',
296              type: status.types.TEXT,
297              suggestions: faucetSuggestions,
298              placeholder: I18n.t('faucet_placeholder')
299          }],
300  
301  If you define a `text` input, when the user responds, it will pop up a
302  normal QWERTY keyboard. The example provided shows the first part of the
303  `status.commnad()` we use to interact with our faucet so that our users
304  can get some (test) ether to do interesting things with.
305  
306  ##### status.types.NUMBER
307  
308      status.response({
309          name: 'confirmation-code',
310          color: '#7099e6',
311          description: I18n.t('confirm_description'),
312          sequentialParams: true,
313          params: [{
314              name: 'code',
315              type: status.types.NUMBER
316          }],
317  
318  Defining `number` will result in the keyboard opening to it's number
319  section. The example provided shows the first part of the
320  `status.response()` object we use to request a confirmation code from
321  the user when syncing their phone contacts.
322  
323  ##### status.types.PHONE
324  
325      var phoneConfig = {
326          name: 'phone',
327          registeredOnly: true,
328          icon: 'phone_white',
329          color: '#5bb2a2',
330          title: I18n.t('phone_title'),
331          description: I18n.t('phone_description'),
332          sequentialParams: true,
333          validator: function (params) {
334              return {
335                  validationHandler: 'phone',
336                  parameters: [params.phone]
337              };
338          },
339          params: [{
340              name: 'phone',
341              type: status.types.PHONE,
342              suggestions: phoneSuggestions,
343              placeholder: I18n.t('phone_placeholder')
344          }]
345      };
346  
347  Defining `phone` will result in the keyboard opening to it's number
348  section as well. One example should suffice to give you a general idea
349  of how this works, so we have provided an excerpt of how we do phone
350  cofirmation using the `PHONE` type. You can find the full code
351  [here](https://github.com/status-im/status-react/blob/develop/resources/js/bots/console/bot.js#L456)
352  
353  ##### status.types.PASSWORD
354  
355      status.response({
356          name: 'password',
357          color: '#7099e6',
358          description: I18n.t('password_description'),
359          icon: 'lock_white',
360          sequentialParams: true,
361          params: [
362              {
363                  name: 'password',
364                  type: status.types.PASSWORD,
365                  placeholder: I18n.t('password_placeholder'),
366                  hidden: true
367              },
368              {
369                  name: 'password-confirmation',
370                  type: status.types.PASSWORD,
371                  placeholder: I18n.t('password_placeholder2'),
372                  hidden: true
373              }
374          ]
375      });
376  
377  Defining `password` will result in the keyboard opening to it's variable
378  character section. The example provided shows the first part of the
379  `status.response()` object we use to request and confirm a password from
380  our user when they are setting up their account.
381  
382  #### status.events
383  
384      events: {
385          SET_VALUE: 'set-value',
386          SET_COMMAND_ARGUMENT: 'set-command-argument'
387      }
388  
389  Events are essentially the glue that allow you to commuicate with the
390  Status API effectively.
391  
392  ##### status.events.SET_VALUE
393  
394      {onPress: status.components.dispatch([
395          status.events.SET_VALUE,
396          entry
397      ])},
398  
399  This method will completely update the content of text input. The full
400  function around the snippet example provided can be found
401  [here](https://github.com/status-im/status-react/blob/30596f743f0a6ac0b7aec575cc1483dd306cc1ef/bots/console/bot.js#L560).
402  
403  ##### status.events.SET_COMMAND_ARGUMENT
404  
405      {onPress: status.components.dispatch([
406          status.events.SET_COMMAND_ARGUMENT,
407          [0, entry.url]
408      ])},
409  
410  As opposed to `SET_VALUE`, this event will only update a single argument
411  which you define. The full function around the snippet example provided
412  can be found
413  [here](https://github.com/status-im/status-react/blob/30596f743f0a6ac0b7aec575cc1483dd306cc1ef/bots/console/bot.js#L485).
414  
415  #### status.components
416  
417  Create React Native Components yourself or use our pre-fabricated
418  components.
419  
420  ##### status.components.view
421  
422      function faucetSuggestions(params) {
423          var suggestions = faucets.map(function (entry) {
424              return status.components.touchable(
425                  {onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry.url]])},
426                  status.components.view(
427                      suggestionContainerStyle,
428                      [status.components.view(
429                          suggestionSubContainerStyle,
430                          [
431                              status.components.text(
432                                  {style: valueStyle},
433                                  entry.name
434                              ),
435                              status.components.text(
436                                  {style: descriptionStyle},
437                                  entry.url
438                              )
439                          ]
440                      )]
441                  )
442              );
443          });
444  
445  Standard RN component - please see
446  [JSCoach](https://js.coach/react-native) for more.
447  
448  Expects 2 arguments - `options` and `element`.
449  
450  The example provided shows how we use the `view` component (in
451  combination with the `text` component) to provide different suggestions
452  about which faucets our users can call to get some test ether.
453  
454  ##### status.components.text
455  
456  Standard RN component - please see
457  [JSCoach](https://js.coach/react-native) for more.
458  
459  Expects 2 arguments - `options` and some array of strings `s`.
460  
461  ##### status.components.slider
462  
463  Standard RN component - please see
464  [JSCoach](https://js.coach/react-native) for more.
465  
466  Expects only one argument - `options`.
467  
468  Please see the `defineSubscription` method below for an example of this
469  component in action.
470  
471  ##### status.components.image
472  
473  Standard RN component - please see
474  [JSCoach](https://js.coach/react-native) for more.
475  
476  Expects only one argument - `options`.
477  
478  ##### status.components.touchable
479  
480      function jsSuggestions(params, context) {
481          var suggestions = getJsSuggestions(params.code, context);
482          var sugestionsMarkup = [];
483  
484          for (var i = 0; i < suggestions.length; i++) {
485              var suggestion = suggestions[i];
486  
487              if (suggestion.title.indexOf('*') >= 0) {
488                  suggestion.title = createMarkupText(suggestion.title);
489              }
490              var suggestionMarkup = status.components.view(jsSuggestionContainerStyle,
491                  [status.components.view(jsSubContainerStyle,
492                      [
493                          status.components.text({style: jsValueStyle},
494                              suggestion.title),
495                          status.components.text({style: jsDescriptionStyle},
496                              suggestion.desc)
497                      ])]);
498              if (suggestion.pressValue) {
499                  suggestionMarkup = status.components.touchable({
500                          onPress: status.components.dispatch([status.events.SET_VALUE, suggestion.pressValue])
501                      },
502                      suggestionMarkup
503                  );
504              }
505              sugestionsMarkup.push(suggestionMarkup);
506          }
507  
508          if (sugestionsMarkup.length > 0) {
509              var view = status.components.scrollView(jsSuggestionsContainerStyle(sugestionsMarkup.length),
510                  sugestionsMarkup
511              );
512              return {markup: view};
513          }
514      }
515  
516  Standard RN component - please see
517  [JSCoach](https://js.coach/react-native) for more.
518  
519  Expects 2 arguments - `options` and `element`.\]
520  
521  The example provided uses the `touchable` component to make our
522  suggestions that much more native and-feeling and interactive.
523  
524  It's worth noting that `touchable` components can only wrap `view`
525  components, so any touchable text for example needs to first be wrapped
526  in a `view`.
527  
528  ##### status.components.scrollView
529  
530      var view = status.components.scrollView(
531          suggestionsContainerStyle(ph.length),
532          suggestions
533      );
534  
535      return {markup: view};
536  
537  Standard RN component - please see
538  [JSCoach](https://js.coach/react-native) for more.
539  
540  Expects 2 arguments - `options` and `elements`.
541  
542  In the code snippet provided, we have taken the suggestions from the
543  example above to do `components.view` and now want to inject it into a
544  scrollView component for a better and smoother UI that our users have
545  more control over.
546  
547  ##### status.components.webView
548  
549  Standard RN component - please see
550  \[JSCoach\](https://js.coach/react-native) for more. Expects only 1
551  argument - \`url\` and is what we use to display - as expected - the
552  webView of a given DApp when browsing to it.
553  
554  ##### status.components.validationMessage
555  
556  An example of using `validationMessage` within the validator argument
557  being passed to status.command.
558  
559      validator: function (params, context) {
560          var f = faucets.map(function (entry) {
561              return entry.url;
562          });
563  
564          if (f.indexOf(params.url) == -1) {
565              var error = status.components.validationMessage(
566                  I18n.t('faucet_incorrect_title'),
567                  I18n.t('faucet_incorrect_description')
568              );
569  
570              return {markup: error};
571          }
572      }
573  
574  This is the only custom Status component and it takes just two strings,
575  and will return them wrapped in text components inside a view. You can
576  find the full example
577  [here](https://github.com/status-im/status-react/blob/develop/resources/js/bots/console/bot.js#L566).
578  
579  ##### status.components.bridgedWebview
580  
581  Standard RN component - please see
582  [JSCoach](https://js.coach/react-native) for more.
583  
584  Expects only 1 argument - `url`.
585  
586  ##### status.components.subscribe
587  
588  A method that allows you to add a subscription in the markup.
589  
590  Expects only 1 argument - `path`. The added subscription will get the
591  value from the bot-db using your specified path.
592  
593  ##### status.components.dispatch
594  
595      var view = [
596          'view',
597          {},
598          ['text', {}, 'Balance ' + balance + ' ETH'],
599          ['text', {}, ['subscribe', ['doubledValue']]],
600          ['slider', {
601              maximumValue: ['subscribe', ['balance']],
602              value: defaultSliderValue,
603              minimumValue: 0,
604              onSlidingComplete: ['dispatch', ['set', 'sliderValue']],
605              step: 0.05
606          }],
607          ['touchable',
608              {onPress: ['dispatch', ['set-value-from-db', 'roundedValue']]},
609              ['view', {}, ['text', {}, 'Set value']]
610          ],
611          ['text', {style: {color: 'red'}}, ['subscribe', ['validationText']]]
612      ];
613  
614  A method that allows you to specify an event that will be dispatched on
615  some other event that occurs inside the markup (like pressing button,
616  text change etc.). By 'markup', we mean - essentially - the view, or the
617  mobile equivalent of the DOM.
618  
619  In the example provided, the variable `view` is what we mean by markup
620  (and is, in this case, part of our `superSuggestion` function found
621  [here](https://github.com/status-im/status-react/blob/2862af86c960b481ddf64ec1713e14908a366616/bots/demo_bot/bot.js#L31))
622  we specify that `["set", "sliderValue"]` will be dispatched on
623  `onSlidingComplete`. We can’t allow user to write a real js handler
624  here, so this is our workaround for now.
625  
626  #### status.setSuggestions
627  
628  A method that allows you to set the suggestions that will appear in the
629  markup, whether this is something simple like sending a message, or
630  pretty much anything
631  
632  #### status.setDefaultDb and status.updateDb
633  
634      function superSuggestion(params, context) {
635          var balance = parseFloat(web3.fromWei(web3.eth.getBalance(context.from), 'ether'));
636          var defaultSliderValue = balance / 2;
637  
638          var view = ['view', {},
639              ['text', {}, 'Balance ' + balance + ' ETH'],
640              ['text', {}, ['subscribe', ['doubledValue']]],
641              ['slider', {
642                  maximumValue: ['subscribe', ['balance']],
643                  value: defaultSliderValue,
644                  minimumValue: 0,
645                  onSlidingComplete: ['dispatch', ['set', 'sliderValue']],
646                  step: 0.05
647              }],
648              ['touchable',
649                  {onPress: ['dispatch', ['set-value-from-db', 'roundedValue']]},
650                  ['view', {}, ['text', {}, 'Set value']]
651              ],
652              ['text', {style: {color: 'red'}}, ['subscribe', ['validationText']]]
653          ];
654  
655          status.setDefaultDb({
656              sliderValue: defaultSliderValue,
657              doubledValue: doubledValueLabel({value: defaultSliderValue})
658          });
659  
660          var validationText = ';
661  
662          if (isNaN(params.message)) {
663              validationText = 'That's not a float number!';
664          } else if (parseFloat(params.message) > balance) {
665              validationText =
666                  'Input value is too big!' +
667                  ' You have only ' + balance + ' ETH on your balance!';
668          }
669  
670          status.updateDb({
671              balance: balance,
672              validationText: validationText
673          });
674  
675          return {markup: view};
676      };
677  
678  It is easiest to show you an example of these two methods at work in our
679  \[<https://github.com/status-im/status-react/blob/2862af86c960b481ddf64ec1713e14908a366616/bots/demo_bot/bot.js#L31>)
680  demo-bot\] within a `superSuggestions` object we have created.
681  
682  `status.setDefaultDb` is a method that can be used to add default values
683  to bot-db. These values will be applied to app-db only when markup is
684  rendered the first time. For instance, on each change in command input
685  suggestions handler for particular command's parameter is called, and
686  this handler returns some markup. If markup wasn't changed between calls
687  values passed to `setDefaultDb` will not be applied to bot-db
688  
689  `status.updateDb` is a method that updates the bot-db, even if the
690  markup doesn't contain any changes. It too expects just 1 argument -
691  `map`
692  
693  #### status.sendMessage
694  
695  This has just been implemented in the latest nightlies\! Go and grab one
696  of those and you'll have access to this route, as demonstrated by our
697  updated [demo
698  bot](https://github.com/status-im/status-react/blob/master/bots/demo_bot/bot.js#L77).
699  The snippet provided also reveals how to work with the javascript
700  concept of `localStorage`.
701  
702      status.addListener('on-message-send', function (params, context) {
703          var cnt = localStorage.getItem('cnt');
704          if(!cnt) {
705              cnt = 0;
706          }
707  
708          cnt++;
709  
710          localStorage.setItem('cnt', cnt);
711          if (isNaN(params.message)) {
712              return {'text-message': 'Seems that you don't want to send money :(. cnt = ' + cnt};
713          }
714  
715          var balance = web3.eth.getBalance(context.from);
716          var value = parseFloat(params.message);
717          var weiValue = web3.toWei(value, 'ether');
718          if (bn(weiValue).greaterThan(bn(balance))) {
719              return {'text-message': 'No way man, you don't have enough money! :)'};
720          }
721          web3.eth.sendTransaction({
722              from: context.from,
723              to: context.from,
724              value: weiValue
725          }, function (error, hash) {
726              if (error) {
727                  status.sendMessage('Something went wrong, try again :(');
728                  status.showSuggestions(demoSuggestions(params, context).markup);
729              } else {
730                  status.sendMessage('You are the hero, you sent ' + value + ' ETH to yourself!')
731              }
732          });
733      });
734  
735  #### status.defineSubscription
736  
737      function round(n) {
738          return Math.round(n * 100) / 100;
739      }
740  
741      function doubledValueLabel(params) {
742          var value = round(params.value);
743          return 'sliderValue = ' + value + '; (2 * sliderValue) = ' + (2 * value);
744      }
745  
746      status.defineSubscription(
747          // the name of subscription and the name of the value in bot-db
748          // associated with this subscription
749          'doubledValue',
750          // the map of values on which subscription depends: keys are arbitrary names
751          // and values are db paths to another value
752          {value: ['sliderValue']},
753          // the function which will be called as reaction on changes of values above,
754          // should be pure. Returned result will be associated with subscription in bot-db
755          doubledValueLabel
756      );
757  
758      status.defineSubscription(
759          'roundedValue',
760          {value: ['sliderValue']},
761          function (params) {
762              return round(params.value);
763          }
764      );
765  
766  This method was added to allow a bot to react on changes in the bot-db
767  and add another calculated value to that bot-db in the result.
768  
769  It expects 3 arguments: the name of subscription, a map of values on
770  which the subscription depends, and a callback function.