Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
wlchn committed Feb 19, 2019
0 parents commit 28f3aab
Show file tree
Hide file tree
Showing 25 changed files with 1,126 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
BLOCKCHAIN=
# GIN_MODE=release
GIN_MODE=debug
PORT=8080
POSTGRES_URL=postgres://YourUserName:YourPassword@YourHost:5432/YourDatabase?sslmode=disable
HYDRO_EXCHANGE_ADDRESS=0x2cB4B49C0d6E9db2164d94Ce48853BF77C4D883E
WEB3_URL=https://mainnet.infura.io
WEB3_WS=wss://mainnet.infura.io/ws
ETHPLORER_APIKEY=freekey
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
13 changes: 13 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package api

import (
"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/api/v1"
)

func ApplyRoutes(r *gin.Engine) {
api := r.Group("/api")
{
apiv1.ApplyRoutes(api)
}
}
26 changes: 26 additions & 0 deletions api/v1/relayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package apiv1

import (
"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/models"
"github.com/jinzhu/gorm"
)

func GetRelayers(c *gin.Context) {
var relayers []models.Relayer
if err := models.DB.Find(&relayers).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, relayers)
}
}

func GetRelayer(c *gin.Context) {
slug := c.Params.ByName("slug")
relayer := models.Relayer{}
if err := models.DB.Where("slug = ?", slug).First(&relayer).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, relayer)
}
}
37 changes: 37 additions & 0 deletions api/v1/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package apiv1

import (
"strconv"

"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/models"
"github.com/jinzhu/gorm"
)

func GetTokens(c *gin.Context) {
pageQuery := c.DefaultQuery("page", "1")
i, err := strconv.ParseInt(pageQuery, 10, 64)
page := int(i)
if err != nil {
page = 0
}
pageSize := 20
offset := (page - 1) * pageSize

var tokens []models.Token
if err := models.DB.Offset(offset).Limit(pageSize).Find(&tokens).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, tokens)
}
}

func GetToken(c *gin.Context) {
address := c.Params.ByName("address")
token := models.Token{}
if err := models.DB.Where("address = ?", address).First(&token).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, token)
}
}
37 changes: 37 additions & 0 deletions api/v1/trade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package apiv1

import (
"strconv"

"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/models"
"github.com/jinzhu/gorm"
)

func GetTrades(c *gin.Context) {
pageQuery := c.DefaultQuery("page", "1")
i, err := strconv.ParseInt(pageQuery, 10, 64)
page := int(i)
if err != nil {
page = 0
}
pageSize := 20
offset := (page - 1) * pageSize

var trades []models.Trade
if err := models.DB.Order("block_number desc").Order("log_index desc").Offset(offset).Limit(pageSize).Preload("Relayer").Preload("BaseToken").Preload("QuoteToken").Find(&trades).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, trades)
}
}

func GetTrade(c *gin.Context) {
uuid := c.Params.ByName("uuid")
trade := models.Trade{}
if err := models.DB.Where("uuid = ?", uuid).First(&trade).Error; gorm.IsRecordNotFoundError(err) {
c.AbortWithStatus(404)
} else {
c.JSON(200, trade)
}
}
17 changes: 17 additions & 0 deletions api/v1/v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package apiv1

import (
"github.com/gin-gonic/gin"
)

func ApplyRoutes(r *gin.RouterGroup) {
v1 := r.Group("/v1")
{
v1.GET("/tokens", GetTokens)
v1.GET("/tokens/:address", GetToken)
v1.GET("/relayers", GetRelayers)
v1.GET("/relayers/:slug", GetRelayer)
v1.GET("/trades", GetTrades)
v1.GET("/trades/:uuid", GetTrade)
}
}
42 changes: 42 additions & 0 deletions cmd/cron/cron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"github.com/hydroscan/hydroscan-api/models"
"github.com/hydroscan/hydroscan-api/task"
"github.com/jasonlvhit/gocron"
_ "github.com/joho/godotenv/autoload"
log "github.com/sirupsen/logrus"
)

type taskType func()

// Ensure cron don't crash when one task failed(panic)
func safeTask(fn taskType) taskType {
return func() {
defer func() {
if err := recover(); err != nil {
log.Warn(err)
}
}()
fn()
}
}

func main() {
models.Connect()
defer models.Close()
task.InitEthClient()

log.Info("cron running")

// Fetch a mass of missing logs before cron task
// task.FetchHistoricalLogs()

// gocron.Every(1).Minutes().Do(safeTask(task.FetchHistoricalLogs))
gocron.Every(5).Minutes().Do(safeTask(task.UpdateTokenPrices))
gocron.Every(1).Day().Do(safeTask(task.UpdateRelayers))

_, time := gocron.NextRun()
log.Info(time)
<-gocron.Start()
}
23 changes: 23 additions & 0 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/api"
"github.com/hydroscan/hydroscan-api/middleware"
"github.com/hydroscan/hydroscan-api/models"
"github.com/hydroscan/hydroscan-api/task"
_ "github.com/joho/godotenv/autoload"
)

func main() {
models.Connect()
defer models.Close()
task.InitEthClient()

r := gin.Default()
r.ForwardedByClientIP = true
r.Use(middleware.Limit())
r.Use(middleware.CORS())
api.ApplyRoutes(r)
r.Run()
}
31 changes: 31 additions & 0 deletions cmd/subscriber/subscriber.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"time"

"github.com/hydroscan/hydroscan-api/models"
"github.com/hydroscan/hydroscan-api/task"
_ "github.com/joho/godotenv/autoload"
log "github.com/sirupsen/logrus"
)

func subscribeRetryWrapper() {
defer func() {
if err := recover(); err != nil {
log.Warn(err)
}
}()
task.SubscribeLogs()
time.Sleep(3000 * time.Millisecond)
log.Info("subscriber retry")
}

func main() {
models.Connect()
defer models.Close()
task.InitEthClient()
log.Info("subscriber running")
for {
subscribeRetryWrapper()
}
}
39 changes: 39 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module github.com/hydroscan/hydroscan-api

require (
cloud.google.com/go v0.36.0 // indirect
github.com/allegro/bigcache v1.2.0 // indirect
github.com/aristanetworks/goarista v0.0.0-20190212181145-83ee463e1d9e // indirect
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 // indirect
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289 // indirect
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
github.com/ethereum/go-ethereum v1.8.22
github.com/gin-contrib/sse v0.0.0-20190125020943-a7658810eb74 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/go-sql-driver/mysql v1.4.1 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gofrs/uuid v3.2.0+incompatible // indirect
github.com/google/uuid v1.1.0
github.com/jasonlvhit/gocron v0.0.0-20190121134850-6771d4b492ba // indirect
github.com/jinzhu/gorm v1.9.2
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3 // indirect
github.com/joho/godotenv v1.3.0
github.com/json-iterator/go v1.1.5
github.com/lib/pq v1.0.0 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/mattn/go-sqlite3 v1.10.0 // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/rs/cors v1.6.0 // indirect
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
github.com/sirupsen/logrus v1.3.0
github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66 // indirect
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 // indirect
github.com/ulule/limiter/v3 v3.1.0
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 // indirect
google.golang.org/appengine v1.4.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)
Loading

0 comments on commit 28f3aab

Please sign in to comment.