Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ CRYPTO_NOTIFY_TELEGRAM_CHAT_ID=""
CRYPTO_NOTIFY_LINE_NOTIFY_TOKEN=""
CRYPTO_NOTIFY_NOTIFY_CRON="0 0 */3 * * ? *" # optional
CRYPTO_NOTIFY_HEALTHCHECK_CRON="0 */1 * * * ? *" # optional
CRYPTO_NOTIFY_BSCSCAN_API_KEY="" # optional
CRYPTO_NOTIFY_BSCSCAN_ADDRESS="" # optional
CRYPTO_NOTIFY_ETHERSCAN_API_KEY="" # optional
CRYPTO_NOTIFY_BSC_ADDRESS="" # optional
CRYPTO_NOTIFY_MACKEREL_API_KEY="" # optional
CRYPTO_NOTIFY_MACKEREL_SERVICE_NAME="" # optional
CRYPTO_NOTIFY_BINANCE_API_KEY="" # optional
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
dockerPublish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
- uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
distribution: 'zulu'
java-version: '25'
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
Expand Down
30 changes: 15 additions & 15 deletions .github/workflows/pr_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ jobs:
runs-on: ubuntu-latest
if: ${{ !contains(github.actor, 'github-actions[bot]') }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.ACTION_TOKEN }}
- name: Set up JDK 21
uses: actions/setup-java@v4
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
distribution: 'zulu'
java-version: '25'
- name: Set Git Username
run: |
git config --global user.name "github-actions[bot]"
Expand All @@ -44,12 +44,12 @@ jobs:
needs: formatCode
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
- uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
distribution: 'zulu'
java-version: '25'
- uses: sbt/setup-sbt@v1
- name: Clean and Compile
run: sbt clean compile
Expand All @@ -58,12 +58,12 @@ jobs:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
- uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
distribution: 'zulu'
java-version: '25'
- uses: sbt/setup-sbt@v1
- name: Test
run: sbt test
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
needs: dockerPublish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
distribution: 'zulu'
java-version: '25'
- name: Set GitHub user
run: |
git config --global user.name 'github-actions[bot]'
Expand All @@ -34,7 +34,7 @@ jobs:
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set GitHub user
run: |
git config --global user.name 'oat9002'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Notify your current cryptocurrency balance from Satang Pro via Line Notify or Te

- Orbix `// Required to convert to THB`
- Binance `// Required if there is no listed coin in Satang Pro`
- BscScan
- EtherScan
- Terra
- CakePool
- VeCakePool
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ scalacOptions ++= Seq("-deprecation")
enablePlugins(JavaAppPackaging, DockerPlugin)

dockerRepository := Some("oat9002")
dockerBaseImage := "eclipse-temurin:21-jre-jammy"
dockerBaseImage := "azul/zulu-openjdk:25-jre-latest"
dockerExposedPorts := Seq(8080, 80, 443)
dockerUpdateLatest := true

Expand Down
2 changes: 1 addition & 1 deletion qodana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ profile:
# paths:
# - <path/where/not/run/inspection>

projectJDK: temurin-21 #(Applied in CI/CD pipeline)
projectJDK: zulu-25 #(Applied in CI/CD pipeline)

