loomnetwork/loom-js

Move to ethers.js in Plasma Cash bindings

gakonst opened this issue · 0 comments

Currently, the Plasma Cash bindings are all using web3.js for interacting with mainnet. We should move to Ethers.js which has strictly better APIs for monitoring events, as well as creating transactions offline. This also allows us to have both offline tx signing and metamask in a very intuitive way.

This will be implemented by wrapping the createUser function from the metamask branch as follows:

User.newMetamaskUser(<same args as createUser without web3>) {
  const provider = new ethers.providers.Web3Provider(web3.currentProvider);
  const wallet = provider.getSigner();
  return User.createUser(wallet, ...args)
}

The above will create a net User instance which is instantiated to work with metamask.

The offline user will be done with:

User.newOfflineUser(privateKey, endpoint, <same args as createUser without web3>) {
  const privateKey = <yourpk>
  const provider = new ethers.providers.JsonRpcProvider(endpoint)
  const wallet = new ethers.Wallet(privateKey, provider);
  return User.createUser(wallet, ...args)
}

This will require changing the Entity class to accept a ethers.js Signer object instead of web3, as well as any necessary API changes to the contracts for calling methods and listening to events.


Below I am adding some example usages of ethers.js, along with docs:
https://docs.ethers.io/ethers.js/html/cookbook.html?highlight=cookbook

Connecting with a Privatekey:

var ethers = require('ethers');

var privateKey = <yourpk>
var provider = ethers.providers.getDefaultProvider('rinkeby');
var wallet = new ethers.Wallet(privateKey, provider);

var address  = <contractaddress>
var abi = <yourabi>

var contract = new ethers.Contract(address,abi,wallet);

await contract.someFunction(<args>)

Connecting to metamask:

var ethers = require('ethers');
const provider = new ethers.providers.Web3Provider(web3.currentProvider);
const wallet = provider.getSigner();

var address  = <contractaddress>
var abi = <yourabi>

var contract = new ethers.Contract(address,abi,wallet);

Sending ETH

 let tx = await wallet.sendTransaction({
        gasLimit: gasLimit,
        gasPrice: gasPrice,
        to: newAddress,
        value: value
    });
    let receipt = await tx.wait()

Sending ETH along a function

let tx = contract.someFunction(addr, { value: utils.parseEther('1.0') })
let receipt = await tx.wait()

Watching / Listening for Events

Listening for all occurences of an event

contract.on("ValueChanged", (author, oldValue, newValue, event) => {
    // Called whenever ValueChanged is emitted. The callback arguments are the event params.
    console.log(author);
    // "0x14791697260E4c9A71f18484C9f997B308e59325"
    console.log(oldValue);
    // "Hello World"
    console.log(newValue);
    // "Ilike turtles."
    // See Event Emitter below for all properties on Event
    console.log(event.blockNumber);
    // 4115004
});

Filtering

// The null field indicates any value matches
// This will filter all Transfer events where the second argument is myAddress.
let filter = contract.Transfer(null, myAddress);

// Listen for our filtered results
contract.on(filter, (from, to, value) => {
    console.log('I received ' + value.toString() + ' tokens from ' + from);
});