Subspace 1.0.0
Subspace is a framework agnostic JS library that embraces reactive programming with RxJS, by observing asynchronous changes in Smart Contracts, and providing methods to track and subscribe to events, changes to the state of contracts and address balances, and react to these changes and events via observables.
Subspace also takes care of syncing under the hood, saving & loading the state in a local database.
Instalation
npm install --save @status-im/subspace
Usage
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 "@status-im/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)
});
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));
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)
});
React Integration Example
note: Subspace is framework agnostic and can integrate with ANY framework.
Subspace can make any react component compatible with observables so you easily reactive components
import { observe } from "@status-im/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')
);