Skip to content

Commit

Permalink
Merge pull request #7 from blockfrost/feature/openapi-v0.1.27
Browse files Browse the repository at this point in the history
Update to openapi v0.1.27
  • Loading branch information
mmahut committed Sep 28, 2021
2 parents 5fe5800 + a981307 commit bc77ab3
Show file tree
Hide file tree
Showing 24 changed files with 270 additions and 137 deletions.
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -5,7 +5,7 @@
<br/>

<p align="center">A Scala SDK for <a href="https://blockfrost.io">Blockfrost.io</a> API.</p>
<p align="center">Compatible with Blockfrost.io OpenAPI version 0.1.25</p>
<p align="center">Compatible with Blockfrost.io OpenAPI version 0.1.27</p>
<p align="center">
<a href="#getting-started">Getting started</a> •
<a href="#installation">Installation</a> •
Expand Down Expand Up @@ -70,13 +70,13 @@ libraryDependencies += "com.softwaremill.sttp.client3" %% "async-http-client-bac
- NutlinkApi

#### Example application with blockfrost-sdk and Future sttp backend

```scala
import io.blockfrost.sdk.BlockfrostClient
import io.blockfrost.sdk.api.{AssetsApi, BlockApi, IpfsApi}
import io.blockfrost.sdk.common._
import io.blockfrost.sdk.effect.FuturePaginationSupport
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FuturePaginationSupport
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.json4s.jackson.Serialization
import org.json4s.{DefaultFormats, Formats}
import sttp.client3.SttpBackend
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/io/blockfrost/sdk/api/AddressesApi.scala
Expand Up @@ -45,6 +45,6 @@ object AddressesApi {
case class Transaction(tx_hash: String, tx_index: Int, block_height: Int)
case class Utxo(tx_hash: String, output_index: Int, amount: Seq[Amount], block: String, data_hash: Option[String])
case class AddressDetail(address: String, received_sum: Seq[Amount], sent_sum: Seq[Amount], tx_count: Int)
case class Address(address: String, amount: Seq[Amount], stake_address: Option[String], `type`: String)
case class Address(address: String, amount: Seq[Amount], stake_address: Option[String], `type`: String, script: Boolean)
case class Amount(unit: String, quantity: String)
}
4 changes: 2 additions & 2 deletions src/main/scala/io/blockfrost/sdk/api/AssetsApi.scala
Expand Up @@ -3,6 +3,7 @@ package io.blockfrost.sdk.api
import io.blockfrost.sdk.ApiClient
import io.blockfrost.sdk.api.AssetsApi._
import io.blockfrost.sdk.common.{Config, SortedPageRequest, SttpSupport}
import org.json4s.JsonAST.JValue
import org.json4s.{Formats, Serialization}
import sttp.client3.UriContext

Expand Down Expand Up @@ -47,15 +48,14 @@ trait AssetsApiImpl[F[_], P] extends AssetsApi[F, P] {
object AssetsApi {
case class AssetShort(asset: String, quantity: String)
case class Metadata(name: String, description: String, ticker: Option[String], url: Option[String], logo: Option[String], decimals: Option[Int])
case class OnchainMetadata(name: String, image: String)
case class Asset(asset: String,
policy_id: String,
asset_name: Option[String],
fingerprint: String,
quantity: String,
initial_mint_tx_hash: String,
mint_or_burn_count: Int,
onchain_metadata: Option[OnchainMetadata],
onchain_metadata: Option[Map[String, JValue]],
metadata: Option[Metadata])
case class AssetHistory(tx_hash: String, amount: String, action: String)
case class AssetTransaction(tx_hash: String, tx_index: Int, block_height: Int)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/io/blockfrost/sdk/api/NetworkApi.scala
Expand Up @@ -22,5 +22,5 @@ trait NetworkApiImpl[F[_], P] extends NetworkApi[F, P] {
object NetworkApi {
case class NetworkInfo(supply: Supply, stake: Stake)
case class Stake(live: String, active: String)
case class Supply(max: String, total: String, circulating: String)
case class Supply(max: String, total: String, circulating: String, locked: String)
}
36 changes: 36 additions & 0 deletions src/main/scala/io/blockfrost/sdk/api/ScriptsApi.scala
@@ -0,0 +1,36 @@
package io.blockfrost.sdk.api

import io.blockfrost.sdk.ApiClient
import io.blockfrost.sdk.api.ScriptsApi.{ScriptRedeemer, Script, ScriptHash}
import io.blockfrost.sdk.common.{Config, SortedPageRequest, SttpSupport}
import org.json4s.{Formats, Serialization}
import sttp.client3.UriContext

trait ScriptsApi[F[_], P] extends SttpSupport {
this: ApiClient[F, P] =>

def getListOfScripts(pageRequest: SortedPageRequest = SortedPageRequest())(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[ScriptHash]]]

def getSpecificScript(scriptHash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Script]]

def getSpecificScriptRedeemers(scriptHash: String, pageRequest: SortedPageRequest = SortedPageRequest())(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[ScriptRedeemer]]]
}

trait ScriptsApiImpl[F[_], P] extends ScriptsApi[F, P] {
this: ApiClient[F, P] =>

override def getListOfScripts(pageRequest: SortedPageRequest = SortedPageRequest())(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[ScriptHash]]] =
get(uri"$host/scripts", Some(pageRequest))

def getSpecificScript(scriptHash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Script]] =
get(uri"$host/scripts/$scriptHash")

override def getSpecificScriptRedeemers(scriptHash: String, pageRequest: SortedPageRequest = SortedPageRequest())(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[ScriptRedeemer]]] =
get(uri"$host/scripts/$scriptHash/redeemers", Some(pageRequest))
}

object ScriptsApi {
case class ScriptHash(script_hash: String)
case class Script(script_hash: String, `type`: String, serialised_size: Option[Double])
case class ScriptRedeemer(tx_hash: String, tx_index: Int, purpose: String, unit_mem: String, unit_steps: String, fee: String)
}
13 changes: 10 additions & 3 deletions src/main/scala/io/blockfrost/sdk/api/TransactionsApi.scala
Expand Up @@ -30,6 +30,8 @@ trait TransactionsApi[F[_], P] extends SttpSupport {

def getTransactionMetadataCbor(hash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[TransactionMetadataCbor]]]

def getTransactionRedeemers(hash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[TransactionRedeemer]]]

def submitTransaction(serializedTransaction: Array[Byte])(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[String]]
}

Expand Down Expand Up @@ -66,6 +68,9 @@ trait TransactionsApiImpl[F[_], P] extends TransactionsApi[F, P] {
override def getTransactionMetadataCbor(hash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[TransactionMetadataCbor]]] =
get(uri"$host/txs/$hash/metadata/cbor")

override def getTransactionRedeemers(hash: String)(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[Seq[TransactionRedeemer]]] =
get(uri"$host/txs/$hash/redeemers")

override def submitTransaction(serializedTransaction: Array[Byte])(implicit formats: Formats, serialization: Serialization, config: Config): F[ApiResponse[String]] =
post(uri"$host/tx/submit", serializedTransaction, "application/cbor")
}
Expand All @@ -90,10 +95,11 @@ object TransactionsApi {
stake_cert_count: Int,
pool_update_count: Int,
pool_retire_count: Int,
asset_mint_or_burn_count: Int)
asset_mint_or_burn_count: Int,
redeemer_count: Int)
case class Amount(unit: String, quantity: String)
case class Inputs(address: String, amount: List[Amount], tx_hash: String, output_index: Double)
case class Outputs(address: String, amount: List[Amount])
case class Inputs(address: String, amount: List[Amount], tx_hash: String, output_index: Double, data_hash: Option[String], collateral: Boolean)
case class Outputs(address: String, amount: List[Amount], data_hash: Option[String])
case class TransactionUtxos(hash: String, inputs: List[Inputs], outputs: List[Outputs])
case class AddressCertificate(cert_index: Double, address: String, registration: Boolean)
case class DelegationCertificate(cert_index: Double, address: String, pool_id: String, active_epoch: Int)
Expand Down Expand Up @@ -127,4 +133,5 @@ object TransactionsApi {
case class RetirementCertificate(cert_index: Double, pool_id: String, retiring_epoch: Int)
case class TransactionMetadata(label: String, json_metadata: JValue)
case class TransactionMetadataCbor(label: String, cbor_metadata: Option[String])
case class TransactionRedeemer(tx_index: Int, purpose: String, unit_mem: String, unit_steps: String, fee: String)
}
@@ -1,4 +1,4 @@
package io.blockfrost.sdk.effect
package io.blockfrost.sdk.util

import com.typesafe.scalalogging.LazyLogging
import io.blockfrost.sdk.common._
Expand Down
@@ -1,4 +1,4 @@
package io.blockfrost.sdk.effect
package io.blockfrost.sdk.util

import org.json4s.jackson.Serialization
import org.json4s.{Formats, Serialization}
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/AccountsApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.AccountsApi.{AccountAddress, Address, Asset}
import io.blockfrost.sdk.api.{AccountsApi, AccountsApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.{ApiError, ApiException, FutureResponseOps}
import io.blockfrost.sdk.util.FutureResponseConverter.{ApiError, ApiException, FutureResponseOps}
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
3 changes: 2 additions & 1 deletion src/test/scala/io/blockfrost/sdk/AddressesApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.AddressesApi._
import io.blockfrost.sdk.api.{AddressesApi, AddressesApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down Expand Up @@ -40,6 +40,7 @@ class AddressesApiSpec extends AsyncFlatSpec with Matchers with TestContextSuppo
body.stake_address.isDefined shouldBe true
body.`type` shouldBe "shelley"
body.amount.nonEmpty shouldBe true
body.script shouldBe false
succeed
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/AssetsApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.AssetsApi._
import io.blockfrost.sdk.api.{AssetsApi, AssetsApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/BlockApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.BlockApi.BlockContent
import io.blockfrost.sdk.api.{BlockApi, BlockApiImpl}
import io.blockfrost.sdk.common.{SortedPageRequest, UnsortedPageRequest}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/EpochApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.EpochsApi.{Epoch, EpochProtocolParameters}
import io.blockfrost.sdk.api.{EpochsApi, EpochsApiImpl}
import io.blockfrost.sdk.common.{SortedPageRequest, UnsortedPageRequest}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/HealthApiSpec.scala
Expand Up @@ -2,7 +2,7 @@ package io.blockfrost.sdk

import io.blockfrost.sdk.api.HealthApi.HealthStatus
import io.blockfrost.sdk.api.{HealthApi, HealthApiImpl}
import io.blockfrost.sdk.effect.FutureResponseConverter._
import io.blockfrost.sdk.util.FutureResponseConverter._
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/io/blockfrost/sdk/IpfsApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.IpfsApi.{IpfsObject, PinnedObject}
import io.blockfrost.sdk.api.{IpfsApi, IpfsApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down Expand Up @@ -31,7 +31,7 @@ class IpfsApiSpec extends AsyncFlatSpec with Matchers with TestContextSupport {
ipfsFileData <- ctx.api.getObject(ipfsObject.ipfs_hash)
_ <- ctx.api.removePinnedObject(ipfsObject.ipfs_hash).extract
} yield {
ipfsFileData.body.right.get.nonEmpty shouldBe true
ipfsFileData.body.map(_.nonEmpty) shouldBe Right(true)
succeed
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/LedgerApiSpec.scala
Expand Up @@ -2,7 +2,7 @@ package io.blockfrost.sdk

import io.blockfrost.sdk.api.LedgerApi.Genesis
import io.blockfrost.sdk.api.{LedgerApi, LedgerApiImpl}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/MetadataApiSpec.scala
Expand Up @@ -4,7 +4,7 @@ import io.blockfrost.sdk.TestContextSupport.RichString
import io.blockfrost.sdk.api.MetadataApi.{MetadataContentCbor, MetadataContentJson, MetadataLabel}
import io.blockfrost.sdk.api.{MetadataApi, MetadataApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.json4s.JsonAST.JValue
import org.json4s.{JObject, JString}
import org.scalatest.flatspec.AsyncFlatSpec
Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/io/blockfrost/sdk/MetricsApiSpec.scala
@@ -1,7 +1,7 @@
package io.blockfrost.sdk

import io.blockfrost.sdk.api.{MetricsApi, MetricsApiImpl}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down Expand Up @@ -41,7 +41,7 @@ class MetricsApiSpec extends AsyncFlatSpec with Matchers with TestContextSupport
.getEndpointUsageMetrics
.extract
.map(body => {
body.foreach(m => (m.time > 1 && m.calls >= 0 && s"${m.endpoint}".nonEmpty) shouldBe true)
body.foreach(m => (m.time >= 0 && m.calls >= 0 && m != null) shouldBe true)
succeed
})
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/scala/io/blockfrost/sdk/NetworkApiSpec.scala
Expand Up @@ -2,7 +2,7 @@ package io.blockfrost.sdk

import io.blockfrost.sdk.api.NetworkApi.{NetworkInfo, Stake, Supply}
import io.blockfrost.sdk.api.{NetworkApi, NetworkApiImpl}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand All @@ -27,12 +27,12 @@ class NetworkApiSpec extends AsyncFlatSpec with Matchers with TestContextSupport
Seq(testnetTestContext, mainnetTestContext).foreach { ctx =>
implicit val testCtx: TestContext = ctx

s"getProtocolParameters [${ctx.env}]" should "return EpochProtocolParameters" in genericTestContext[TestContext] { ctx =>
s"getProtocolParameters [${ctx.env}]" should "return NetworkInfo" in genericTestContext[TestContext] { ctx =>
ctx.api
.getNetworkInformation
.extract
.map(body => {
body should matchPattern { case NetworkInfo(Supply("45000000000000000", _, _), Stake(_, _)) => }
body should matchPattern { case NetworkInfo(Supply("45000000000000000", _, _, _), Stake(_, _)) => }
succeed
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/NutlinkApiSpec.scala
Expand Up @@ -2,7 +2,7 @@ package io.blockfrost.sdk

import io.blockfrost.sdk.api.NutlinkApi.{AddressMetadata, Ticker, TickerRecord}
import io.blockfrost.sdk.api.{NutlinkApi, NutlinkApiImpl}
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/PoolsApiSpec.scala
Expand Up @@ -3,7 +3,7 @@ package io.blockfrost.sdk
import io.blockfrost.sdk.api.PoolsApi._
import io.blockfrost.sdk.api.{PoolsApi, PoolsApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.effect.FutureResponseConverter.FutureResponseOps
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

Expand Down
61 changes: 61 additions & 0 deletions src/test/scala/io/blockfrost/sdk/ScriptApiSpec.scala
@@ -0,0 +1,61 @@
package io.blockfrost.sdk

import io.blockfrost.sdk.api.{ScriptsApi, ScriptsApiImpl}
import io.blockfrost.sdk.common.SortedPageRequest
import io.blockfrost.sdk.util.FutureResponseConverter.FutureResponseOps
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

import scala.concurrent.Future

class ScriptApiSpec extends AsyncFlatSpec with Matchers with TestContextSupport {
trait TestContext {
val api: ScriptsApi[Future, Any]
val env: String
val scriptHash: String
}

val testnetTestContext: TestContext = new TestContext {
val api: ScriptsApi[Future, Any] = new ScriptsApiImpl[Future, Any] with TestnetApiClient
val env: String = TestnetEnv
val scriptHash: String = "740b419cfe4fda7a90073fd4d4637cc81773e9108207254d7c9d3c75"
}

val mainnetTestContext: TestContext = new TestContext {
val api: ScriptsApi[Future, Any] = new ScriptsApiImpl[Future, Any] with MainnetApiClient
val env: String = MainnetEnv
val scriptHash: String = "f55dfaa24ac08874405206588859ec2804b722a51eb71651433135ef"
}

Seq(testnetTestContext, mainnetTestContext).foreach { ctx =>
implicit val testCtx: TestContext = ctx

s"getListOfScripts [${ctx.env}]" should "return sequence of ScriptHash" in genericTestContext[TestContext] { ctx =>
ctx.api
.getListOfScripts(SortedPageRequest(1))
.extract
.map(body => {
body.size shouldBe 1
body.head.script_hash.nonEmpty shouldBe true
succeed
})
}

s"getSpecificScript [${ctx.env}]" should "return Script" in genericTestContext[TestContext] { ctx =>
ctx.api
.getSpecificScript(ctx.scriptHash)
.extract
.map(body => {
body.script_hash shouldBe ctx.scriptHash
succeed
})
}

s"getSpecificScriptRedeemers [${ctx.env}]" should "return sequence of ScriptRedeemer" in genericTestContext[TestContext] { ctx =>
ctx.api
.getSpecificScriptRedeemers(ctx.scriptHash, SortedPageRequest(1))
.extract
.map(_ => succeed)
}
}
}
2 changes: 1 addition & 1 deletion src/test/scala/io/blockfrost/sdk/TestContextSupport.scala
Expand Up @@ -12,7 +12,7 @@ import scala.language.implicitConversions
trait TestContextSupport {
implicit val formats: Formats = org.json4s.DefaultFormats
implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization
implicit val sdkConfig: Config = Config(5, 500, 10000)
implicit val sdkConfig: Config = Config(5, 500, 30000)
val backend: SttpBackend[Future, Any] = AsyncHttpClientFutureBackend()
val TestnetEnv = "Testnet"
val MainnetEnv = "Mainnet"
Expand Down

0 comments on commit bc77ab3

Please sign in to comment.