npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@openst/mosaic.js

v0.10.0

Published

mosaic.js provides a JS abstraction layer to interact with contracts on mosaic chains.

Downloads

14

Readme

💠 mosaic.js

Build master Build develop npm version Discuss on Discourse Chat on Gitter

Mosaic is a parallelization schema for decentralized applications. It composes heterogeneous blockchain systems into one another. Decentralized applications can use Mosaic to compute over a composed network of multiple blockchain systems in parallel.

Mosaic enables building scalable blockchain token economies through the bidirectional transposition of ERC20 tokens on one blockchain, the origin chain, and a utility token representation on another blockchain, the auxiliary chain.

The protocol defines a set of actions that together perform atomic token transfers across two blockchains using gateway contracts. A gateway for a given EIP20 token is comprised of a EIP20Gateway contract on origin, a corresponding EIP20CoGateway contract on auxiliary, and an EIP20 utility token contract on auxiliary that mints and burns utility tokens to atomically mirror tokens staked and unstaked on the origin chain.

Atomicity is achieved using a 2-phase message passing architecture between the chains. Messages are declared on the source chain, and confirmed on the target chain with Merkle Patricia proofs once the source chain is finalized. Once messages are confirmed on the target chain, they can efficiently progressed with a hashlock. Messages can also be reverted if they are not yet completed on the target chain.

⚠️ Reverting is not yet supported in mosaic.js and will be supported in a future version. In the meantime you can revert by accessing the contracts directly.

You can read the draft of the mosaic whitepaper or the original OpenST whitepaper.

Instructions

Installation

npm install @openst/mosaic.js web3 web3-eth-accounts

ℹ️ Note that web3 and web3-eth-accounts are peer-dependencies.

Usage

Mosaic

const Web3 = require('web3');
const Mosaic = require('@openst/mosaic.js');

const originWeb3 = new Web3('http://localhost:8546');
const auxiliaryWeb3 = new Web3('http://localhost:8547');

const originContractAddresses = {
  EIP20Gateway: '0x0000000000000eip20gatewaycontractaddress',
  ...,
};
const auxiliaryContractAddresses = {
  EIP20CoGateway: '0x00000000000eip20cogatewaycontractaddress',
  ...,
};

const originChain = new Mosaic.Chain(originWeb3, originContractAddresses);
const auxiliaryChain = new Mosaic.Chain(auxiliaryWeb3, auxiliaryContractAddresses);

const mosaic = new Mosaic(originChain, auxiliaryChain);

Facilitator

Creating a new facilitator:

const facilitator = new Mosaic.Facilitator(mosaic);

Staking:

const staker = '0x00000000000000000000stakeraccountaddress';
const amount = '1000000000000';
const beneficiary = '0x000000000000000beneficiaryaccountaddress';
const gasPrice = '5';
const gasLimit = '150000000';
const hashLock = '0x00000000000000000000000000000000000000000000000000000000hashlock';
const txOptions = { from: staker };

facilitator
  .stake(
    staker,
    amount,
    beneficiary,
    gasPrice,
    gasLimit,
    hashLock,
    txOptions,
  )
  .then(console.log)
  .catch(console.log);

Progressing the stake after the state root has been transferred:

const unlockSecret = '0x0000000000000000000000000000000000000000000000000000unlocksecret';
const txOptionOrigin = { from: '0x0000000000000000originfacilitatoraddress' };
const txOptionAuxiliary = { from: '0x0000000000000auxiliaryfacilitatoraddress' };

facilitator
  .progressStake(
    staker,
    amount,
    beneficiary,
    gasPrice,
    gasLimit,
    nonce,
    hashLock,
    unlockSecret,
    txOptionOrigin,
    txOptionAuxiliary,
  )
  .then(console.log)
  .catch(console.log);

Redeeming:

