Implemented buyPrice and sellPrice. Closes #1
This commit is contained in:
parent
c046cd7341
commit
bef4b2ee20
18 changed files with 152 additions and 98 deletions
|
@ -29,11 +29,11 @@ defaults_gradle: &defaults_gradle
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: build/reports/
|
path: build/reports/
|
||||||
jobs:
|
jobs:
|
||||||
build_gradle_jdk17:
|
build_gradle_jdk18:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/openjdk:17.0
|
- image: cimg/openjdk:18.0
|
||||||
|
|
||||||
<<: *defaults_gradle
|
<<: *defaults_gradle
|
||||||
|
|
||||||
|
@ -50,4 +50,4 @@ workflows:
|
||||||
gradle:
|
gradle:
|
||||||
jobs:
|
jobs:
|
||||||
- build_gradle_jdk11
|
- build_gradle_jdk11
|
||||||
- build_gradle_jdk17
|
- build_gradle_jdk18
|
||||||
|
|
2
.github/workflows/gradle.yml
vendored
2
.github/workflows/gradle.yml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
java-version: [ 11, 17 ]
|
java-version: [ 11, 18 ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
5
.idea/jarRepositories.xml
generated
5
.idea/jarRepositories.xml
generated
|
@ -21,5 +21,10 @@
|
||||||
<option name="name" value="maven" />
|
<option name="name" value="maven" />
|
||||||
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
|
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="MavenLocal" />
|
||||||
|
<option name="name" value="MavenLocal" />
|
||||||
|
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
6
.idea/kotlinc.xml
generated
Normal file
6
.idea/kotlinc.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="1.7.10" />
|
||||||
|
</component>
|
||||||
|
</project>
|
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
|
@ -1,5 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK" />
|
<component name="FrameworkDetectionExcludesConfiguration">
|
||||||
|
<file type="web" url="file://$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="18" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
10
.idea/runConfigurations.xml
generated
10
.idea/runConfigurations.xml
generated
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
41
README.md
41
README.md
|
@ -1,10 +1,10 @@
|
||||||
[](https://opensource.org/licenses/BSD-3-Clause) [](https://github.com/ethauvin/cryptoprice/releases/latest) [](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22) <!-- [](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/cryptoprice/) -->
|
[](https://opensource.org/licenses/BSD-3-Clause) [](https://github.com/ethauvin/cryptoprice/releases/latest) <!-- [](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22) --> [](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/cryptoprice/)
|
||||||
|
|
||||||
[](https://snyk.io/test/github/ethauvin/cryptoprice?targetFile=pom.xml) [](https://sonarcloud.io/dashboard?id=ethauvin_cryptoprice) [](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml) [](https://circleci.com/gh/ethauvin/cryptoprice/tree/master)
|
[](https://snyk.io/test/github/ethauvin/cryptoprice?targetFile=pom.xml) [](https://sonarcloud.io/dashboard?id=ethauvin_cryptoprice) [](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml) [](https://circleci.com/gh/ethauvin/cryptoprice/tree/master)
|
||||||
|
|
||||||
# Retrieve cryptocurrencies current prices
|
# Retrieve cryptocurrencies current (buy, sell or spot) prices
|
||||||
|
|
||||||
A simple Kotlin/Java/Android implementation of the spot price [Coinbase Public API](https://developers.coinbase.com/api/v2#get-spot-price).
|
A simple Kotlin/Java/Android implementation of the prices [Coinbase Public API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices).
|
||||||
|
|
||||||
## Examples (TL;DR)
|
## Examples (TL;DR)
|
||||||
|
|
||||||
|
@ -16,7 +16,10 @@ import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
||||||
val btc = spotPrice("BTC") // Bitcoin
|
val btc = spotPrice("BTC") // Bitcoin
|
||||||
println(btc.amount)
|
println(btc.amount)
|
||||||
|
|
||||||
val eth = spotPrice("ETH", "EUR") // Ethereum in Euros
|
val eth = sellPrice("ETH", "EUR") // Ethereum in Euro
|
||||||
|
println(eth.amount)
|
||||||
|
|
||||||
|
val eth = buyPrice("LTC", "GBP") // Litecoin in Pound sterling
|
||||||
println(eth.amount)
|
println(eth.amount)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -28,21 +31,31 @@ To use with [Gradle](https://gradle.org/), include the following dependency in y
|
||||||
|
|
||||||
```gradle
|
```gradle
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("net.thauvin.erik:cryptoprice:0.9.0")
|
implementation("net.thauvin.erik:cryptoprice:1.0.0-SNAPSHOT")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/artifact/net.thauvin.erik/cryptoprice/0.9.0/jar).
|
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22).
|
||||||
|
|
||||||
### Spot Price
|
### Prices
|
||||||
|
|
||||||
The `spotPrice` function defines the following parameters:
|
The `spotPrice`, `buyPrice` and `sellPrice` functions define the following parameters:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
spotPrice(
|
spotPrice(
|
||||||
base: String, // Required
|
base: String, // Required
|
||||||
currency: String = "USD",
|
currency: String = "USD",
|
||||||
date: LocalDate? = null,
|
date: LocalDate? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
buyPrice(
|
||||||
|
base: String, // Required
|
||||||
|
currency: String = "USD"
|
||||||
|
)
|
||||||
|
|
||||||
|
sellPrice(
|
||||||
|
base: String, // Required
|
||||||
|
currency: String = "USD"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -57,7 +70,7 @@ A `CryptoPrice` object is returned defined as follows:
|
||||||
```kotlin
|
```kotlin
|
||||||
CryptoPrice(val base: String, val currency: String, val amount: BigDecimal)
|
CryptoPrice(val base: String, val currency: String, val amount: BigDecimal)
|
||||||
```
|
```
|
||||||
The parameter names match the [Coinbase API](https://developers.coinbase.com/api/v2#get-spot-price).
|
The parameter names match the [Coinbase API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices).
|
||||||
|
|
||||||
#### Format
|
#### Format
|
||||||
|
|
||||||
|
@ -86,7 +99,7 @@ println(price.toJson())
|
||||||
{"data":{"base":"BTC","currency":"USD","amount":"34567.89"}}
|
{"data":{"base":"BTC","currency":"USD","amount":"34567.89"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `data` object matches the [Coinbase API](https://developers.coinbase.com/api/v2#get-spot-price). To specify a different (or no) key, use:
|
The `data` object matches the [Coinbase API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price). To specify a different (or no) key, use:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
println(price.toJson("bitcoin"))
|
println(price.toJson("bitcoin"))
|
||||||
|
@ -109,15 +122,15 @@ val eth = """{"ether":{"base":"ETH","currency":"USD","amount":"2345.67"}}""".toP
|
||||||
|
|
||||||
### Extending
|
### Extending
|
||||||
|
|
||||||
A generic `apiCall()` function is available to access other [API data endpoints](https://developers.coinbase.com/api/v2#data-endpoints). For example to retrieve the current [buy price](https://developers.coinbase.com/api/v2#get-buy-price) of a cryptocurrency:
|
A generic `apiCall()` function is available to access other [data API endpoints](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies). For example to retrieve the [exchange rates](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates):
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
apiCall(paths = listOf("prices", "BTC-USD", "buy"), params = emptyMap())
|
apiCall(listOf("exchange-rates"), mapOf("currency" to "usd"))
|
||||||
```
|
```
|
||||||
will return something like:
|
will return something like:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"data":{"base":"BTC","currency":"USD","amount":"34554.32"}}
|
{"data":{"currency":"BTC","rates":{"AED":"36.73","AFN":"589.50",...}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [examples](https://github.com/ethauvin/cryptoprice/blob/master/examples/) for more details.
|
See the [examples](https://github.com/ethauvin/cryptoprice/blob/master/examples/) for more details.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
image: openjdk:17
|
image: openjdk:18
|
||||||
|
|
||||||
pipelines:
|
pipelines:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -8,21 +8,21 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||||
plugins {
|
plugins {
|
||||||
id("application")
|
id("application")
|
||||||
id("com.github.ben-manes.versions") version "0.42.0"
|
id("com.github.ben-manes.versions") version "0.42.0"
|
||||||
id("io.gitlab.arturbosch.detekt") version "1.20.0"
|
id("io.gitlab.arturbosch.detekt") version "1.21.0"
|
||||||
id("java")
|
id("java")
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
id("org.jetbrains.dokka") version "1.6.21"
|
id("org.jetbrains.dokka") version "1.7.10"
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.5.0"
|
id("org.jetbrains.kotlinx.kover") version "0.6.0"
|
||||||
id("org.sonarqube") version "3.3"
|
id("org.sonarqube") version "3.4.0.2513"
|
||||||
id("signing")
|
id("signing")
|
||||||
kotlin("jvm") version "1.6.21"
|
kotlin("jvm") version "1.7.10"
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultTasks(ApplicationPlugin.TASK_RUN_NAME)
|
defaultTasks(ApplicationPlugin.TASK_RUN_NAME)
|
||||||
|
|
||||||
description = "Retrieve cryptocurrencies current prices."
|
description = "Retrieve cryptocurrencies prices."
|
||||||
group = "net.thauvin.erik"
|
group = "net.thauvin.erik"
|
||||||
version = "0.9.0"
|
version = "1.0.0-SNAPSHOT"
|
||||||
|
|
||||||
val deployDir = "deploy"
|
val deployDir = "deploy"
|
||||||
val gitHub = "ethauvin/$name"
|
val gitHub = "ethauvin/$name"
|
||||||
|
@ -43,9 +43,9 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(platform(kotlin("bom")))
|
implementation(platform(kotlin("bom")))
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.9.3")
|
implementation("com.squareup.okhttp3:okhttp:4.10.0")
|
||||||
implementation("org.json:json:20220320")
|
implementation("org.json:json:20220320")
|
||||||
|
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
@ -71,7 +71,7 @@ sonarqube {
|
||||||
property("sonar.organization", "ethauvin-github")
|
property("sonar.organization", "ethauvin-github")
|
||||||
property("sonar.host.url", "https://sonarcloud.io")
|
property("sonar.host.url", "https://sonarcloud.io")
|
||||||
property("sonar.sourceEncoding", "UTF-8")
|
property("sonar.sourceEncoding", "UTF-8")
|
||||||
property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/report.xml")
|
property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/xml/report.xml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ tasks {
|
||||||
register("deploy") {
|
register("deploy") {
|
||||||
description = "Copies all needed files to the $deployDir directory."
|
description = "Copies all needed files to the $deployDir directory."
|
||||||
group = PublishingPlugin.PUBLISH_TASK_GROUP
|
group = PublishingPlugin.PUBLISH_TASK_GROUP
|
||||||
dependsOn(build, jar)
|
dependsOn(clean, build, jar)
|
||||||
outputs.dir(deployDir)
|
outputs.dir(deployDir)
|
||||||
inputs.files(copyToDeploy)
|
inputs.files(copyToDeploy)
|
||||||
mustRunAfter(clean)
|
mustRunAfter(clean)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
plugins {
|
plugins {
|
||||||
id("application")
|
id("application")
|
||||||
id("com.github.ben-manes.versions") version "0.42.0"
|
id("com.github.ben-manes.versions") version "0.42.0"
|
||||||
kotlin("jvm") version "1.6.21"
|
kotlin("jvm") version "1.7.10"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ./gradlew run
|
// ./gradlew run
|
||||||
|
@ -20,7 +20,8 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("net.thauvin.erik:cryptoprice:0.9.0")
|
implementation("net.thauvin.erik:cryptoprice:1.0.0-SNAPSHOT")
|
||||||
|
implementation("org.json:json:20220320")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -2,13 +2,14 @@ package com.example;
|
||||||
|
|
||||||
import net.thauvin.erik.crypto.CryptoException;
|
import net.thauvin.erik.crypto.CryptoException;
|
||||||
import net.thauvin.erik.crypto.CryptoPrice;
|
import net.thauvin.erik.crypto.CryptoPrice;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CryptoPriceSample {
|
public class CryptoPriceSample {
|
||||||
public static void main(String[] args) {
|
public static void main(final String[] args) {
|
||||||
try {
|
try {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
final CryptoPrice price;
|
final CryptoPrice price;
|
||||||
|
@ -21,27 +22,27 @@ public class CryptoPriceSample {
|
||||||
+ price.getCurrency());
|
+ price.getCurrency());
|
||||||
} else {
|
} else {
|
||||||
// Get current Bitcoin spot price.
|
// Get current Bitcoin spot price.
|
||||||
final CryptoPrice price = CryptoPrice.spotPrice("BTC");
|
final var price = CryptoPrice.spotPrice("BTC");
|
||||||
System.out.println("The current Bitcoin price is " + price.toCurrency());
|
System.out.println("The current Bitcoin price is " + price.toCurrency());
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
// Get current Ethereum spot price in Pound sterling.
|
// Get current Ethereum buy price in Pound sterling.
|
||||||
final CryptoPrice gbpPrice = CryptoPrice.spotPrice("ETH", "GBP");
|
final var gbpPrice = CryptoPrice.buyPrice("ETH", "GBP");
|
||||||
System.out.println("The current Ethereum price is " + gbpPrice.toCurrency());
|
System.out.println("The current Ethereum buy price is " + gbpPrice.toCurrency());
|
||||||
|
|
||||||
// Get current Litecoin spot price in Euros.
|
// Get current Litecoin sell price in Euros.
|
||||||
final CryptoPrice euroPrice = CryptoPrice.spotPrice("LTC", "EUR");
|
final var euroPrice = CryptoPrice.sellPrice("LTC", "EUR");
|
||||||
System.out.println("The current Litecoin price is " + euroPrice.toCurrency());
|
System.out.println("The current Litecoin sell price is " + euroPrice.toCurrency());
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
// Get current Bitcoin buy price using API.
|
// Get exchange rate using API.
|
||||||
// See: https://developers.coinbase.com/api/v2#get-buy-price
|
// See: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates
|
||||||
final CryptoPrice buyPrice = CryptoPrice
|
final var response = CryptoPrice.apiCall(List.of("exchange-rates"),
|
||||||
.toPrice(CryptoPrice.apiCall(List.of("prices", "BTC-USD", "buy"), Collections.emptyMap()));
|
Collections.singletonMap("currency", "USD"));
|
||||||
System.out.println("The current " + buyPrice.getBase() + " buy price is " + buyPrice.getAmount()
|
final var rates = new JSONObject(response).getJSONObject("data").getJSONObject("rates");
|
||||||
+ " in " + buyPrice.getCurrency());
|
System.out.printf("The USD-EUR exchange rate is: %s%n", rates.getString("EUR"));
|
||||||
}
|
}
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
System.err.println("HTTP Status Code: " + e.getStatusCode());
|
System.err.println("HTTP Status Code: " + e.getStatusCode());
|
||||||
|
|
|
@ -2,9 +2,10 @@ package com.example
|
||||||
|
|
||||||
import net.thauvin.erik.crypto.CryptoException
|
import net.thauvin.erik.crypto.CryptoException
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
|
||||||
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.buyPrice
|
||||||
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.sellPrice
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice
|
import org.json.JSONObject
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
@ -19,20 +20,21 @@ fun main(args: Array<String>) {
|
||||||
|
|
||||||
println()
|
println()
|
||||||
|
|
||||||
// Get current Ethereum spot price in Pound sterling.
|
// Get current Ethereum sell price in Pound sterling.
|
||||||
val gbpPrice = spotPrice("ETH", "GBP")
|
val gbpPrice = sellPrice("ETH", "GBP")
|
||||||
println("The current Ethereum price is ${gbpPrice.toCurrency()}")
|
println("The current Ethereum sell price is ${gbpPrice.toCurrency()}")
|
||||||
|
|
||||||
// Get current Litecoin spot price in Euro.
|
// Get current Litecoin buy price in Euro.
|
||||||
val euroPrice = spotPrice("LTC", "EUR")
|
val euroPrice = buyPrice("LTC", "EUR")
|
||||||
println("The current Litecoin price is ${euroPrice.toCurrency()}")
|
println("The current Litecoin buy price is ${euroPrice.toCurrency()}")
|
||||||
|
|
||||||
println()
|
println()
|
||||||
|
|
||||||
// Get current Bitcoin buy price using API.
|
// Get exchange rate using API.
|
||||||
// See: https://developers.coinbase.com/api/v2#get-buy-price
|
// See: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates
|
||||||
val buyPrice = apiCall(listOf("prices", "BTC-USD", "buy"), emptyMap()).toPrice()
|
val response = apiCall(listOf("exchange-rates"), mapOf("currency" to "usd"))
|
||||||
println("The current ${buyPrice.base} buy price is ${buyPrice.amount} in ${buyPrice.currency}")
|
val rates = JSONObject(response).getJSONObject("data").getJSONObject("rates")
|
||||||
|
println("The USD-EUR exchange rate is: ${rates.getString("EUR")}")
|
||||||
}
|
}
|
||||||
} catch (e: CryptoException) {
|
} catch (e: CryptoException) {
|
||||||
System.err.println("HTTP Status Code: ${e.statusCode}")
|
System.err.println("HTTP Status Code: ${e.statusCode}")
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
12
pom.xml
12
pom.xml
|
@ -8,9 +8,9 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.thauvin.erik</groupId>
|
<groupId>net.thauvin.erik</groupId>
|
||||||
<artifactId>cryptoprice</artifactId>
|
<artifactId>cryptoprice</artifactId>
|
||||||
<version>0.9.0</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
<name>cryptoprice</name>
|
<name>cryptoprice</name>
|
||||||
<description>Retrieve cryptocurrencies current prices.</description>
|
<description>Retrieve cryptocurrencies prices.</description>
|
||||||
<url>https://github.com/ethauvin/cryptoprice</url>
|
<url>https://github.com/ethauvin/cryptoprice</url>
|
||||||
<licenses>
|
<licenses>
|
||||||
<license>
|
<license>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-bom</artifactId>
|
<artifactId>kotlin-bom</artifactId>
|
||||||
<version>1.6.10</version>
|
<version>1.7.10</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -50,19 +50,19 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
<version>1.6.10</version>
|
<version>1.7.10</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
<version>4.9.3</version>
|
<version>4.10.0</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>20211205</version>
|
<version>20220320</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
@ -42,11 +42,10 @@ import java.io.IOException
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.text.NumberFormat
|
import java.text.NumberFormat
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.Currency
|
import java.util.*
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves and holds a cryptocurrency current spot price.
|
* Retrieves and holds a cryptocurrency price.
|
||||||
*
|
*
|
||||||
* @constructor Constructs a new [CryptoPrice] object.
|
* @constructor Constructs a new [CryptoPrice] object.
|
||||||
*
|
*
|
||||||
|
@ -116,6 +115,19 @@ open class CryptoPrice(val base: String, val currency: String, val amount: BigDe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the buy price.
|
||||||
|
*
|
||||||
|
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
|
||||||
|
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
@Throws(CryptoException::class, IOException::class)
|
||||||
|
fun buyPrice(base: String, currency: String = "USD"): CryptoPrice {
|
||||||
|
return apiCall(listOf("prices", "$base-$currency", "buy"), emptyMap()).toPrice()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the current prices for the specified cryptocurrencies.
|
* Prints the current prices for the specified cryptocurrencies.
|
||||||
*/
|
*/
|
||||||
|
@ -129,7 +141,20 @@ open class CryptoPrice(val base: String, val currency: String, val amount: BigDe
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current spot price.
|
* Retrieves the sell price.
|
||||||
|
*
|
||||||
|
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
|
||||||
|
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
@Throws(CryptoException::class, IOException::class)
|
||||||
|
fun sellPrice(base: String, currency: String = "USD"): CryptoPrice {
|
||||||
|
return apiCall(listOf("prices", "$base-$currency", "sell"), emptyMap()).toPrice()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the spot price.
|
||||||
*
|
*
|
||||||
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
|
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
|
||||||
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
|
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
|
||||||
|
|
|
@ -33,11 +33,13 @@
|
||||||
package net.thauvin.erik.crypto
|
package net.thauvin.erik.crypto
|
||||||
|
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
|
||||||
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.buyPrice
|
||||||
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.sellPrice
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
|
||||||
import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice
|
import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.Locale
|
import java.util.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
@ -54,29 +56,35 @@ class CryptoPriceTest {
|
||||||
@Test
|
@Test
|
||||||
@Throws(CryptoException::class)
|
@Throws(CryptoException::class)
|
||||||
fun testBitcoinPrice() {
|
fun testBitcoinPrice() {
|
||||||
val price = spotPrice("BTC")
|
val prices = listOf(spotPrice("BTC"), buyPrice("BTC"), sellPrice("BTC"))
|
||||||
|
for (price in prices) {
|
||||||
assertEquals("BTC", price.base, "BTC")
|
assertEquals("BTC", price.base, "BTC")
|
||||||
assertEquals("USD", price.currency, "is USD")
|
assertEquals("USD", price.currency, "is USD")
|
||||||
assertTrue(price.amount.signum() > 0, "BTC > 0")
|
assertTrue(price.amount.signum() > 0, "BTC > 0")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(CryptoException::class)
|
@Throws(CryptoException::class)
|
||||||
fun testEtherPrice() {
|
fun testEtherPrice() {
|
||||||
val price = spotPrice("ETH", "EUR")
|
val prices = listOf(spotPrice("ETH", "EUR"), buyPrice("ETH", "EUR"), sellPrice("ETH", "EUR"))
|
||||||
|
for (price in prices) {
|
||||||
assertEquals("ETH", price.base, "ETH")
|
assertEquals("ETH", price.base, "ETH")
|
||||||
assertEquals("EUR", price.currency, "is EUR")
|
assertEquals("EUR", price.currency, "is EUR")
|
||||||
assertTrue(price.amount.signum() > 0, "ETH > 0")
|
assertTrue(price.amount.signum() > 0, "ETH > 0")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(CryptoException::class)
|
@Throws(CryptoException::class)
|
||||||
fun testLitecoinPrice() {
|
fun testLitecoinPrice() {
|
||||||
val price = spotPrice("LTC", "GBP")
|
val prices = listOf(spotPrice("LTC", "GBP"), buyPrice("LTC", "GBP"), sellPrice("LTC", "GBP"))
|
||||||
|
for (price in prices) {
|
||||||
assertEquals("LTC", price.base, "LTC")
|
assertEquals("LTC", price.base, "LTC")
|
||||||
assertEquals("GBP", price.currency, "is GBP")
|
assertEquals("GBP", price.currency, "is GBP")
|
||||||
assertTrue(price.amount.signum() > 0, "LTC > 0")
|
assertTrue(price.amount.signum() > 0, "LTC > 0")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(CryptoException::class)
|
@Throws(CryptoException::class)
|
||||||
|
@ -102,7 +110,7 @@ class CryptoPriceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(CryptoException::class)
|
@Throws(CryptoException::class)
|
||||||
fun testSpotPrice() {
|
fun testPrices() {
|
||||||
assertFailsWith(
|
assertFailsWith(
|
||||||
message = "FOO did not fail",
|
message = "FOO did not fail",
|
||||||
exceptionClass = CryptoException::class,
|
exceptionClass = CryptoException::class,
|
||||||
|
@ -112,11 +120,11 @@ class CryptoPriceTest {
|
||||||
assertFailsWith(
|
assertFailsWith(
|
||||||
message = "BAR did not fail",
|
message = "BAR did not fail",
|
||||||
exceptionClass = CryptoException::class,
|
exceptionClass = CryptoException::class,
|
||||||
block = { spotPrice("BTC", "BAR") }
|
block = { buyPrice("BTC", "BAR") }
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
spotPrice("FOOBAR")
|
sellPrice("FOOBAR")
|
||||||
} catch (e: CryptoException) {
|
} catch (e: CryptoException) {
|
||||||
assertNotEquals(400, e.statusCode, "FOOBAR status code is not 400")
|
assertNotEquals(400, e.statusCode, "FOOBAR status code is not 400")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue