From 1dbfe0347664a1dc9f99eb985409e465dd0b7d10 Mon Sep 17 00:00:00 2001 From: Stefano Franz Date: Fri, 5 Jun 2020 10:17:56 +0100 Subject: [PATCH 1/2] keep --- contracts/build.gradle | 10 +- .../corda/lib/tokens/money/DigitalCurrency.kt | 27 ----- .../r3/corda/lib/tokens/money/FiatCurrency.kt | 22 ---- .../r3/corda/lib/tokens/money/Utilities.kt | 107 ------------------ workflows/build.gradle | 19 +++- .../lib/tokens/workflows/OwnerMigration.kt | 5 - .../money/CurrencyAccessFromJavaTest.java | 0 7 files changed, 25 insertions(+), 165 deletions(-) delete mode 100644 modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt delete mode 100644 modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt delete mode 100644 modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt rename {modules/money => workflows}/src/test/java/com/r3/corda/lib/tokens/money/CurrencyAccessFromJavaTest.java (100%) diff --git a/contracts/build.gradle b/contracts/build.gradle index 6ea16d86..58de5f53 100644 --- a/contracts/build.gradle +++ b/contracts/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'kotlin-jpa' apply plugin: 'net.corda.plugins.cordapp' if (!(corda_release_version in ['4.1'])) { -apply from: "${rootProject.projectDir}/deterministic.gradle" + apply from: "${rootProject.projectDir}/deterministic.gradle" } sourceSets { @@ -23,7 +23,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Corda dependencies. - cordaCompile ("$corda_release_group:corda-core:$corda_release_version"){ + cordaCompile("$corda_release_group:corda-core:$corda_release_version") { changing = true } @@ -54,4 +54,10 @@ cordapp { jar { baseName "tokens-contracts" +} + +test { + beforeTest { + throw new IllegalStateException() + } } \ No newline at end of file diff --git a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt b/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt deleted file mode 100644 index 4eafefd4..00000000 --- a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.r3.corda.lib.tokens.money - -import com.r3.corda.lib.tokens.contracts.types.TokenType -import java.util.* - -/** - * A representation of digital money. This implementation somewhat mirrors that of [Currency]. - * - * Note that the primary constructor only exists for simple and convenient access from Java code. - * - * @param currencyCode The currency code that represents the TokenType which the developer wishes to instantiate. - */ -class DigitalCurrency { - companion object { - private val registry = mapOf( - Pair("XRP", TokenType("Ripple", 6)), - Pair("BTC", TokenType("Bitcoin", 8)), - Pair("ETH", TokenType("Ethereum", 18)), - Pair("DOGE", TokenType("Dogecoin", 8)) - ) - - @JvmStatic - fun getInstance(currencyCode: String): TokenType { - return registry[currencyCode] ?: throw IllegalArgumentException("$currencyCode doesn't exist.") - } - } -} \ No newline at end of file diff --git a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt b/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt deleted file mode 100644 index 87e0faed..00000000 --- a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.r3.corda.lib.tokens.money - -import com.r3.corda.lib.tokens.contracts.types.TokenType -import java.util.* - -/** - * This class is used to return a [TokenType] with the required currency code and fraction digits for fiat currencies. - * - * Note that the primary constructor only exists for simple and convenient access from Java code. - * - * @param currencyCode The currency code that represents the TokenType which the developer wishes to instantiate. - */ -class FiatCurrency { - companion object { - // Uses the java money registry. - @JvmStatic - fun getInstance(currencyCode: String): TokenType { - val currency = Currency.getInstance(currencyCode) - return TokenType(currency.currencyCode, currency.defaultFractionDigits) - } - } -} diff --git a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt b/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt deleted file mode 100644 index fb0b363e..00000000 --- a/modules/money/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt +++ /dev/null @@ -1,107 +0,0 @@ -@file:JvmName("MoneyUtilities") -package com.r3.corda.lib.tokens.money - -import com.r3.corda.lib.tokens.contracts.types.TokenType -import com.r3.corda.lib.tokens.contracts.utilities.amount -import net.corda.core.contracts.Amount - -/** Helpers for creating amounts of fixed token definitions. */ - -// Sterling. -val GBP = FiatCurrency.getInstance("GBP") - -fun GBP(amount: Int): Amount = amount(amount, GBP) -fun GBP(amount: Long): Amount = amount(amount, GBP) -fun GBP(amount: Double): Amount = amount(amount, GBP) -val Int.GBP: Amount get() = GBP(this) -val Long.GBP: Amount get() = GBP(this) -val Double.GBP: Amount get() = GBP(this) - -// US Dollar. -val USD = FiatCurrency.getInstance("USD") - -fun USD(amount: Int): Amount = amount(amount, USD) -fun USD(amount: Long): Amount = amount(amount, USD) -fun USD(amount: Double): Amount = amount(amount, USD) -val Int.USD: Amount get() = USD(this) -val Long.USD: Amount get() = USD(this) -val Double.USD: Amount get() = USD(this) - -// Euro. -val EUR = FiatCurrency.getInstance("EUR") - -fun EUR(amount: Int): Amount = amount(amount, EUR) -fun EUR(amount: Long): Amount = amount(amount, EUR) -fun EUR(amount: Double): Amount = amount(amount, EUR) -val Int.EUR: Amount get() = EUR(this) -val Long.EUR: Amount get() = EUR(this) -val Double.EUR: Amount get() = EUR(this) - -// Swissie. -val CHF = FiatCurrency.getInstance("CHF") - -fun CHF(amount: Int): Amount = amount(amount, CHF) -fun CHF(amount: Long): Amount = amount(amount, CHF) -fun CHF(amount: Double): Amount = amount(amount, CHF) -val Int.CHF: Amount get() = CHF(this) -val Long.CHF: Amount get() = CHF(this) -val Double.CHF: Amount get() = CHF(this) - -// Japanese Yen. -val JPY = FiatCurrency.getInstance("JPY") - -fun JPY(amount: Int): Amount = amount(amount, JPY) -fun JPY(amount: Long): Amount = amount(amount, JPY) -fun JPY(amount: Double): Amount = amount(amount, JPY) -val Int.JPY: Amount get() = JPY(this) -val Long.JPY: Amount get() = JPY(this) -val Double.JPY: Amount get() = JPY(this) - -// Canadian Dollar. -val CAD = FiatCurrency.getInstance("CAD") - -fun CAD(amount: Int): Amount = amount(amount, CAD) -fun CAD(amount: Long): Amount = amount(amount, CAD) -fun CAD(amount: Double): Amount = amount(amount, CAD) -val Int.CAD: Amount get() = CAD(this) -val Long.CAD: Amount get() = CAD(this) -val Double.CAD: Amount get() = CAD(this) - -// Australian Dollar. -val AUD = FiatCurrency.getInstance("AUD") - -fun AUD(amount: Int): Amount = amount(amount, AUD) -fun AUD(amount: Long): Amount = amount(amount, AUD) -fun AUD(amount: Double): Amount = amount(amount, AUD) -val Int.AUD: Amount get() = AUD(this) -val Long.AUD: Amount get() = AUD(this) -val Double.AUD: Amount get() = AUD(this) - -// New Zealand Dollar. -val NZD = FiatCurrency.getInstance("NZD") - -fun NZD(amount: Int): Amount = amount(amount, NZD) -fun NZD(amount: Long): Amount = amount(amount, NZD) -fun NZD(amount: Double): Amount = amount(amount, NZD) -val Int.NZD: Amount get() = NZD(this) -val Long.NZD: Amount get() = NZD(this) -val Double.NZD: Amount get() = NZD(this) - -// Bitcoin. -val BTC = DigitalCurrency.getInstance("BTC") - -fun BTC(amount: Int): Amount = amount(amount, BTC) -fun BTC(amount: Long): Amount = amount(amount, BTC) -fun BTC(amount: Double): Amount = amount(amount, BTC) -val Int.BTC: Amount get() = BTC(this) -val Long.BTC: Amount get() = BTC(this) -val Double.BTC: Amount get() = BTC(this) - -val XRP = DigitalCurrency.getInstance("XRP") - -fun XRP(amount: Int): Amount = amount(amount, XRP) -fun XRP(amount: Long): Amount = amount(amount, XRP) -fun XRP(amount: Double): Amount = amount(amount, XRP) -val Int.XRP: Amount get() = XRP(this) -val Long.XRP: Amount get() = XRP(this) -val Double.XRP: Amount get() = XRP(this) diff --git a/workflows/build.gradle b/workflows/build.gradle index 2af8db93..f0bd43f9 100644 --- a/workflows/build.gradle +++ b/workflows/build.gradle @@ -2,6 +2,13 @@ apply plugin: 'kotlin-jpa' apply plugin: 'net.corda.plugins.quasar-utils' apply plugin: 'net.corda.plugins.cordapp' + +evaluationDependsOn(":modules:money") +evaluationDependsOn(":modules:selection") + +def moneyProject = project(":modules:money") +def selectionProject = project(":modules:selection") + cordapp { targetPlatformVersion 5 minimumPlatformVersion 5 @@ -41,6 +48,10 @@ configurations { integrationTestRuntime.extendsFrom testRuntime } +compileKotlin{ + dependsOn (moneyProject.jar, selectionProject.jar) +} + dependencies { // Kotlin. compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" @@ -50,6 +61,10 @@ dependencies { changing = true } + cordaCompile("$corda_release_group:corda-node-api:$corda_release_version") { + changing = true + } + // Logging. testCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" @@ -60,8 +75,8 @@ dependencies { // CorDapp dependencies. cordapp project(":contracts") - compile project(":modules:money") - compile project(":modules:selection") + + compile(files(moneyProject.jar.archivePath, selectionProject.jar.archivePath)) //CI for confidential tokens cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version" diff --git a/workflows/src/main/kotlin/com/r3/corda/lib/tokens/workflows/OwnerMigration.kt b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/workflows/OwnerMigration.kt index 55a2e688..23c8fa9d 100644 --- a/workflows/src/main/kotlin/com/r3/corda/lib/tokens/workflows/OwnerMigration.kt +++ b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/workflows/OwnerMigration.kt @@ -15,13 +15,8 @@ import net.corda.core.crypto.toStringShort import net.corda.core.internal.readFully import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.deserialize -import net.corda.core.serialization.internal.SerializationEnvironment -import net.corda.core.serialization.internal._allEnabledSerializationEnvs -import net.corda.core.serialization.internal._inheritableContextSerializationEnv -import net.corda.core.serialization.internal.effectiveSerializationEnv import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.contextLogger -import net.corda.serialization.internal.AMQP_P2P_CONTEXT import net.corda.serialization.internal.AMQP_STORAGE_CONTEXT import net.corda.serialization.internal.CordaSerializationMagic import net.corda.serialization.internal.SerializationFactoryImpl diff --git a/modules/money/src/test/java/com/r3/corda/lib/tokens/money/CurrencyAccessFromJavaTest.java b/workflows/src/test/java/com/r3/corda/lib/tokens/money/CurrencyAccessFromJavaTest.java similarity index 100% rename from modules/money/src/test/java/com/r3/corda/lib/tokens/money/CurrencyAccessFromJavaTest.java rename to workflows/src/test/java/com/r3/corda/lib/tokens/money/CurrencyAccessFromJavaTest.java From 9d8134d4e14f29c666aa194f5d458c10a57f4a83 Mon Sep 17 00:00:00 2001 From: Stefano Franz Date: Sat, 6 Jun 2020 07:17:58 +0100 Subject: [PATCH 2/2] put workflows jar on a bit of a diet --- contracts/build.gradle | 7 -- .../lib/tokens/contracts/CommonTokens.kt | 17 +++ .../tokens/contracts/FungibleTokenTests.kt | 40 +++---- .../tokens/contracts/NonFungibleTokenTests.kt | 9 +- .../lib/tokens/contracts/TokenPointerTests.kt | 5 +- modules/contracts-for-testing/build.gradle | 1 - modules/money/build.gradle | 57 ---------- settings.gradle | 2 - workflows/build.gradle | 6 +- .../tokens/integrationTest/TokenDriverTest.kt | 4 - .../corda/lib/tokens/money/DigitalCurrency.kt | 27 +++++ .../r3/corda/lib/tokens/money/FiatCurrency.kt | 22 ++++ .../r3/corda/lib/tokens/money/Utilities.kt | 107 ++++++++++++++++++ 13 files changed, 201 insertions(+), 103 deletions(-) create mode 100644 contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/CommonTokens.kt delete mode 100644 modules/money/build.gradle create mode 100644 workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt create mode 100644 workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt create mode 100644 workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt diff --git a/contracts/build.gradle b/contracts/build.gradle index 58de5f53..21e20c66 100644 --- a/contracts/build.gradle +++ b/contracts/build.gradle @@ -34,7 +34,6 @@ dependencies { testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testCompile "junit:junit:$junit_version" testCompile "$corda_release_group:corda-node-driver:$corda_release_version" - testCompile project(":modules:money") testCompile project(":modules:contracts-for-testing") } @@ -54,10 +53,4 @@ cordapp { jar { baseName "tokens-contracts" -} - -test { - beforeTest { - throw new IllegalStateException() - } } \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/CommonTokens.kt b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/CommonTokens.kt new file mode 100644 index 00000000..048bd14c --- /dev/null +++ b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/CommonTokens.kt @@ -0,0 +1,17 @@ +package com.r3.corda.lib.tokens.contracts + +import com.r3.corda.lib.tokens.contracts.types.TokenType +import net.corda.core.contracts.Amount + +class CommonTokens { + + companion object { + val USD = TokenType("USD", 2) + val GBP = TokenType("GBP", 2) + } + +} + +fun Number.ofType(tt: TokenType): Amount { + return Amount(this.toLong(), tt) +} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/FungibleTokenTests.kt b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/FungibleTokenTests.kt index c91d9963..6c6a7dbf 100644 --- a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/FungibleTokenTests.kt +++ b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/FungibleTokenTests.kt @@ -8,12 +8,12 @@ import com.r3.corda.lib.tokens.contracts.utilities.getAttachmentIdForGenericPara import com.r3.corda.lib.tokens.contracts.utilities.heldBy import com.r3.corda.lib.tokens.contracts.utilities.issuedBy import com.r3.corda.lib.tokens.contracts.utilities.of -import com.r3.corda.lib.tokens.money.GBP -import com.r3.corda.lib.tokens.money.USD import com.r3.corda.lib.tokens.testing.states.DodgeToken import com.r3.corda.lib.tokens.testing.states.DodgeTokenContract import com.r3.corda.lib.tokens.testing.states.RUB import com.r3.corda.lib.tokens.testing.states.RubleToken +import com.r3.corda.lib.tokens.contracts.CommonTokens.Companion.USD +import com.r3.corda.lib.tokens.contracts.CommonTokens.Companion.GBP import org.junit.Test // TODO: Some of these tests are testing AbstractToken and should be moved into the super-class. @@ -58,7 +58,7 @@ class FungibleTokenTests : ContractTestCommon() { } // Includes a group with no assigned command. tweak { - output(FungibleTokenContract.contractId, 10.USD issuedBy ISSUER.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy ISSUER.party heldBy ALICE.party) command(ISSUER.publicKey, IssueTokenCommand(issuedToken, listOf(0))) this `fails with` "There is a token group with no assigned command!" } @@ -101,7 +101,7 @@ class FungibleTokenTests : ContractTestCommon() { // Includes the same token issued by a different issuer. // You wouldn't usually do this but it is possible. tweak { - output(FungibleTokenContract.contractId, 1.GBP issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 1.ofType(GBP) issuedBy BOB.party heldBy ALICE.party) command(ISSUER.publicKey, IssueTokenCommand(issuedToken, listOf(0))) command(BOB.publicKey, IssueTokenCommand(GBP issuedBy BOB.party, listOf(1))) verifies() @@ -131,7 +131,7 @@ class FungibleTokenTests : ContractTestCommon() { // Move coupled with an issue. tweak { - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) //the issue token is added after the move tokens, so it will have index(1) command(BOB.publicKey, IssueTokenCommand(USD issuedBy BOB.party, outputs = listOf(1))) @@ -140,7 +140,7 @@ class FungibleTokenTests : ContractTestCommon() { // Input missing. tweak { - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy BOB.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, outputs = listOf(1))) this `fails with` "When moving tokens, there must be input states present." @@ -148,7 +148,7 @@ class FungibleTokenTests : ContractTestCommon() { // Output missing. tweak { - input(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) + input(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1))) this `fails with` "When moving tokens, there must be output states present." @@ -156,9 +156,9 @@ class FungibleTokenTests : ContractTestCommon() { // Inputs sum to zero. tweak { - input(FungibleTokenContract.contractId, 0.USD issuedBy BOB.party heldBy ALICE.party) - input(FungibleTokenContract.contractId, 0.USD issuedBy BOB.party heldBy ALICE.party) - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy BOB.party) + input(FungibleTokenContract.contractId, 0.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + input(FungibleTokenContract.contractId, 0.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1, 2), outputs = listOf(1))) // Command for the move. this `fails with` "In move groups there must be an amount of input tokens > ZERO." @@ -166,9 +166,9 @@ class FungibleTokenTests : ContractTestCommon() { // Outputs sum to zero. tweak { - input(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) - output(FungibleTokenContract.contractId, 0.USD issuedBy BOB.party heldBy BOB.party) - output(FungibleTokenContract.contractId, 0.USD issuedBy BOB.party heldBy BOB.party) + input(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 0.ofType(USD) issuedBy BOB.party heldBy BOB.party) + output(FungibleTokenContract.contractId, 0.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1), outputs = listOf(1, 2))) // Command for the move. this `fails with` "In move groups there must be an amount of output tokens > ZERO." @@ -176,8 +176,8 @@ class FungibleTokenTests : ContractTestCommon() { // Unbalanced move. tweak { - input(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) - output(FungibleTokenContract.contractId, 11.USD issuedBy BOB.party heldBy BOB.party) + input(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 11.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1), outputs = listOf(1))) // Command for the move. this `fails with` "In move groups the amount of input tokens MUST EQUAL the amount of output tokens. " + @@ -185,9 +185,9 @@ class FungibleTokenTests : ContractTestCommon() { } tweak { - input(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy BOB.party) - output(FungibleTokenContract.contractId, 0.USD issuedBy BOB.party heldBy BOB.party) + input(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy BOB.party) + output(FungibleTokenContract.contractId, 0.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1), outputs = listOf(1, 2))) // Command for the move. this `fails with` "You cannot create output token amounts with a ZERO amount." @@ -195,8 +195,8 @@ class FungibleTokenTests : ContractTestCommon() { // Two moves (two different groups). tweak { - input(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy BOB.party) + input(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(USD) issuedBy BOB.party heldBy BOB.party) command(ALICE.publicKey, MoveTokenCommand(USD issuedBy BOB.party, inputs = listOf(1), outputs = listOf(1))) // Command for the move. verifies() diff --git a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/NonFungibleTokenTests.kt b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/NonFungibleTokenTests.kt index e6805037..0bbb5563 100644 --- a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/NonFungibleTokenTests.kt +++ b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/NonFungibleTokenTests.kt @@ -7,7 +7,6 @@ import com.r3.corda.lib.tokens.contracts.utilities.heldBy import com.r3.corda.lib.tokens.contracts.utilities.issuedBy import com.r3.corda.lib.tokens.contracts.utilities.of import com.r3.corda.lib.tokens.contracts.utilities.withNewHolder -import com.r3.corda.lib.tokens.money.USD import com.r3.corda.lib.tokens.testing.states.PTK import com.r3.corda.lib.tokens.testing.states.RUB import org.junit.Test @@ -58,7 +57,7 @@ class NonFungibleTokenTests : ContractTestCommon() { } // Includes a group with no assigned command. tweak { - output(FungibleTokenContract.contractId, 10.USD issuedBy ISSUER.party heldBy ALICE.party) + output(FungibleTokenContract.contractId, 10.ofType(CommonTokens.USD) issuedBy ISSUER.party heldBy ALICE.party) command(ISSUER.publicKey, IssueTokenCommand(issuedToken, outputs = listOf(0))) this `fails with` "There is a token group with no assigned command!" } @@ -71,7 +70,7 @@ class NonFungibleTokenTests : ContractTestCommon() { // Includes another token type and a matching command. tweak { - val otherToken = USD issuedBy ISSUER.party + val otherToken = CommonTokens.USD issuedBy ISSUER.party output(FungibleTokenContract.contractId, 10 of otherToken heldBy ALICE.party) command(ISSUER.publicKey, IssueTokenCommand(issuedToken, outputs = listOf(0))) command(ISSUER.publicKey, IssueTokenCommand(otherToken, outputs = listOf(1))) @@ -118,8 +117,8 @@ class NonFungibleTokenTests : ContractTestCommon() { // Move coupled with an issue. tweak { - output(FungibleTokenContract.contractId, 10.USD issuedBy BOB.party heldBy ALICE.party) - command(BOB.publicKey, IssueTokenCommand(USD issuedBy BOB.party, outputs = listOf(1))) + output(FungibleTokenContract.contractId, 10.ofType(CommonTokens.USD) issuedBy BOB.party heldBy ALICE.party) + command(BOB.publicKey, IssueTokenCommand(CommonTokens.USD issuedBy BOB.party, outputs = listOf(1))) // Command for the move. command(ALICE.publicKey, MoveTokenCommand(issuedToken, inputs = listOf(0), outputs = listOf(0))) verifies() diff --git a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/TokenPointerTests.kt b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/TokenPointerTests.kt index 5a56bfac..5dce26f6 100644 --- a/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/TokenPointerTests.kt +++ b/contracts/src/test/kotlin/com/r3/corda/lib/tokens/contracts/TokenPointerTests.kt @@ -6,7 +6,6 @@ import com.r3.corda.lib.tokens.contracts.states.FungibleToken import com.r3.corda.lib.tokens.contracts.states.NonFungibleToken import com.r3.corda.lib.tokens.contracts.types.TokenPointer import com.r3.corda.lib.tokens.contracts.utilities.* -import com.r3.corda.lib.tokens.money.GBP import net.corda.core.crypto.Crypto import net.corda.core.crypto.SignableData import net.corda.core.crypto.SignatureMetadata @@ -57,8 +56,8 @@ class TokenPointerTests : ContractTestCommon() { fun `tokenTypeJarHash must be not null if tokenType is not a pointer`() { val pointer: TokenPointer = TestEvolvableTokenType(listOf(ALICE.party)).toPointer() val pointerToken: NonFungibleToken = pointer issuedBy ISSUER.party heldBy ALICE.party - val staticToken: NonFungibleToken = GBP issuedBy ISSUER.party heldBy ALICE.party + val staticToken: NonFungibleToken = CommonTokens.GBP issuedBy ISSUER.party heldBy ALICE.party assertEquals(pointerToken.tokenTypeJarHash, null) - assertEquals(staticToken.tokenTypeJarHash, GBP.getAttachmentIdForGenericParam()) + assertEquals(staticToken.tokenTypeJarHash, CommonTokens.GBP.getAttachmentIdForGenericParam()) } } \ No newline at end of file diff --git a/modules/contracts-for-testing/build.gradle b/modules/contracts-for-testing/build.gradle index 1082ff37..9602787f 100644 --- a/modules/contracts-for-testing/build.gradle +++ b/modules/contracts-for-testing/build.gradle @@ -46,5 +46,4 @@ dependencies { // CorDapp dependencies. cordapp project(":contracts") - cordapp project(":modules:money") } \ No newline at end of file diff --git a/modules/money/build.gradle b/modules/money/build.gradle deleted file mode 100644 index ed0f8a51..00000000 --- a/modules/money/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -apply plugin: 'net.corda.plugins.cordapp' - -if (!(corda_release_version in ['4.1'])) { -apply from: "${rootProject.projectDir}/deterministic.gradle" -} - -cordapp { - targetPlatformVersion 4 - minimumPlatformVersion 4 - contract { - name "Token SDK money definitions" - vendor "R3" - licence "Apache 2" - versionId 1 - } - signing { - enabled false - } -} - -sourceSets { - main { - resources { - srcDir rootProject.file("config/dev") - } - } - test { - resources { - srcDir rootProject.file("config/test") - } - } -} - -dependencies { - // Kotlin. - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - - // Corda dependencies. - cordaCompile ("$corda_release_group:corda-core:$corda_release_version"){ - changing = true - } - - // Logging. - testCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" - - // Testing. - testCompile "$corda_release_group:corda-node-driver:$corda_release_version" - testCompile "junit:junit:$junit_version" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" - - // CorDapp dependencies. - cordapp project(":contracts") -} - -jar { - baseName "tokens-money" -} diff --git a/settings.gradle b/settings.gradle index 31861d30..70ec1b99 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1,6 @@ include 'contracts' include 'workflows' -include 'modules:money' include 'modules:contracts-for-testing' include 'modules:selection' -findProject(':modules:money')?.name = 'money' include 'freighter-tests' diff --git a/workflows/build.gradle b/workflows/build.gradle index 60f3c0fc..04a5c4ac 100644 --- a/workflows/build.gradle +++ b/workflows/build.gradle @@ -3,10 +3,8 @@ apply plugin: 'net.corda.plugins.quasar-utils' apply plugin: 'net.corda.plugins.cordapp' -evaluationDependsOn(":modules:money") evaluationDependsOn(":modules:selection") -def moneyProject = project(":modules:money") def selectionProject = project(":modules:selection") cordapp { @@ -49,7 +47,7 @@ configurations { } compileKotlin{ - dependsOn (moneyProject.jar, selectionProject.jar) + dependsOn (selectionProject.jar) } dependencies { @@ -76,7 +74,7 @@ dependencies { // CorDapp dependencies. cordapp project(":contracts") - compile(files(moneyProject.jar.archivePath, selectionProject.jar.archivePath)) + compile(files(selectionProject.jar.archivePath)) //CI for confidential tokens cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version" diff --git a/workflows/src/integrationTest/kotlin/com/r3/corda/lib/tokens/integrationTest/TokenDriverTest.kt b/workflows/src/integrationTest/kotlin/com/r3/corda/lib/tokens/integrationTest/TokenDriverTest.kt index 17490288..fed5b17a 100644 --- a/workflows/src/integrationTest/kotlin/com/r3/corda/lib/tokens/integrationTest/TokenDriverTest.kt +++ b/workflows/src/integrationTest/kotlin/com/r3/corda/lib/tokens/integrationTest/TokenDriverTest.kt @@ -130,7 +130,6 @@ class TokenDriverTest { portAllocation = incrementalPortAllocation(), startNodesInProcess = false, cordappsForAllNodes = listOf( - TestCordapp.findCordapp("com.r3.corda.lib.tokens.money"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.selection"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.workflows"), @@ -156,7 +155,6 @@ class TokenDriverTest { portAllocation = incrementalPortAllocation(), startNodesInProcess = false, cordappsForAllNodes = listOf( - TestCordapp.findCordapp("com.r3.corda.lib.tokens.money"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.workflows"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.testing"), @@ -265,7 +263,6 @@ class TokenDriverTest { inMemoryDB = false, startNodesInProcess = false, cordappsForAllNodes = listOf( - TestCordapp.findCordapp("com.r3.corda.lib.tokens.money"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.workflows"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.testing"), @@ -323,7 +320,6 @@ class TokenDriverTest { inMemoryDB = false, startNodesInProcess = false, cordappsForAllNodes = listOf( - TestCordapp.findCordapp("com.r3.corda.lib.tokens.money"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.contracts"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.workflows"), TestCordapp.findCordapp("com.r3.corda.lib.tokens.testing"), diff --git a/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt new file mode 100644 index 00000000..4eafefd4 --- /dev/null +++ b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/DigitalCurrency.kt @@ -0,0 +1,27 @@ +package com.r3.corda.lib.tokens.money + +import com.r3.corda.lib.tokens.contracts.types.TokenType +import java.util.* + +/** + * A representation of digital money. This implementation somewhat mirrors that of [Currency]. + * + * Note that the primary constructor only exists for simple and convenient access from Java code. + * + * @param currencyCode The currency code that represents the TokenType which the developer wishes to instantiate. + */ +class DigitalCurrency { + companion object { + private val registry = mapOf( + Pair("XRP", TokenType("Ripple", 6)), + Pair("BTC", TokenType("Bitcoin", 8)), + Pair("ETH", TokenType("Ethereum", 18)), + Pair("DOGE", TokenType("Dogecoin", 8)) + ) + + @JvmStatic + fun getInstance(currencyCode: String): TokenType { + return registry[currencyCode] ?: throw IllegalArgumentException("$currencyCode doesn't exist.") + } + } +} \ No newline at end of file diff --git a/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt new file mode 100644 index 00000000..87e0faed --- /dev/null +++ b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/FiatCurrency.kt @@ -0,0 +1,22 @@ +package com.r3.corda.lib.tokens.money + +import com.r3.corda.lib.tokens.contracts.types.TokenType +import java.util.* + +/** + * This class is used to return a [TokenType] with the required currency code and fraction digits for fiat currencies. + * + * Note that the primary constructor only exists for simple and convenient access from Java code. + * + * @param currencyCode The currency code that represents the TokenType which the developer wishes to instantiate. + */ +class FiatCurrency { + companion object { + // Uses the java money registry. + @JvmStatic + fun getInstance(currencyCode: String): TokenType { + val currency = Currency.getInstance(currencyCode) + return TokenType(currency.currencyCode, currency.defaultFractionDigits) + } + } +} diff --git a/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt new file mode 100644 index 00000000..fb0b363e --- /dev/null +++ b/workflows/src/main/kotlin/com/r3/corda/lib/tokens/money/Utilities.kt @@ -0,0 +1,107 @@ +@file:JvmName("MoneyUtilities") +package com.r3.corda.lib.tokens.money + +import com.r3.corda.lib.tokens.contracts.types.TokenType +import com.r3.corda.lib.tokens.contracts.utilities.amount +import net.corda.core.contracts.Amount + +/** Helpers for creating amounts of fixed token definitions. */ + +// Sterling. +val GBP = FiatCurrency.getInstance("GBP") + +fun GBP(amount: Int): Amount = amount(amount, GBP) +fun GBP(amount: Long): Amount = amount(amount, GBP) +fun GBP(amount: Double): Amount = amount(amount, GBP) +val Int.GBP: Amount get() = GBP(this) +val Long.GBP: Amount get() = GBP(this) +val Double.GBP: Amount get() = GBP(this) + +// US Dollar. +val USD = FiatCurrency.getInstance("USD") + +fun USD(amount: Int): Amount = amount(amount, USD) +fun USD(amount: Long): Amount = amount(amount, USD) +fun USD(amount: Double): Amount = amount(amount, USD) +val Int.USD: Amount get() = USD(this) +val Long.USD: Amount get() = USD(this) +val Double.USD: Amount get() = USD(this) + +// Euro. +val EUR = FiatCurrency.getInstance("EUR") + +fun EUR(amount: Int): Amount = amount(amount, EUR) +fun EUR(amount: Long): Amount = amount(amount, EUR) +fun EUR(amount: Double): Amount = amount(amount, EUR) +val Int.EUR: Amount get() = EUR(this) +val Long.EUR: Amount get() = EUR(this) +val Double.EUR: Amount get() = EUR(this) + +// Swissie. +val CHF = FiatCurrency.getInstance("CHF") + +fun CHF(amount: Int): Amount = amount(amount, CHF) +fun CHF(amount: Long): Amount = amount(amount, CHF) +fun CHF(amount: Double): Amount = amount(amount, CHF) +val Int.CHF: Amount get() = CHF(this) +val Long.CHF: Amount get() = CHF(this) +val Double.CHF: Amount get() = CHF(this) + +// Japanese Yen. +val JPY = FiatCurrency.getInstance("JPY") + +fun JPY(amount: Int): Amount = amount(amount, JPY) +fun JPY(amount: Long): Amount = amount(amount, JPY) +fun JPY(amount: Double): Amount = amount(amount, JPY) +val Int.JPY: Amount get() = JPY(this) +val Long.JPY: Amount get() = JPY(this) +val Double.JPY: Amount get() = JPY(this) + +// Canadian Dollar. +val CAD = FiatCurrency.getInstance("CAD") + +fun CAD(amount: Int): Amount = amount(amount, CAD) +fun CAD(amount: Long): Amount = amount(amount, CAD) +fun CAD(amount: Double): Amount = amount(amount, CAD) +val Int.CAD: Amount get() = CAD(this) +val Long.CAD: Amount get() = CAD(this) +val Double.CAD: Amount get() = CAD(this) + +// Australian Dollar. +val AUD = FiatCurrency.getInstance("AUD") + +fun AUD(amount: Int): Amount = amount(amount, AUD) +fun AUD(amount: Long): Amount = amount(amount, AUD) +fun AUD(amount: Double): Amount = amount(amount, AUD) +val Int.AUD: Amount get() = AUD(this) +val Long.AUD: Amount get() = AUD(this) +val Double.AUD: Amount get() = AUD(this) + +// New Zealand Dollar. +val NZD = FiatCurrency.getInstance("NZD") + +fun NZD(amount: Int): Amount = amount(amount, NZD) +fun NZD(amount: Long): Amount = amount(amount, NZD) +fun NZD(amount: Double): Amount = amount(amount, NZD) +val Int.NZD: Amount get() = NZD(this) +val Long.NZD: Amount get() = NZD(this) +val Double.NZD: Amount get() = NZD(this) + +// Bitcoin. +val BTC = DigitalCurrency.getInstance("BTC") + +fun BTC(amount: Int): Amount = amount(amount, BTC) +fun BTC(amount: Long): Amount = amount(amount, BTC) +fun BTC(amount: Double): Amount = amount(amount, BTC) +val Int.BTC: Amount get() = BTC(this) +val Long.BTC: Amount get() = BTC(this) +val Double.BTC: Amount get() = BTC(this) + +val XRP = DigitalCurrency.getInstance("XRP") + +fun XRP(amount: Int): Amount = amount(amount, XRP) +fun XRP(amount: Long): Amount = amount(amount, XRP) +fun XRP(amount: Double): Amount = amount(amount, XRP) +val Int.XRP: Amount get() = XRP(this) +val Long.XRP: Amount get() = XRP(this) +val Double.XRP: Amount get() = XRP(this)