Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
enzofoucaud committed Jun 6, 2023
0 parents commit e0e6e51
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
45 changes: 45 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of uname.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
42 changes: 42 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package config

import (
"encoding/json"
"os"
)

type Config struct {
LogLevel string `json:"log_level"`
DiscordID string `json:"discord_id"`
DiscordToken string `json:"discord_token"`
Tokens []struct {
Token string `json:"token"`
Price float64 `json:"price"`
IsBelow bool `json:"is_below"`
IsAbove bool `json:"is_above"`
} `json:"tokens"`
}

func GetConfig() (Config, error) {
var config Config
err := ReadJSON("config.json", &config)
if err != nil {
return config, err
}
return config, nil
}

func ReadJSON(path string, v interface{}) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()

decoder := json.NewDecoder(file)
err = decoder.Decode(&v)
if err != nil {
return err
}
return nil
}
13 changes: 13 additions & 0 deletions example.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"log_level": "DEBUG",
"discord_id": "",
"discord_token": "",
"tokens": [
{
"token": "WAGMI",
"price": 0.000001,
"is_below": false,
"is_above": true
}
]
}
75 changes: 75 additions & 0 deletions exrond/getPairsQuery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package exrond

import (
"encoding/json"
"io"
"net/http"
"strings"

"github.com/rs/zerolog/log"
)

type Pairs struct {
Data struct {
Pairs []struct {
Address string `json:"address"`
FirstTokenPrice string `json:"firstTokenPrice"`
SecondTokenPrice string `json:"secondTokenPrice"`
FirstTokenReserve string `json:"firstTokenReserve"`
SecondTokenReserve string `json:"secondTokenReserve"`
FirstToken struct {
Identifier string `json:"identifier"`
Name string `json:"name"`
Decimals int `json:"decimals"`
Supply string `json:"supply"`
Ticker string `json:"ticker"`
Balance string `json:"balance"`
} `json:"firstToken"`
SecondToken struct {
Identifier string `json:"identifier"`
Name string `json:"name"`
Decimals int `json:"decimals"`
Supply string `json:"supply"`
Ticker string `json:"ticker"`
Balance string `json:"balance"`
} `json:"secondToken"`
} `json:"pairs"`
} `json:"data"`
}

func GetPairsQuery() (Pairs, error) {
//Encode the data
var (
url = "https://api.exrond.com/graphql"
)

request := `
{"operationName":"GET_PAIRS_QUERY","variables":{},"query":"query GET_PAIRS_QUERY {\n pairs {\n address\n firstTokenPrice\n secondTokenPrice\n firstTokenReserve\n secondTokenReserve\n firstToken {\n identifier\n name\n decimals\n supply\n ticker\n balance\n assets {\n svgUrl\n pngUrl\n __typename\n }\n __typename\n }\n secondToken {\n identifier\n name\n decimals\n supply\n ticker\n balance\n assets {\n svgUrl\n pngUrl\n __typename\n }\n __typename\n }\n __typename\n }\n}"}
`

// Create a new request using http
resp, err := http.Post(url, "application/json", strings.NewReader(request))
if err != nil {
log.Err(err).Msg("error making request")
return Pairs{}, err
}

defer func() {
_ = resp.Body.Close()
}()

body, err := io.ReadAll(resp.Body)
if err != nil {
log.Err(err).Msg("error reading response body")
return Pairs{}, err
}

var p Pairs
err = json.Unmarshal(body, &p)
if err != nil {
log.Err(err).Msg("error unmarshalling data")
return Pairs{}, err
}

return p, nil
}
19 changes: 19 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/enzofoucaud/exrond-notifier

go 1.20

require (
github.com/disgoorg/disgo v0.16.5
github.com/disgoorg/snowflake/v2 v2.0.1
github.com/rs/zerolog v1.29.1
)

