2019-09-03 14:40:19 -04:00
# Getting Started
## Installation
2019-09-27 15:24:05 -04:00
**Subspace** can be used in browser, node and native script environments. To get started install the package `@status-im/subspace` using `npm` or `yarn` by executing this command in your project directory:
2019-09-03 14:40:19 -04:00
```bash
# Using npm
2019-09-27 15:24:05 -04:00
npm install --save @status -im/subspace
2019-09-03 14:40:19 -04:00
# Using yarn
2019-09-27 15:24:05 -04:00
yarn add @status -im/subspace
2019-09-03 14:40:19 -04:00
```
## Importing the library
```js
// ESM (might require babel / browserify)
2019-09-27 15:24:05 -04:00
import Subspace from '@status -im/subspace';
2019-09-03 14:40:19 -04:00
// CommonJS
2019-09-27 15:24:05 -04:00
const Subspace = require('@status -im/subspace');
2019-09-03 14:40:19 -04:00
```
## Connecting to a web3 provider
2019-09-11 10:07:10 -04:00
To interact with the EVM, **Subspace** requires a valid websockets Web3 provider.
2019-09-03 14:40:19 -04:00
```js
2019-09-27 15:24:05 -04:00
const subspace = new Subspace(web3.currentProvider);
await subspace.init();
2019-09-03 14:40:19 -04:00
```
2019-09-11 10:07:10 -04:00
In addition to the provider, `Subspace` also accepts an `options` object with settings that can change its behavior:
- `dbFilename` - Name of the database where the information will be stored (default `'subspace.db'` )
2019-09-06 09:28:26 -04:00
- `callInterval` - Interval of time in milliseconds to query a contract/address to determine changes in state or balance (default: `undefined` . Obtains data every block).
2019-09-03 14:40:19 -04:00
## Reacting to data
2019-09-11 10:07:10 -04:00
Once it's initialized, you can use **Subspace** 's methods to track the contract state, events and balances. These functions return RxJS Observables which you can subscribe to, and obtain and transform the observed data via operators.
2019-09-03 14:40:19 -04:00
2019-09-06 09:53:21 -04:00
::: tip What is an Observable?
The `Observable` type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. In addition, observables are:
- Compositional: Observables can be composed with higher-order combinators.
- Lazy: Observables do not start emitting data until an observer has subscribed.
:::
2019-09-03 14:40:19 -04:00
2019-09-09 19:49:35 -04:00
#### Further read
- [RxJS Observables ](https://rxjs-dev.firebaseapp.com/guide/observable )
2019-09-03 14:40:19 -04:00
### Tracking a contract's state
You can track changes to the contract state, by specifying the view function and arguments to call and query the contract.
```js
const contractObject = ...; // A web3.eth.Contract object initialized with an address and ABI.
const functionName = "..."; // string containing the name of the contract's constant/view function to track.
const functionArgs = []; // array containing the arguments of the function to track. Optional
const callOptions = {from: web3.eth.defaultAccount}; // Options used for calling. Only `from` , `gas` and `gasPrice` are accepted. Optional
2019-09-03 20:13:43 -04:00
2019-09-27 15:24:05 -04:00
const myObservable$ = subspace.trackProperty(contractObject, functionName, functionArgs, callOptions);
2019-09-03 14:40:19 -04:00
```
2019-09-06 09:28:26 -04:00
::: tip Tracking the public variables of a contract
State variables implicity create a `view` function when they're defined as `public` . The `functionName` would be the same as the variable name, and `functionArgs` would have a value when the type is a `mapping` or `array` (since these require an index value to query them).
:::
2019-09-03 14:40:19 -04:00
### Tracking contract events
You can track events and react to their returned values.
```js
const contractObject = ...; // A web3.eth.Contract object initialized with an address and ABI.
const eventName = "..."; // string containing the name of the event to track.
const options = { filter: { }, fromBlock: 1 }; // options used to query the events. Optional
2019-09-27 15:24:05 -04:00
const myEventObservable$ = subspace.trackEvent(contractObject, eventName, options)
2019-09-06 09:28:26 -04:00
2019-09-03 14:40:19 -04:00
```
### Tracking balances of addresses
2019-09-06 09:28:26 -04:00
You can also track changes in both ETH and ERC20 token balances for each mined block or time interval depending on the `callInterval` configured.
2019-09-03 14:40:19 -04:00
```js
// Tracking ETH balance
const address = "0x0001020304050607080900010203040506070809";
2019-09-27 15:24:05 -04:00
subspace
2019-09-03 14:40:19 -04:00
.trackBalance(address)
.subscribe((balance) => {
console.log("ETH balance is ", balance)
});
```
```js
// Tracking ERC20 balance
const address = "0x0001020304050607080900010203040506070809";
const tokenAddress = "0x744d70fdbe2ba4cf95131626614a1763df805b9e"; // SNT Address
2019-09-27 15:24:05 -04:00
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);
2019-09-03 14:40:19 -04:00
```
2019-09-06 09:53:21 -04:00
::: warning
2019-09-06 09:28:26 -04:00
Balances are returned as a string containing the value in *wei* .
:::
2019-09-03 14:40:19 -04:00
## Subscriptions
2019-09-06 09:28:26 -04:00
Once you have an `Observable` , you may receive a stream of data by creating a subscription.Subscriptions are triggered each time an observable emits a new value. These subscription receive a callback that must have a parameter which represents the value received from the observable (a contract state variable, an event, or the balance of an address); and they return an object representing the subscription.
2019-09-03 14:40:19 -04:00
Subscriptions can be disposed by executing the method `unsubscribe()` liberating the resource held by it:
```js
2019-09-27 15:24:05 -04:00
const myBalanceObservable$ = subspace.trackBalance(address, tokenAddress);
2019-09-06 09:28:26 -04:00
const subscription = myBalanceObservable$.subscribe(value => {
console.log("The balance is: ", value);
});
2019-09-03 14:40:19 -04:00
// ...
subscription.unsubscribe();
```
2019-09-06 09:28:26 -04:00
#### Further read
- [RxJS Subscriptions ](https://rxjs-dev.firebaseapp.com/guide/subscription )
2019-09-03 14:40:19 -04:00
2019-09-06 09:28:26 -04:00
## Cleanup
2019-09-11 10:07:10 -04:00
If **Subspace** is not needed anymore, you need can invoke `close()` to dispose and perform the cleanup necessary to remove the internal subscriptions and interval timers created by **Subspace** during its normal execution, thus avoiding any potential memory leak.
2019-09-09 19:49:35 -04:00
2019-09-03 14:40:19 -04:00
```
2019-09-27 15:24:05 -04:00
subspace.close();
2019-09-03 14:40:19 -04:00
```
2019-09-06 09:53:21 -04:00
::: warning What about subscriptions created with our observables?
2019-09-06 09:28:26 -04:00
Any subscription created via the tracking methods must be unsubscribed manually (in the current version).
:::
2019-09-03 14:40:19 -04:00