hero

Reactive ÐApp Development

Get Started

Automatic Syncing

Subspace takes care of syncing under the hood, syncing exactly what you need when you need it. It saves the state to a local database ensuring the DApp always syncs from the last known point even after reloading the DApp.

Reactive

Subspace embraces reactive programming with RxJS. It provides methods to track and subscribe to events, contract state & balances, and react to changes via observables.

Framework Agnostic

Subspace is framework agnostic and integrates well with your favourite frameworks, from React to Angular. It works in the browser and in nodejs.


Event Tracking & Event Sourcing

You can track events and react to their values. With Subspace observables doing event sourcing is easy.
import { $average, $latest } from "@embarklabs/subspace";

const rating$ = Product.events.Rating.track().map("rating"));

rating$.pipe($latest(5), $average()).subscribe((rating) => {
  console.log("average rating of the last 5 events is " + rating)
});
  
1
2
3
4
5
6
7

Tracking State

You can track changes to a contract state variable, by specifying the view function and arguments to call and query the contract.
const productTitle$ = ProductList.methods.products(0).track().map("title");
productTitle$.subscribe((title) => console.log("product title is " + title));
  
1
2

Tracking balances

You can also track changes in both ETH and ERC20 token balances
const address = "0x0001020304050607080900010203040506070809";

subspace.trackBalance(address).subscribe((balance) => {
  console.log("ETH balance is ", balance)
});

subspace.trackBalance(address, "0x744d70fdbe2ba4cf95131626614a1763df805b9e").subscribe((balance) => {
  console.log("SNT balance is ", balance)
});

1
2
3
4
5
6
7
8
9

React Integration

Subspace can make any react component compatible with observables so you easily reactive components
import { observe } from "@embarklabs/subspace/react";

const ProductComponent = ({ maxRating, minRating, averageRating }) => {
  return <ul>
    <li><b>minimum rating: </b> {minRating}</li>
    <li><b>maximum rating: </b> {maxRating}</li>
    <li><b>average rating: </b> {averageRating}</li>
  </ul>;
};

const ReactiveProductComponent = observe(ProductComponent);
const Product = subspace.contract({abi, address});
const rating$ = Product.events.Rating.track().map("rating").pipe(map(x => parseInt(x)));

ReactDOM.render(
  <ReactiveProductComponent
    maxRating={rating$.pipe($max())}
    minRating={rating$.pipe($min())}
    averageRating={rating$.pipe($average())}
  />,
  document.getElementById('hello-example')
);
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23