const redeemer = '0x0000000000000000000000000redeemeraddress';
const redeemAmount = '1000000000000';
const beneficiary = '0x000000000000000beneficiaryaccountaddress';
const gasPrice = '4';
const gasLimit = '150000000';
const hashLock = '00000000000000000000000000000000000000000000000000000000hashlock';
const txOptionRedeem = {
  from: redeemer,
  value: '100', // This must be equal to the bounty amount!
};

facilitator
  .redeem(
    redeemer,
    redeemAmount,
    beneficiary,
    gasPrice,
    gasLimit,
    hashLock,
    txOptionRedeem,
  )
  .then(console.log)
  .catch(console.log);

Progressing the redemption after the state root has been transferred:

const unlockSecret = '0x0000000000000000000000000000000000000000000000000000unlocksecret';
const txOptionOriginRedeem = { from: '0x000000000facilitatoraddressonoriginchain' };
const txOptionAuxiliaryRedeem = { from: '0x000000facilitatoraddressonauxiliarychain' };

facilitator
  .progressRedeem(
    redeemer,
    nonce,
    beneficiary,
    redeemAmount,
    gasPrice,
    gasLimit,
    hashLock,
    unlockSecret,
    txOptionOriginRedeem,
    txOptionAuxiliaryRedeem,
  )
  .then(console.log)
  .catch(console.log);

General Contract Interaction

EIP20Gateway example:

// Expecting Mosaic import and an instance of `mosaic`:
const {
  Anchor,
  EIP20CoGateway,
  EIP20Gateway,
  EIP20Token,
  OSTPrime,
} = Mosaic.Contracts;

// Afterwards, ou can call methods directly on the contract instance:
const eip20Gateway = new EIP20Gateway(
  mosaic.origin.web3,
  mosaic.origin.contractAddresses.EIP20Gateway,
);

const staker = '0x00000000000000000000stakeraccountaddress';

const amount = '1000000000000';
const beneficiary = '0x000000000000000beneficiaryaccountaddress';
const gasPrice = '5';
const gasLimit = '150000000';
const hashLock = '0x00000000000000000000000000000000000000000000000000000000hashlock';
const txOptions = { from: staker };

const nonce = await eip20Gateway.getNonce(staker);

eip20Gateway
  .stake(
    amount,
    beneficiary,
    gasPrice,
    gasLimit,
    nonce,
    hashLock,
    txOptions,
  )
  .then(console.log)
  .catch(console.log);

OSTPrime

On the auxiliary chain OST is the base token. The gas price on auxiliary is paid in OST (like Ether pays for gas on Ethereum mainnet). To obtain the base token, you need to stake OST on origin.

On auxiliary, the OSTPrime contract will convert the EIP20 token to base tokens for the beneficiary.

Create an OSTPrime object:

const ostPrime = new Mosaic.ContractInteract.OSTPrime(
  mosaic.auxiliary.web3,
  mosaic.auxiliary.contractAddresses.OSTPrime,
);

Wrap:

const amountToWrap = '1000';
const fromAddress = '0x00000000000000000000000000000fromaddress';
let txOptions = {
  value: amountToWrap,
  from: fromAddress,
};

ostPrime
  .wrap(txOptions)
  .then(console.log)
  .catch(console.log);

Unwrap:

const amountToUnwrap = '1000';
txOptions = {
  from: fromAddress,
};

ostPrime
  .unwrap(amountToUnwrap, txOptions)
  .then(console.log)
  .catch(console.log);

Related Work

mosaic-contracts provides the EVM smart contracts implementations. You can use mosaic-contracts directly to deploy a new mosaic chain.

Contributing

Set-up

git clone [email protected]:openst/mosaic.js.git
cd mosaic.js
npm install
npm run test

# Requires docker:
npm run test:integration

Guidelines

There are multiple ways to contribute to this project. However, before contributing, please first review the Code of Conduct.

We track our issues on GitHub.

To contribute code, please ensure that your submissions adhere to the Style Guide; please also be aware that this project is under active development and we have not yet established firm contribution guidelines or acceptance criteria.

Community