Lyra Documentation
Search…
⌃K

Execute a Trade (off chain)

In this guide, we will write a simple script using the Lyra.js package that purchases a call option from the AMM, then modifies and closes the position.

1. Setup Lyra.js

Lyra.js is a JavaScript SDK for Optimistic Ethereum and the Lyra Protocol. It wraps around ethers and works in the web browser and Node.js.
To get started, clone the Lyra.js starter project:
git clone https://github.com/lyra-finance/lyra-js-starter.git
cd lyra-js-starter
Next, run yarn install to install node modules, including lyrafinance/lyra-js:
yarn install

2. Find a Strike

First, we need to find a strike in delta range for the ETH market. This example fetches the ETH Market entity. The Market entity has a liveBoards field which gets all active Board entities (representing expiries). The Board entity also has a strikes field which gets all available strikes, and finds the first strike with flag isInDeltaRange set to true.
import Lyra from '@lyrafinance/lyra-js'
// Initialize Lyra.js
const lyra = new Lyra()
// Get the ETH market
const market = await lyra.market('eth')
// Select most recent expiry
const board = market.liveBoards()[0]
// Select first strike in delta range
const strike = board.strikes().find(strike => strike.isDeltaInRange)
if (!strike) {
throw new Error('No strike in delta range')
}

3. Approve sUSD

Lyra uses synths as collateral and settlement for trades, with option premiums being paid in Synthetic USD or sUSD. After finding a strike, approve sUSD for trading against the OptionMarketWrapper contract, which has permission to trade across all markets. In this example we approve ethers.constants.MaxUint256, the maximum possible amount.
// Initialize an account with a private key
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, lyra.provider)
const account = lyra.account(signer.address)
// Generate approval transaction
// Here, quoteToken for a market is sUSD
const approveTx = await account.approveStableToken(
market.quoteToken.address,
ethers.constants.MaxUint256
)
// Sign and send transaction
const approveResponse = await signer.sendTransaction(approveTx)
// Wait for transaction to be confirmed
await approveResponse.wait()

4. Buy a Call

In this example we buy a single call contract from the ETH market with 0.1% slippage. After executing the trade, a TradeEvent entity is returned which contains details about the executed trade including premiums and fees paid and a reference to the generated Position.
// Get unique strike ID
const strikeId = strike.id
// Buying a call
const isCall = true
const isBuy = true
// Buying 1.0 contract (in units of wei)
const ONE_BN = ethers.constants.WeiPerEther
/ Allow for 0.1% slippage
const SLIPPAGE = 0.001
// Generate trade transaction with quote
const trade = await strike.trade(
account.address,
strikeId,
isCall,
isBuy,
ONE_BN,
SLIPPAGE
)
// Check if trade is disabled
if (trade.isDisabled) {
throw new Error(trade.disabledReason)
}
// Sign + send transaction
const tradeResponse = await signer.sendTransaction(trade.tx)
// Wait for transaction to be confirmed
const tradeReceipt = await tradeResponse.wait()
// Get the resulting trade event
const tradeEvent = (await TradeEvent.getByHash(
lyra,
tradeReceipt.transactionHash
))[0]

5. Adjust Position

Using a reference to a position - which can be retrieved from lyra.positions or directly from a TradeEvent per the previous code snippet - we can adjust its size and collateral. In this example we increase the previous position's size from 1.0 to 2.0 contracts using the position.add function.
// Get the open position from a trade (can also be fetched from lyra.positions)
const position = await tradeEvent.position()
// Adding 1.0 contracts to the position
const ONE_BN = ethers.constants.WeiPerEther
// Maintaining slippage of 0.1%
const SLIPPAGE = 0.001
// Generate trade transaction with quote
const addPosition = await position.add(ONE_BN, SLIPPAGE)
// Check if trade is disabled
if (addPosition.isDisabled) {
throw new Error(addPosition.disabledReason)
}
// Sign + send transaction
const addPositionResponse = await signer.sendTransaction(addPosition.tx)
// Wait for transaction to be confirmed
const addPositionReceipt = await addPositionResponse.wait()
// Get the resulting position adjustment event
const addPositionEvent = (await TradeEvent.getByHash(
lyra,
addPositionReceipt.transactionHash
))[0]

6. Close Position

Similarly, to close a position you can simply call position.close from a Position reference.
// Maintaining slippage of 0.1%
const SLIPPAGE = 0.001
// Generate trade transaction with quote
const closePosition = await position.close(SLIPPAGE)
// Check if trade is disabled
if (closePosition.isDisabled) {
throw new Error(addPosition.disabledReason)
}
// Sign + send transaction
const closePositionResponse = await signer.sendTransaction(closePosition.tx)
// Wait for transaction to be confirmed
const closePositionReceipt = await closePositionResponse.wait()
// Get the resulting position close event
const closePositionEvent = (await TradeEvent.getByHash(
lyra,
addPositionReceipt.transactionHash
))[0]