Skip to main content

Quick Start

Let's get started writing a quick cross-chain JavaScript app with Cubist! The app we're going to build exposes a number stored across two different chains. The app's smart contracts look like standard Solidity code, but we're going to use Cubist to automatically deploy and use them cross-chain.


The following instructions assume that you have installed Cubist.


If you're interested in a more detailed explanation of what's going on, check out the advanced examples---including a more detailed walkthrough of this app.

Clone the example repo

We're going to be using the JavaScript version of the Storage example.

git clone [email protected]:cubist-labs/cubist-sdk-templates.git
cd cubist-sdk-templates/Storage/JavaScript

Install app dependencies

Let's start by installing the Cubist Node.js SDK and related dependencies. From the Storage application directory, with npm or yarn:

npm install

Build the app

This app consists of two contracts: StorageSender stores a number and then calls to store the number to the StorageReceiver contract, too. The twist is that StorageSender and StorageReceiver are deployed on different chains---even though they look like they're on the same chain.

The cubist-config.json specifies the chain on which each contract should run; in this example, the StorageReceiver contract runs on Ethereum and the StorageSender contract runs on Polygon. If you want to change chains, simply edit the configuration file.

Now that we know where each contract should run, let's build the project with Cubist:

cubist build

This command tells Cubist to (1) generate "shim" contracts that expose StorageReceiver to (in this case) Polygon, (2) compile both the normal contracts and the shim contracts, and (3) generate ORM interfaces (i.e., JavaScript types for the contracts).

Start Cubist chains and relayer

In order to actually run the app, we need to start the local chains and the Cubist relayer. To start both the chains and the relayer, run:

cubist start

This may take a minute when you first run it, because Cubist needs to download and build the local chain running services.

Running relayer in the foreground

The cubist start command runs services in the background, but doesn't hide the relayer output since it's useful for debugging. If you don't want the output of the relayer interspersed with your app output, you can run this command in a separate terminal. You can also run the command in the foreground with the --mode=foreground flag.

Deploy the contracts

Let's deploy the contracts (and the generated shims):

npm run deploy 17

This calls the app's deploy script, which uses Cubist-generated functions to deploy each smart contract to its respective chain. Note in the output listing above that a bridge was created for the newly deployed StorageReceiver contract; the deploy script didn't do that, the Cubist relayer did!

Interact with the contracts from JavaScript

Now that we've deployed the contracts, we can increment and decrement the stored value, as well as storing a completely new value or retrieving the current value. For example, to increment the value:

npm run inc 5

Again, note the output from the relayer indicating that a call to StorageReceiver::store on Polygon was automatically relayed to Ethereum (the StorageSender::inc method calls StorageSender::store, which then calls (cross-chain) StorageReceiver::store).

dec, inc, store, and retrieve all work similarly; run these commands to update the value to your heart's content. For example:

npm run retrieve

Shut down background processes

Running cubist stop will shut down both the chains and the relayer. Once the chains and the relayer are shut down, trying to call contract functions from within the app will cause errors.