#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
#bootstrap: sh ./prepare-qodana.sh
Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ telegram {
botToken = ${?CRYPTO_NOTIFY_TELEGRAM_BOT_TOKEN}
chatId = ${?CRYPTO_NOTIFY_TELEGRAM_CHAT_ID}
}
bscScan {
apiKey = ${?CRYPTO_NOTIFY_BSCSCAN_API_KEY}
address = ${?CRYPTO_NOTIFY_BSCSCAN_ADDRESS}
etherScan {
apiKey = ${?CRYPTO_NOTIFY_ETHERSCAN_API_KEY}
address = ${?CRYPTO_NOTIFY_BSC_ADDRESS}
}
binance {
apiKey = ${?CRYPTO_NOTIFY_BINANCE_API_KEY}
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/commons/Configuration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Configuration {
lazy val telegramConfig: Option[TelegramConfig]
lazy val satangConfig: SatangConfig
lazy val akkaConfig: AkkaConfig
lazy val bscScanConfig: Option[BscScanConfig]
lazy val etherScanConfig: Option[EtherScanConfig]
lazy val mackerelConfig: Option[MackerelConfig]
lazy val binanceConfig: Option[BinanceConfig]
lazy val terraConfig: Option[TerraConfig]
Expand All @@ -28,7 +28,7 @@ class ConfigurationImpl extends Configuration {
private val lineSection = conf.getConfig("line")
private val satangSection = conf.getConfig("satang")
private val akkaSection = conf.getConfig("akka")
private val bscScanSection = conf.getConfig("bscScan")
private val etherScanSection = conf.getConfig("etherScan")
private val mackerelSection = conf.getConfig("mackerel")
private val binanceSection = conf.getConfig("binance")
private val terraSection = conf.getConfig("terra")
Expand All @@ -53,10 +53,10 @@ class ConfigurationImpl extends Configuration {
satangSection.getString("apiSecret"),
satangSection.getString("userId")
)
lazy val bscScanConfig: Option[BscScanConfig] = Try(
BscScanConfig(
bscScanSection.getString("apiKey"),
bscScanSection.getString("address")
lazy val etherScanConfig: Option[EtherScanConfig] = Try(
EtherScanConfig(
etherScanSection.getString("apiKey"),
etherScanSection.getString("address")
)
) match {
case Success(v) => Some(v)
Expand Down
4 changes: 3 additions & 1 deletion src/main/scala/commons/Constant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object Constant {

val bscRpcUrl = "https://bsc-dataseed.binance.org"
val satangUrl = "https://www.orbixtrade.com/api"
val bscScanUrl = "https://api.bscscan.com/api"
val etherScanUrl = "https://api.etherscan.io/v2/api"
val binanceUrl = "https://api.binance.com"
val terraUrl = "https://terra-classic-lcd.publicnode.com"
val twoPointOTerraUrl = "https://terra-lcd.publicnode.com"
Expand All @@ -17,6 +17,8 @@ object Constant {
val telegramUrl = "https://api.telegram.org"
val blockStreamUrl = "https://blockstream.info/api"

val bnbMainNetChainId = 56

enum EncryptionAlgorithm:
case HmacSHA512, HmacSHA256

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/di/DependencySetup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class DependencySetup(using system: ActorSystem[Nothing], context: ExecutionCont
given terraHelper: TerraHelper = TerraHelperImpl()
given satangService: SatangService =
SatangServiceImpl()
given bscScanService: BscScanService =
BscScanServiceImpl()
given etherScanService: EtherScanService =
EtherScanServiceImpl()
given binanceService: BinanceService =
BinanceServiceImpl()
given terraService: TerraService =
Expand Down
10 changes: 0 additions & 10 deletions src/main/scala/models/bscScan/BscScanResponse.scala

This file was deleted.

3 changes: 0 additions & 3 deletions src/main/scala/models/configuration/BscScanConfig.scala

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/scala/models/configuration/EtherScanConfig.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package models.configuration

final case class EtherScanConfig(apiKey: String, address: String)
10 changes: 10 additions & 0 deletions src/main/scala/models/etherScan/EtherScanResponse.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package models.etherScan

import io.circe.*
import io.circe.generic.semiauto.*

case class EtherScanResponse(status: Int, message: String, result: String)
object EtherScanResponse {
given Encoder[EtherScanResponse] = deriveEncoder[EtherScanResponse]
given Decoder[EtherScanResponse] = deriveDecoder[EtherScanResponse]
}
2 changes: 1 addition & 1 deletion src/main/scala/processors/NotifyProcessor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class NotifyProcessorImpl(using
val now = getFormattedNowDate("E dd MMM YYYY HH:mm:ss", isThai = false)
val message = userService.getBalanceMessage(
configuration.satangConfig.userId,
configuration.bscScanConfig.map(_.address),
configuration.etherScanConfig.map(_.address),
configuration.terraConfig.map(_.address),
configuration.bitcoinConfig.map(_.address),
notificationService.getProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,43 @@
package services.crypto

import akka.actor.typed.ActorSystem
import com.typesafe.scalalogging.LazyLogging
import commons.{Configuration, Constant, HttpClient, Logger}
import models.bscScan.BscScanResponse
import services.crypto.BscScanService
import models.etherScan.EtherScanResponse

import scala.concurrent.{ExecutionContext, Future}
import scala.math.BigDecimal.RoundingMode
import scala.math.pow

trait BscScanService {
trait EtherScanService {
def getBnbBalance(address: String): Future[Option[BigDecimal]]
def getTokenBalance(
contractAddress: String,
address: String
): Future[Option[BigDecimal]]
}

class BscScanServiceImpl(using configuration: Configuration, httpClient: HttpClient)(using
class EtherScanServiceImpl(using configuration: Configuration, httpClient: HttpClient)(using
system: ActorSystem[Nothing],
context: ExecutionContext,
logger: Logger
) extends BscScanService {
val baseUrl: String = Constant.bscScanUrl
val apiKey: String = configuration.bscScanConfig.map(_.apiKey).getOrElse("")
) extends EtherScanService {
val baseUrl: String = Constant.etherScanUrl
val apiKey: String = configuration.etherScanConfig.map(_.apiKey).getOrElse("")

override def getBnbBalance(address: String): Future[Option[BigDecimal]] = {
val url =
s"$baseUrl?module=account&action=balance&address=$address&apikey=$apiKey"
val response = httpClient.get[BscScanResponse](url)
s"$baseUrl?chainId=${Constant.bnbMainNetChainId}&module=account&action=balance&address=$address&apikey=$apiKey"
val response = httpClient.get[EtherScanResponse](url)

response.map {
case Left(err) =>
logger.error(s"getBnbBalance failed: $err")
None
case Right(x) =>
if (x.message == "OK") {
Some(convertFromWei(x.result))
Some(convertFromWei(BigInt(x.result)))
} else {
logger.error(s"getBnbBalance failed: ${x.message}")
logger.error(s"getBnbBalance failed: ${x.message}, ${x.result}")
None
}
}
Expand All @@ -50,18 +48,18 @@ class BscScanServiceImpl(using configuration: Configuration, httpClient: HttpCli
address: String
): Future[Option[BigDecimal]] = {
val url =
s"$baseUrl?module=account&action=tokenbalance&contractaddress=$contractAddress&address=$address&tag=latest&apikey=$apiKey"
val response = httpClient.get[BscScanResponse](url)
s"$baseUrl?chainId=${Constant.bnbMainNetChainId}&module=account&action=tokenbalance&contractaddress=$contractAddress&address=$address&tag=latest&apikey=$apiKey"
val response = httpClient.get[EtherScanResponse](url)

response.map {
case Left(err) =>
logger.error(s"getTokenBalance failed: $err")
None
case Right(x) =>
if (x.message == "OK") {
Some(convertFromWei(x.result))
Some(convertFromWei(BigInt(x.result)))
} else {
logger.error(s"getTokenBalance failed: ${x.message}")
logger.error(s"getTokenBalance failed: ${x.message}, ${x.result}")
None
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package services.crypto.contracts

import akka.actor.typed.ActorSystem
import com.typesafe.scalalogging.LazyLogging
import commons.{Configuration, Constant, Logger}
import contracts.pancake.{CakePool, VeCakePool}
import org.web3j.crypto.Credentials
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/services/user/UserService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ trait UserService {

class UserServiceImpl(using
satangService: SatangService,
bscScanService: BscScanService,
etherScanService: EtherScanService,
binanceService: BinanceService,
terraService: TerraService,
pancakeService: PancakeService,
Expand All @@ -44,11 +44,11 @@ class UserServiceImpl(using
val satangCurrentPricesF = satangService.getCryptoPrices
val binanceCurrentPricesF = binanceService.getLatestPrice
val extBnbAmountF = bscAddress
.map(bscScanService.getBnbBalance)
.map(etherScanService.getBnbBalance)
.getOrElse(Future.successful(None))
val extCakeAmountF = bscAddress
.map(address =>
bscScanService.getTokenBalance(
etherScanService.getTokenBalance(
Constant.CakeTokenContractAddress,
address
)
Expand Down
31 changes: 0 additions & 31 deletions src/test/scala/BscScanServiceSpec.scala

This file was deleted.