Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ RUN mvn -f /home/app/pom.xml clean package -DskipTests
FROM openjdk:17.0.2-slim
COPY --from=build /home/app/target/serum-data-1.2.0-SNAPSHOT.jar /usr/local/lib/serumdata.jar
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,address=*:8000,server=y,suspend=n
ENV OPENSERUM_ENDPOINT=GENESYSGO
ENV OPENSERUM_ENDPOINT=PROJECT_SERUM
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/serumdata.jar"]
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ public List<SerumOrder> getMarketBids(@PathVariable String marketId, HttpServlet
final Optional<OrderBook> orderBook = marketManager.getCachedBidOrderBook(marketPublicKey);

if (orderBook.isPresent()) {
List<SerumOrder> serumOrders = MarketUtil.convertOrderBookToSerumOrders(orderBook.get(), true);
boolean isZeta = marketManager.isZetaMarket(marketPublicKey);
List<SerumOrder> serumOrders = MarketUtil.convertOrderBookToSerumOrders(orderBook.get(), true, isZeta);

// Calculate aggregate percentages for each quote, add to metadata
float aggregateNotional = serumOrders.stream()
Expand Down Expand Up @@ -140,7 +141,8 @@ public List<SerumOrder> getMarketAsks(@PathVariable String marketId, HttpServlet
final Optional<OrderBook> orderBook = marketManager.getCachedAskOrderBook(marketPublicKey);

if (orderBook.isPresent()) {
List<SerumOrder> serumOrders = MarketUtil.convertOrderBookToSerumOrders(orderBook.get(), false);
boolean isZeta = marketManager.isZetaMarket(marketPublicKey);
List<SerumOrder> serumOrders = MarketUtil.convertOrderBookToSerumOrders(orderBook.get(), false, isZeta);

// Calculate aggregate percentages for each quote, add to metadata
float aggregateNotional = serumOrders.stream()
Expand Down Expand Up @@ -271,8 +273,9 @@ public MarketDepth getMarketDepth(@PathVariable String marketId, HttpServletResp
}

// isBid = false on the bids since chart JS library expects ascending order
final List<SerumOrder> bids = MarketUtil.convertOrderBookToSerumOrders(bidOrderBook.get(), false);
final List<SerumOrder> asks = MarketUtil.convertOrderBookToSerumOrders(askOrderBook.get(), false);
boolean isZeta = marketManager.isZetaMarket(marketPubkey);
final List<SerumOrder> bids = MarketUtil.convertOrderBookToSerumOrders(bidOrderBook.get(), false, isZeta);
final List<SerumOrder> asks = MarketUtil.convertOrderBookToSerumOrders(askOrderBook.get(), false, isZeta);

float bestBid = bids.size() > 0 ? bidOrderBook.get().getBestBid().getFloatPrice() : 0.0f;
float bestAsk = asks.size() > 0 ? askOrderBook.get().getBestAsk().getFloatPrice() : 0.0f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ public String markets(Model model) {
return "markets";
}

@RequestMapping("/zeta/{market}")
public String zetaMarket(Model model, @PathVariable String market) {
String sanitized = market.replaceAll("[^a-zA-Z\\d]", "");
PublicKey zetaMarketPublicKey = new PublicKey(sanitized);

model.addAttribute(DEFAULT_TOKEN_ATTRIBUTE_NAME, DEFAULT_TOKEN_SEARCH.toBase58());
model.addAttribute("tokens", activeTokenMap);
model.addAttribute(marketRankManager);

model.addAttribute(MARKET_ID_ATTRIBUTE_NAME, zetaMarketPublicKey.toBase58());

return "index";
}

// for now, return index with the market determined.
@RequestMapping("/{market}")
public String market(Model model, @PathVariable String market) {
Expand Down
48 changes: 38 additions & 10 deletions src/main/java/com/mmorrell/serumdata/manager/MarketManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class MarketManager {
private final Map<PublicKey, Long> bidOrderBookMinContextSlot = new HashMap<>();
private final Map<PublicKey, Long> eventQueueMinContextSlot = new HashMap<>();

private List<ProgramAccount> zetaAccounts = new ArrayList<>();

// Caching for individual bid and asks orderbooks.
final LoadingCache<PublicKey, OrderBook> bidOrderBookLoadingCache = CacheBuilder.newBuilder()
.refreshAfterWrite(ORDER_BOOK_CACHE_DURATION_SECONDS, TimeUnit.SECONDS)
Expand Down Expand Up @@ -204,6 +206,21 @@ public void updateMarkets() {
throw new RuntimeException(e);
}

try {
List<ProgramAccount> zetaAccounts = new ArrayList<>(
client.getApi().getProgramAccounts(
new PublicKey("zDEXqXEG7gAyxb1Kg9mK5fPnUdENCGKzWrM21RMdWRq"),
Collections.emptyList(),
1476
)
);

this.zetaAccounts = zetaAccounts;
programAccounts.addAll(zetaAccounts);
} catch (RpcException e) {
throw new RuntimeException(e);
}

for (ProgramAccount programAccount : programAccounts) {
Market market = Market.readMarket(programAccount.getAccount().getDecodedData());

Expand All @@ -212,16 +229,22 @@ public void updateMarkets() {
continue;
}

market.setBaseDecimals(
(byte) tokenManager.getDecimals(
market.getBaseMint()
)
);
market.setQuoteDecimals(
(byte) tokenManager.getDecimals(
market.getQuoteMint()
)
);
if (!zetaAccounts.contains(programAccount)) {
market.setBaseDecimals(
(byte) tokenManager.getDecimals(
market.getBaseMint()
)
);
market.setQuoteDecimals(
(byte) tokenManager.getDecimals(
market.getQuoteMint()
)
);
} else {
// zeta, hardcode decimals for poc
market.setBaseDecimals((byte) 0);
market.setQuoteDecimals((byte) 6);
}
marketCache.put(market.getOwnAddress(), market);

// marketMapCache is a baseMint to List<Market> map which powers the token search.
Expand Down Expand Up @@ -396,4 +419,9 @@ public long getBidContext(PublicKey publicKey) {
public long getAskContext(PublicKey publicKey) {
return bidOrderBookMinContextSlot.getOrDefault(publicKey, DEFAULT_MIN_CONTEXT_SLOT);
}

public boolean isZetaMarket(PublicKey marketPublicKey) {
return zetaAccounts.stream()
.anyMatch(programAccount -> programAccount.getPubkey().equalsIgnoreCase(marketPublicKey.toBase58()));
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/mmorrell/serumdata/util/MarketUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public class MarketUtil {
PublicKey.valueOf("61CjGbapEVoyCC51x5tPZGZHCYsgtPSSssCatHEEUWeG");


public static List<SerumOrder> convertOrderBookToSerumOrders(OrderBook orderBook, boolean isBid) {
public static List<SerumOrder> convertOrderBookToSerumOrders(OrderBook orderBook, boolean isBid, boolean isZeta) {
return orderBook.getOrders().stream()
.map(order -> {
SerumOrder serumOrder = new SerumOrder();
serumOrder.setPrice(order.getFloatPrice());
serumOrder.setQuantity(order.getFloatQuantity());
serumOrder.setQuantity(isZeta ? order.getFloatQuantity() / 1000 : order.getFloatQuantity());
serumOrder.setOwner(order.getOwner());
return serumOrder;
})
Expand Down
38 changes: 19 additions & 19 deletions src/main/resources/templates/index.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Project Serum market data">
<title>Openserum - Project Serum Market Data</title>
<link rel="shortcut icon" type="image/png" href="static/serum-srm-logo.png"/>
<link rel="shortcut icon" type="image/png" href="/static/serum-srm-logo.png"/>

<!-- DARK MODE -->
<meta name="color-scheme" content="dark">
<link href="static/css/bootstrap-nightshade.min.css" rel="stylesheet">
<link href="static/css/custom.css" rel="stylesheet">
<link href="static/css/jquery.dataTables.min.css" rel="stylesheet">
<link href="/static/css/bootstrap-nightshade.min.css" rel="stylesheet">
<link href="/static/css/custom.css" rel="stylesheet">
<link href="/static/css/jquery.dataTables.min.css" rel="stylesheet">
<!-- end dark mode -->

<!-- github/twitter icons -->
<link rel="stylesheet" href="static/css/font-awesome.min.css">
<link href="static/css/select2.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link href="/static/css/select2.min.css" rel="stylesheet"/>

<!-- jquery & chartjs -->
<script src="static/js/jquery-3.6.0.min.js"></script>
<script src="static/js/chart.min.js"></script>
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script src="/static/js/chart.min.js"></script>

<!-- depth -->
<script src="static/highcharts.js"></script>
<script src="static/plugin.js"></script>
<script src="/static/highcharts.js"></script>
<script src="/static/plugin.js"></script>

<script src="static/js/select2.min.js"></script>
<script src="/static/js/select2.min.js"></script>
<!-- JavaScript Bundle with Popper -->
<script src="static/js/bootstrap.bundle.min.js"></script>
<script src="static/js/jquery.dataTables.min.js"></script>
<script src="static/js/custom.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/jquery.dataTables.min.js"></script>
<script src="/static/js/custom.js"></script>

<!-- inlined vars from controller -->
<script th:inline="javascript">
Expand Down Expand Up @@ -81,7 +81,7 @@
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<span class="coloredlink" style="font-size: calc(1.4rem + .3vw)!important;"><img
src="static/serum-srm-logo.png"
src="/static/serum-srm-logo.png"
width="32"
height="32"
style="margin-right: 0.5rem!important;">Openserum Market Data</span>
Expand All @@ -95,13 +95,13 @@
target="_blank" style="background-image:
linear-gradient(45deg, #e15300, #a12100); color:white;
text-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;"><img
src="static/entities/solend.ico" width="20"
src="/static/entities/solend.ico" width="20"
height="20">Solend</a></li>
<li class="nav-item"><a href="https://trade.mango.markets?ref=openserum" aria-current="page"
class="nav-link"
target="_blank" style="background-image:
linear-gradient(45deg, #ff9500, #ff0000); color:white;"><img
src="static/entities/mango.ico" width="20"
src="/static/entities/mango.ico" width="20"
height="20">Mango Markets</a></li>
</ul>
</header>
Expand Down Expand Up @@ -251,7 +251,7 @@
rgb(29, 29, 29);">
<thead>
<tr>
<h4><img src="static/serum-srm-logo.png" width="32" height="32" style="margin-right:
<h4><img src="/static/serum-srm-logo.png" width="32" height="32" style="margin-right:
0.5rem!important;">Market Information</h4>
</tr>
</thead>
Expand Down Expand Up @@ -492,7 +492,7 @@
setInterval(updateDepthChart, 550);

</script>
<script src="static/js/darkmode.min.js"></script>
<script src="/static/js/darkmode.min.js"></script>
<script type="text/javascript" th:inline="none" class="init">
/*<![CDATA[*/
$(document).ready(function () {
Expand Down
26 changes: 13 additions & 13 deletions src/main/resources/templates/markets.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Project Serum market data">
<title>Markets - Openserum - Project Serum Market Data</title>
<link rel="shortcut icon" type="image/png" href="static/serum-srm-logo.png"/>
<link rel="shortcut icon" type="image/png" href="/static/serum-srm-logo.png"/>

<!-- DARK MODE -->
<meta name="color-scheme" content="dark">
<link href="static/css/bootstrap-nightshade.min.css" rel="stylesheet">
<link href="static/css/custom.css" rel="stylesheet">
<link href="static/css/jquery.dataTables.min.css" rel="stylesheet">
<link href="/static/css/bootstrap-nightshade.min.css" rel="stylesheet">
<link href="/static/css/custom.css" rel="stylesheet">
<link href="/static/css/jquery.dataTables.min.css" rel="stylesheet">

<!-- end dark mode -->
<!-- github/twitter icons -->
<link rel="stylesheet" href="static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">

<!-- jquery & chartjs -->
<script src="static/js/jquery-3.6.0.min.js"></script>
<script src="static/js/chart.min.js"></script>
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script src="/static/js/chart.min.js"></script>

<!-- JavaScript Bundle with Popper -->
<script src="static/js/bootstrap.bundle.min.js"></script>
<script src="static/js/jquery.dataTables.min.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/jquery.dataTables.min.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-H55B3XYLG0"></script>
<script>
Expand All @@ -43,7 +43,7 @@
<div class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<span class="coloredlink" style="font-size: calc(1.4rem + .3vw)!important;"><img src="static/serum-srm-logo.png" width="32"
<span class="coloredlink" style="font-size: calc(1.4rem + .3vw)!important;"><img src="/static/serum-srm-logo.png" width="32"
height="32"
style="margin-right: 0.5rem!important;">Openserum Market Data</span>
</a>
Expand All @@ -57,13 +57,13 @@
target="_blank" style="background-image:
linear-gradient(45deg, #e15300, #a12100); color:white;
text-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;"><img
src="static/entities/solend.ico" width="20"
src="/static/entities/solend.ico" width="20"
height="20">Solend</a></li>
<li class="nav-item"><a href="https://trade.mango.markets?ref=openserum" aria-current="page"
class="nav-link"
target="_blank" style="background-image:
linear-gradient(45deg, #ff9500, #ff0000); color:white;"><img
src="static/entities/mango.ico" width="20"
src="/static/entities/mango.ico" width="20"
height="20">Mango Markets</a></li>
</ul>
</header>
Expand Down Expand Up @@ -126,7 +126,7 @@
</div>
</div>
</main>
<script src="static/js/darkmode.min.js"></script>
<script src="/static/js/darkmode.min.js"></script>
<script type="text/javascript" th:inline="none" class="init">
/*<![CDATA[*/
$(document).ready(function () {
Expand Down