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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
config.yaml
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Alpha-Beta 0.0.0v
This is the initial version of the project. However, some progress has already been made, including:
- Research on STonFi contracts on the TON blockchain.
- Research on UniSwap contracts on Ethereum.
- Development of an initial version of the API server (which will need to be rewritten).
Some mathematical aspects may need to be reviewed, particularly due to the challenges of working with integer operations, which has been a bit of a pain point. Future versions are planned to include support for additional protocols, possibly starting with one on Solana and later adding support for Tron to increase diversity.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 JZethar
Copyright (c) 2024 Yulian Volianskyi aka jzethar

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
87 changes: 86 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,87 @@
# DexPriceAPI
# Dex Price API
An API to retrieve prices directly from DEXs.

## What is it?
This project was initiated as an Open Source token price API. Its primary goal is to provide free access to token prices across various DEXs (Decentralized Exchanges). The API is designed to be particularly useful for companies whose products rely on token prices, such as wallets and other Web3 applications. All prices accessible through this API are publicly available and stored within DEX contracts on public blockchains.

## Supported protocols
Now are supported only 2 protocols:
- [STonFi](https://ston.fi/)
- [UniSwap](https://uniswap.org)

## Supported chains
- Ethereum
- TON

## Run docker
To run docker compose just:

`docker compose up --build -d`

Before using docker compose be sure that you have your ip correct in your config file. Also check ports and config path.

## Config file
Config file now contains only 2 params:
- ip
- port


## Examples
On request:
```sh
curl --location 'http://localhost:15001/ton' \
--header 'Content-Type: application/json' \
--data '{
"method": "TONDex.GetPoolPrice",
"params": [
{
"pool":"EQD8TJ8xEWB1SpnRE4d89YO3jl0W0EiBnNS4IBaHaUmdfizE"
}
],
"id": "1"
}'
```
You will se the response:
```json
{
"result": {
"token0": "0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe",
"token1": "0:8cdc1d7640ad5ee326527fc1ad0514f468b30dc84b0173f0e155f451b4e11f7c",
"price_of_token0": "149599453",
"price_of_token1": "6684516415",
"decimals": "9"
},
"error": null,
"id": "1"
}
```
And the second type of request:
```sh
curl --location 'http://localhost:15001/ton' \
--header 'Content-Type: application/json' \
--data '{
"method": "TONDex.GetTokensPrices",
"params": [
{
"token0" : "EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT",
"token1" : "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"
}
],
"id": "1"
}'
```
Response:
```json
{
"result": {
"token0": "0:2f956143c461769579baef2e32cc2d7bc18283f40d20bb03e432cd603ac33ffc",
"token1": "0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe",
"price_of_token0": "12590087",
"price_of_token1": "79427567228",
"decimals": "9"
},
"error": null,
"id": "1"
}
```
Be aware that prices are changing all the time and this is only example.
13 changes: 13 additions & 0 deletions common/tokenPrices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2024, Yulian Volianskyi aka jzethar, All rights reserved.
// This code is a part of DexPriceAPI project
// See the LICENSE file

package common

type TokenPrice struct {
Token0 string `json:"token0,omitempty"`
Token1 string `json:"token1,omitempty"`
PriceT0 string `json:"price_of_token0,omitempty"`
PriceT1 string `json:"price_of_token1,omitempty"`
Decimals string `json:"decimals,omitempty"`
}
63 changes: 63 additions & 0 deletions common/uniSlot0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2024, Yulian Volianskyi aka jzethar, All rights reserved.
// This code is a part of DexPriceAPI project
// See the LICENSE file

package common

import (
"math/big"
"strconv"
)

// Golang doesn’t check for overflows implicitly and
// so this may lead to unexpected results when a number
// larger than 64 bits are stored in a int64.
type UniSlot0 struct {
SqrtPriceX96 big.Int // uint160
tick int32
observationIndex uint16
observationCardinality uint16
observationCardinalityNext uint16
feeProtocol uint8
unlocked bool
}

func (uns *UniSlot0) hex2int(data string, bitsize int) int64 {
result, _ := strconv.ParseInt(data, 16, bitsize)
return result
}

func (uns *UniSlot0) Unmarshal(data string) error {
data = data[2:]

SqrtPriceX96 := data[:64]
uns.SqrtPriceX96.SetString(SqrtPriceX96, 16)
data = data[64:]

tick := data[:64]
uns.tick = int32(uns.hex2int(tick, 32))
data = data[64:]

observationIndex := data[:64]
uns.observationIndex = uint16(uns.hex2int(observationIndex, 16))
data = data[64:]

observationCardinality := data[:64]
uns.observationCardinality = uint16(uns.hex2int(observationCardinality, 16))
data = data[64:]

observationCardinalityNext := data[:64]
uns.observationCardinalityNext = uint16(uns.hex2int(observationCardinalityNext, 16))
data = data[64:]

feeProtocol := data[:64]
uns.feeProtocol = uint8(uns.hex2int(feeProtocol, 8))
data = data[64:]

if string(data[len(data)-1]) == "1" {
uns.unlocked = true
} else {
uns.unlocked = false
}
return nil
}
3 changes: 3 additions & 0 deletions config_example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
server:
ip: 0.0.0.0
port: 15001
15 changes: 15 additions & 0 deletions dex_prices.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM golang:1.21 AS builder
WORKDIR /app

COPY . .
RUN go mod download
RUN go mod tidy

WORKDIR /app/server
RUN CGO_ENABLED=0 GOOS=linux go build -o main

FROM alpine:latest
RUN apk --no-cache add ca-certificates

WORKDIR /root/
COPY --from=builder /app/server/main .
43 changes: 43 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
version: "3.7"

x-logging: &logging
logging:
driver: json-file
options:
max-size: 5m
max-file: "2"

volumes:
dex_prices:
driver: local
driver_opts:
type: none
device: /var/lib/dex_prices # TODO rename before git
o: bind


services:
dex_api:
build:
context: .
dockerfile: dex_prices.Dockerfile
restart: on-failure
stop_grace_period: 1m
deploy:
resources:
limits:
memory: 2G
cpus: "2"
<<: *logging
ports:
- 127.0.0.1:15001:15001 # API
# TODO: add swagger
networks:
- dex_prices_net
volumes:
- dex_prices:/home/dex_prices
- ./config.yaml:/home/dex_prices/config.yaml
command: ["./main", "-c", "/home/dex_prices/"]

networks:
dex_prices_net:
Loading