diff --git a/server/app/com/xsn/explorer/models/TPoSContract.scala b/server/app/com/xsn/explorer/models/TPoSContract.scala index ae8f002..292b0fd 100644 --- a/server/app/com/xsn/explorer/models/TPoSContract.scala +++ b/server/app/com/xsn/explorer/models/TPoSContract.scala @@ -2,6 +2,7 @@ package com.xsn.explorer.models import com.xsn.explorer.models.values.{Address, TransactionId} import enumeratum._ +import play.api.libs.json.{Json, Writes} import scala.util.Try @@ -65,4 +66,16 @@ object TPoSContract { final case object Active extends State("ACTIVE") final case object Closed extends State("CLOSED") } + + implicit val writes: Writes[TPoSContract] = (obj: TPoSContract) => { + Json.obj( + "txid" -> obj.id.txid, + "index" -> obj.id.index, + "owner" -> obj.details.owner, + "merchant" -> obj.details.merchant, + "merchantCommission" -> obj.details.merchantCommission.int, + "time" -> obj.time, + "state" -> obj.state.entryName + ) + } } diff --git a/server/app/com/xsn/explorer/services/TPoSContractService.scala b/server/app/com/xsn/explorer/services/TPoSContractService.scala new file mode 100644 index 0000000..38f3d33 --- /dev/null +++ b/server/app/com/xsn/explorer/services/TPoSContractService.scala @@ -0,0 +1,25 @@ +package com.xsn.explorer.services + +import com.alexitc.playsonify.core.FutureApplicationResult +import com.alexitc.playsonify.core.FutureOr.Implicits.{FutureOps, OrOps} +import com.xsn.explorer.data.async.TPoSContractFutureDataHandler +import com.xsn.explorer.models.{TPoSContract, WrappedResult} +import com.xsn.explorer.services.validators.AddressValidator +import javax.inject.Inject + +import scala.concurrent.ExecutionContext + +class TPoSContractService @Inject() ( + addressValidator: AddressValidator, + tposContractFutureDataHandler: TPoSContractFutureDataHandler)( + implicit ec: ExecutionContext) { + + def getBy(addressString: String): FutureApplicationResult[WrappedResult[List[TPoSContract]]] = { + val result = for { + address <- addressValidator.validate(addressString).toFutureOr + contracts <- tposContractFutureDataHandler.getBy(address).toFutureOr + } yield WrappedResult(contracts) + + result.toFuture + } +} diff --git a/server/app/com/xsn/explorer/services/validators/AddressValidator.scala b/server/app/com/xsn/explorer/services/validators/AddressValidator.scala new file mode 100644 index 0000000..2c43c7f --- /dev/null +++ b/server/app/com/xsn/explorer/services/validators/AddressValidator.scala @@ -0,0 +1,14 @@ +package com.xsn.explorer.services.validators + +import com.alexitc.playsonify.core.ApplicationResult +import com.xsn.explorer.errors.AddressFormatError +import com.xsn.explorer.models.values.Address +import org.scalactic.{One, Or} + +class AddressValidator { + + def validate(string: String): ApplicationResult[Address] = { + val maybe = Address.from(string) + Or.from(maybe, One(AddressFormatError)) + } +} diff --git a/server/app/controllers/AddressesController.scala b/server/app/controllers/AddressesController.scala index 43e78ed..bb6c6c6 100644 --- a/server/app/controllers/AddressesController.scala +++ b/server/app/controllers/AddressesController.scala @@ -4,7 +4,7 @@ import com.alexitc.playsonify.models.ordering.OrderingQuery import com.alexitc.playsonify.models.pagination.{Limit, Offset, PaginatedQuery} import com.xsn.explorer.models.LightWalletTransaction import com.xsn.explorer.models.persisted.Transaction -import com.xsn.explorer.services.{AddressService, TransactionService} +import com.xsn.explorer.services.{AddressService, TPoSContractService, TransactionService} import com.xsn.explorer.util.Extensions.BigDecimalExt import controllers.common.{Codecs, MyJsonController, MyJsonControllerComponents} import javax.inject.Inject @@ -13,6 +13,7 @@ import play.api.libs.json._ class AddressesController @Inject() ( addressService: AddressService, transactionService: TransactionService, + tposContractService: TPoSContractService, cc: MyJsonControllerComponents) extends MyJsonController(cc) { @@ -60,6 +61,10 @@ class AddressesController @Inject() ( def getUnspentOutputs(address: String) = public { _ => addressService.getUnspentOutputs(address) } + + def getTPoSContracts(address: String) = public { _ => + tposContractService.getBy(address) + } } object AddressesController { diff --git a/server/conf/routes b/server/conf/routes index 150a893..28ccbaa 100644 --- a/server/conf/routes +++ b/server/conf/routes @@ -12,6 +12,7 @@ POST /transactions controllers.TransactionsController.sendRawTrans GET /addresses/:address controllers.AddressesController.getBy(address: String) GET /addresses/:address/transactions controllers.AddressesController.getTransactions(address: String, offset: Int ?= 0, limit: Int ?= 10, orderBy: String ?= "") +GET /addresses/:address/tposcontracts controllers.AddressesController.getTPoSContracts(address: String) GET /v2/addresses/:address/transactions controllers.AddressesController.getLightWalletTransactions(address: String, limit: Int ?= 10, lastSeenTxid: Option[String], order: String ?= "desc") GET /addresses/:address/utxos controllers.AddressesController.getUnspentOutputs(address: String)