Skip to main content

SDK Overview

  • Numbers returned by functions are either plain JavaScript number or big.jsinstances. Some functions with names ending in Raw may returnethers.BigNumbers.
  • As input, numbers can be as plain JavaScript numbers, big.js instances, but also astring.

The precision used when dividing is 20 decimal places.


All API functions that produce a signed transaction can be equipped with the usual ethers.js overrides as optional parameters.


The root class of the API. Use Mangrove.connect to get an instance of it. Here are a few possibilities:

mgv = await Mangrove.connect(window.ethereum); // web browser
mgv = await Mangrove.connect(''); // 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(
'', // provider
privateKey: '0x_your_private_key_', // preferably with environment variable
// Init with HD mnemonic (server side)
mgv = await Mangrove.connect( {
signer: myEthersWallet

You can test you are indeed connected to the deployed Mangrove by asking for the current global configuration of Mangrove:

config = await mgv.config()

The above mgv object gives you access to the MgvToken, Market and OfferLogic (allowing one to connect to an on-chain offer logic) and LiquidityProvider(an abstraction layer to pass bids and asks on Mangrove) objects.


mgv.contractgives access to the standard ethers.js contract and allows one to interact with the deployed Mangrove using low-level ethers.js calls. Hence, await mgv.contract.f(...) will produce the ethers.js call to Mangrove (signed when needed by the signer provided to the connect function).


This class provides easy means to interact with a deployed contract on the standard EIP-20. To obtain an instance use:

mgvTkn = mgv.token("<tokenSymbol>"); // e.g "DAI", "WETH", "amDAI", etc.

with the above MgvT object one has access to standard calls using human readable input/outputs. For instance:

await mgvTkn.approve("<spender>"); // gives infinite approval to spender
await mgvTkn.approve("<spender>",0.5); // gives allowance to spend 0.5 token units to spender
await mgvTkn.contract.approve("<spender>", mgvTkn.mgv.toUnits(0.5)); // ethers.js call

Note that Mangrove's API deals with token decimals automatically (see definitions in constants.ts).


MgvToken.contract gives access to the ethers.js contract allowing one to interact with the deployed contract using low level calls (for instance if the token has functions that are do not belong to the ERC20 standard).


The Market class is an abstraction layer to interact with Mangrove as a liquidity taker, using standard market buy and sell orders. To obtain one instance use:

//connect to a (base,quote) market with default options
mgvMarket = await mgv.connect({base:"<base_symbol>", quote:"<quote_symbol>"});

// connect to the market, caching the first 50 best bids and asks
mgvMarket = await mgv.connect({base:"<base_symbol>", quote:"<quote_symbol>", maxOffers: 50});

Upon connection to a market, the API subscribes to events emanating from Mangrove in order to maintain a local cache of the order book. One may increase the size of the cache by using mgv.connect({..., maxOffers:<size of the book>}).

For debugging purpose, the class provides a console of the current state of bids and asks posted on Mangrove. For instance to display the bid offers on Mangrove on this market:

// Pretty prints to console the bid offers, showing offer `id`, offer `volume` and offer `price
await mgvMarket.consoleAsks(["id", "volume", "price"]);

Market instances allow one to subscribe to markets events using:

const f (event) => ...; // what you want to do when receiving the event 
mgvMarket.subscribe (f);

To unsubscribe f from market events simply use mgvMarket.unsubscribe(f).

Market events are records of the following kinds:

  • {type: 'OfferRetract', ba:'asks'|'bids', offer:Market.Offer} when an ask or a bid offer is removed from the book
  • {type: 'OfferWrite', ba:'asks'|'bids', offer:Market.Offer} when a bid or ask offer is added to the book (or updated)
  • {type:'OfferFail', ba:'asks'|'bids', taker:string, 'takerWants':Big, takerGives:Big, mgvData:string, offer:Market.Offer} when offer failed to deliver. Note that mgvData is a bytes32 string encoding of the fail reason (according to Mangrove).
  • {type: 'OfferSuccess', ba: 'asks'|'bids', taker: string, takerWants:Big, takerGives:Big, offer:Market.Offer} when offer was successfully executed (possibly on a partial fill whenever>takerWants).

and where Market.Offer has the following main fields:

id: number; // the id of the executed offer
maker: string; // address of the maker (contract/wallet) in charge of the offer
gasreq: number; // gas required by the offer
volume: Big; // total volume proposed
price: Big; // price offered


A reactive offer is managed by a smart contract which implements its logic. One may use the API to post liquidity on Mangrove via a deployed logic that complies to the IOfferLogic interface. To do so, one first need an OfferLogic instance:

const mgvLogic = mgv.offerLogic("0x..."); // NB not an async call

The mgvLogic instance offers various function to query and set the underlying contract state, for instance:

await mgvLogic.setAdmin("0x..."); // set new admin
await mgvLogic.redeemToken("DAI", 100); // transfer 100 DAI from contract's signer account to signer's EOA
await mgvLogic.depositToken("WETH", 0.1); // put 0.1 WETH from signer's EOA to contract's account
const bal = await mgvLogic.tokenBalance("USDC"); // returns signer's balance of USDC on the contract
const mgvLogic_ = await mgvLogic.connect(newSigner); // returns a new OfferLogic instance with a new signer
cosnt gasreq = await mgvLogic.getDefaultGasreq(); // returns the gas required (by default) for new offers of this contract
await mgvLogic.setDefaultGasreq(200000); // default gasreq setter

When using an offer logic that inherits from the MultiUser.sol solidity class, one should always use the above depositToken (and tokenBalance) instead of sending tokens (or querying balance) directly to the contract which might result in the tokens being burnt (as only depositToken will increase user balance on the contract).


A LiquidityProvider instance is the object one needs to post bids and asks on a Mangrove market. It can be used to post a direct offer or to post an offer relying on some on-chain logic.

To act as a direct liquidity provider on a mgvMarket you must obtain a LiquidityProvider instance from an mgv object using:

const mgvDirectLP = await mgv.liquidityProvider(mgvMarket);

The EOA providing the liquidity for ask and bid offers emanating from a direct liquidity provider is the address of the mgv's signer provided at the creation of Mangrove instance.

For more complete experience of Mangrove capabilities, on may rather post bids and asks via an offer logic mgvLogic. To do so, one does:

const mgvOnchainLP = await mgvLogic.liquidityProvider(mgvMarket);

Besides posting offers on Mangrove, a LiquidityProvider instance mgvLP gives access to various useful functions such as:

const missingAskProvision = await mgvLP.computeAskProvision();
const missingBidProvision = await mgvLP.computeBidProvision();

which return the missing provision (in native tokens) this liquidity provider needs to deposit on Mangrove if it wishes to post a new bid or ask. When provision is missing, one may fund Mangrove using:

const ethersTx = await mgvLP.fundMangrove(missingAskProvision);
await ethersTx.wait(); // waiting for the funding tx to be confirmed