require (
github.com/disgoorg/json v1.1.0 // indirect
github.com/disgoorg/log v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b // indirect
golang.org/x/exp v0.0.0-20220325121720-054d8573a5d8 // indirect
golang.org/x/sys v0.1.0 // indirect
)
30 changes: 30 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/disgoorg/disgo v0.16.5 h1:6f2k9OwiDvLL/xq9mxevBVEpL0oSKYxM7aZ+v8mnt5w=
github.com/disgoorg/disgo v0.16.5/go.mod h1:wo61ZLPn6bxHVdUODjyZ3fZTnCT7giD3uknsDUwMGn8=
github.com/disgoorg/json v1.1.0 h1:7xigHvomlVA9PQw9bMGO02PHGJJPqvX5AnwlYg/Tnys=
github.com/disgoorg/json v1.1.0/go.mod h1:BHDwdde0rpQFDVsRLKhma6Y7fTbQKub/zdGO5O9NqqA=
github.com/disgoorg/log v1.2.0 h1:sqlXnu/ZKAlIlHV9IO+dbMto7/hCQ474vlIdMWk8QKo=
github.com/disgoorg/log v1.2.0/go.mod h1:3x1KDG6DI1CE2pDwi3qlwT3wlXpeHW/5rVay+1qDqOo=
github.com/disgoorg/snowflake/v2 v2.0.1 h1:CuUxGLwggUxEswZOmZ+mZ5i0xSumQdXW9tXW7uGqe+0=
github.com/disgoorg/snowflake/v2 v2.0.1/go.mod h1:SPU9c2CNn5DSyb86QcKtdZgix9osEtKrHLW4rMhfLCs=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b h1:qYTY2tN72LhgDj2rtWG+LI6TXFl2ygFQQ4YezfVaGQE=
github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
golang.org/x/exp v0.0.0-20220325121720-054d8573a5d8 h1:Xt4/LzbTwfocTk9ZLEu4onjeFucl88iW+v4j4PWbQuE=
golang.org/x/exp v0.0.0-20220325121720-054d8573a5d8/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
99 changes: 99 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import (
"context"
"os"
"strconv"
"time"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/webhook"
"github.com/disgoorg/snowflake/v2"
"github.com/enzofoucaud/exrond-notifier/config"
"github.com/enzofoucaud/exrond-notifier/exrond"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

func init() {
// LOG
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}

func main() {
log.Info().Msg("Starting bot")

c, err := config.GetConfig()
if err != nil {
log.Err(err).Msg("error getting config")
return
}

switch c.LogLevel {
case "INFO":
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case "DEBUG":
zerolog.SetGlobalLevel(zerolog.DebugLevel)
default:
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}

for {
pairs, err := exrond.GetPairsQuery()
if err != nil {
log.Err(err).Msg("error getting pairs")
return
}

for _, pair := range pairs.Data.Pairs {
log.Debug().Msg("--------------")
log.Debug().Msg("Checking pair " + pair.FirstToken.Name + " " + pair.SecondToken.Name)
log.Debug().Msg("First token price: " + pair.FirstTokenPrice)
log.Debug().Msg("Second token price: " + pair.SecondTokenPrice)
// Check if pair is WAGMI
for _, token := range c.Tokens {
if token.Token == pair.SecondToken.Name {
if token.IsBelow {
pairFloat, _ := strconv.ParseFloat(pair.SecondTokenPrice, 64)
if pairFloat <= token.Price {
message := "WAGMI alert: token is below " + pair.SecondTokenPrice
err := Discord(message, c.DiscordID, c.DiscordToken)
if err != nil {
log.Err(err).Msg("error sending discord notification")
}
log.Info().Msg("Notifier sent for " + pair.FirstToken.Name + " " + pair.SecondToken.Name)
}
}
if token.IsAbove {
pairFloat, _ := strconv.ParseFloat(pair.SecondTokenPrice, 64)
if pairFloat >= token.Price {
message := "WAGMI alert: token is above " + pair.SecondTokenPrice
err := Discord(message, c.DiscordID, c.DiscordToken)
if err != nil {
log.Err(err).Msg("error sending discord notification")
}
log.Info().Msg("Notifier sent for " + pair.FirstToken.Name + " " + pair.SecondToken.Name)
}
}
}
}
}
log.Debug().Msg("--------------")

time.Sleep(1 * time.Minute)
}
}

func Discord(message, discordID, discordToken string) error {
client := webhook.New(snowflake.MustParse(discordID), discordToken)
defer client.Close(context.TODO())

if _, err := client.CreateMessage(discord.NewWebhookMessageCreateBuilder().
SetContent(message).
Build(),
); err != nil {
return err
}

return nil
}

0 comments on commit e0e6e51

Please sign in to comment.