0.0.4 • Published 2 years ago

@giry/mangrove.js v0.0.4

Weekly downloads
-
License
(BSD-2-Clause OR ...
Repository
github
Last release
2 years ago

mangrove.js

A JavaScript library for Mangrove. Wraps around Ethers.js. Works in the web browser and Node.js.

This SDK is in open beta, and is constantly under development. USE AT YOUR OWN RISK.

Install / Import

Web Browser

  • TODO Push to npm once ready
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/..."></script>

<script type="text/javascript">
  window.Mangrove; // or `Mangrove`
</script>

Node.js

npm install ...
const { Mangrove } = require("...");

// or, when using ES6

import { Mangrove } from "...";

Usage

const main = async () => {
  const mgv = await Mangrove.connect("maticmum"); // Mumbai testnet

  // Connect to ETHUSDC market
  const market = mgv.market({ base: "ETH", quote: "USDC" });

  // Buy ETH with USDC
  market.buy({ volume: 2.1, price: 3700 });
  market.sell({ volume: 1.1, price: 3750 });

  // Read orderbook
  market.book();
  /*
    Returns
    {
      asks: [
        {id: 3, price: 3700, volume: 4, ...},
        {id: 56, price: 3701, volume: 7.12, ...}
      ],
      bids: [
        {id: 811, price: 3600, volume: 1.23, ...},
        {id: 80, price: 3550, volume: 1.11, ...}
      ]
    }
  */

  // Subscribe to orderbook
  market.subscribe((event, utils) => {
    /* `event` is an offer write, failure, success, or cancel */
    console.log(utils.book());
    /* Prints the updated book, same format as `market.book()` */
  });
};

main().catch(console.error);

Using as a maker

For now the only available maker is SimpleMaker. This maker has its own provisions and no internal logic. You can amplify your liquidity by posting more offers than your available liquidity.

const { Mangrove, SimpleMaker } = require("mangrove.js");
const mgv = await Mangrove.connect("maticmum"); // Mumbai testnet

// deploy a new maker
const mkr_address = await SimpleMaker.deploy(mgv);

// SimpleMaker contracts are token-agnostic, but you must instantiate the js object
// focused on a specific base/quote pair.
const mkr = await mgv.simpleMakerConnect({
  address: mkr_address,
  base: "WETH",
  quote: "USDC",
});

// note that mkr.market is a Market object with all the taker functions available

// approve mangrove for transfers
mkr.approveMangrove("WETH", 10000);
mkr.approveMangrove("USDC", 1000000000000000);

// read current allowance
const allowance = await mkr.mangroveAllowance("USDC");
// you could also do
const allowance2 = mgv
  .token("USDC")
  .allowance({ owner: mkr.address, spender: mgv.address });

// fund maker contract (bot must have ethers)
await mkr.fund(12);

// check current balance of maker at Mangrove
let balance = await mgv.balanceOf(mkr.address);

// withdraw maker's balance to the signer's address
mkr.withdraw(4);

// post a new offer giving weth against usdc
// you can give gives/wants or price/volume
// id:number is the new offer id
// event:ethers.Event is the ethers.js event that created the offer
const { id: askId, event } = await mkr.newAsk({ wants: 3500, gives: 1 });

// post a new offer giving usdc against weth
const { id: bidId, event } = await mkr.newBid({ price: 3400, volume: 2 });

const asks /*:Offer[]*/ = await mkr.asks();
const bids /*:Offer[]*/ = await mkr.bids();

// Update an existing ask.
// You can update gives/wants or price/volume. Other parameters will not change.

const promise = mkr.updateAsk(askId, { wants: 3600, gives: 1 });
promise.then((event) => console.log("offer updated", event));

// Cancel an existing bid.
mkr.cancelBid(bidId);

More Code Examples

See the docblock comments above each function definition or the official mangrove.js Documentation.

  • TODO put documentation online

Instance Creation

The following are valid Ethereum providers for initialization of the SDK.

mgv = await Mangrove.connect(window.ethereum); // web browser

mgv = await Mangrove.connect('http://127.0.0.1:8545'); // HTTP provider

mgv = await Mangrove.connect(); // Uses Ethers.js fallback mainnet (for testing only)

mgv = await Mangrove.connect('rinkeby'); // Uses Ethers.js fallback (for testing only)

// Init with private key (server side)
mgv = await Mangrove.connect('https://mainnet.infura.io/v3/_your_project_id_', {
  privateKey: '0x_your_private_key_', // preferably with environment variable
});

// Init with HD mnemonic (server side)
mgv = await Mangrove.connect('mainnet' {
  mnemonic: 'clutch captain shoe...', // preferably with environment variable
});

Constants and Contract Addresses

Names of contracts, their addresses and token decimals can be found in /src/constants.ts. ABIs and typechain-generated types are in types/typechain/. Addresses, for all networks, can be easily fetched using the getAddress function, combined with contract name constants.

cUsdtAddress = Mangrove.getAddress("USDC");
// Mainnet USDC address. Second parameter can be a network like 'rinkeby'.

Numbers

Numbers returned by functions are either plain js numbers or big.js instances. Some functions with names ending in Raw may return ether.js's BigNumbers.

As input, numbers can be as plain js numbers, big.js instances, but also strings.

The precision used when dividing is 20 decimal places.

Transaction Options

TODO include transaction options (see here)https://github.com/compound-finance/compound-js#transaction-options

Test

Tests are available in ./test/integration/*.integration.test.js. Methods are tested using an in-process local chain using Hardhat. For free archive node access, get a provider URL from Alchemy.

## Run all tests
yarn test

## Run a single test (Mocha JS grep option)
yarn test -- -g 'subscribes'

Test configuration and root hooks

Tests are based on Mocha. Mocha configuration can be found in ./test/mocha/config.

The integration tests use the Root Hooks provided by @giry/hardhat-utils which start an in-process Hardhat chain with Mangrove deployed and add a matching Provider to the Mocha Context.

Utility test scripts

Scripts to ease testing of your Mangrove.js-based dApp can be found in ./test/scripts/.

obFiller.js : Order book filler

The obFiller.js script runs a local Hardhat chain where offers are continously added/removed.

The script helpfully prints mnemonic and addresses that you can copy to MetaMask and your dApp:

$ ts-node test/scripts/obFiller.js
Mnemonic:
test test test test test test test test test test test junk

RPC node
http://localhost:8546

User/admin
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

WETH (18 decimals)
0xDB6BDf95fDb367F2c983167C0f1Ec4a8913694a5

DAI (18 decimals)
0xE77A0C6E103fB655AAA2F31b892deF9Cf0909158

USDC (6 decimals)
0x5d268aEd192e6C55a950ccd65Fe209A13F0e338f

Orderbook filler is now running.

Build for Node.js & Web Browser

$ git clone ...
$ cd <Mangrove clone>
$ yarn install              # <- Only required after initial clone, afterwards 'yarn build' is sufficient
$ cd packages/mangrove.js
$ yarn build

The build artifacts will be placed in ./dist/nodejs and ./dist/browser.