summaryrefslogtreecommitdiff
path: root/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt')
-rw-r--r--wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt110
1 files changed, 110 insertions, 0 deletions
diff --git a/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt b/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
new file mode 100644
index 0000000..3156d3f
--- /dev/null
+++ b/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
@@ -0,0 +1,110 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.kotlin.crypto
+
+import net.taler.wallet.kotlin.Amount
+import net.taler.wallet.kotlin.Base32Crockford
+import net.taler.wallet.kotlin.Timestamp
+import net.taler.wallet.kotlin.crypto.Signature.Companion.WALLET_COIN_DEPOSIT
+
+/**
+ * Deposit operations are requested by a merchant during a transaction.
+ * For the deposit operation, the merchant has to obtain the deposit permission for a coin
+ * from their customer who owns the coin.
+ *
+ * When depositing a coin, the merchant is credited an amount specified in the deposit permission,
+ * possibly a fraction of the total coin’s value,
+ * minus the deposit fee as specified by the coin’s denomination.
+ */
+internal class Deposit(private val crypto: Crypto) {
+
+ /**
+ * Private data required to make a deposit permission.
+ */
+ data class DepositInfo(
+ val exchangeBaseUrl: String,
+ val contractTermsHash: String,
+ val coinPublicKey: String,
+ val coinPrivateKey: String,
+ val spendAmount: Amount,
+ val timestamp: Timestamp,
+ val refundDeadline: Timestamp,
+ val merchantPublicKey: String,
+ val feeDeposit: Amount,
+ val wireInfoHash: String,
+ val denomPublicKey: String,
+ val denomSignature: String
+ )
+
+ /**
+ * Deposit permission for a single coin.
+ */
+ // TODO rename _
+ data class CoinDepositPermission(
+ /**
+ * Signature by the coin.
+ */
+ val coinSignature: String,
+ /**
+ * Public key of the coin being spend.
+ */
+ val coinPublicKey: String,
+ /**
+ * Signature made by the denomination public key.
+ */
+ val denomSignature: String,
+ /**
+ * The denomination public key associated with this coin.
+ */
+ val denomPublicKey: String,
+ /**
+ * The amount that is subtracted from this coin with this payment.
+ */
+ val contribution: String,
+ /**
+ * URL of the exchange this coin was withdrawn from.
+ */
+ val exchangeBaseUrl: String
+ )
+
+ /**
+ * Generate updated coins (to store in the database) and deposit permissions for each given coin.
+ */
+ fun signDepositPermission(depositInfo: DepositInfo): CoinDepositPermission {
+ val d = Signature.PurposeBuilder(WALLET_COIN_DEPOSIT)
+ .put(Base32Crockford.decode(depositInfo.contractTermsHash))
+ .put(Base32Crockford.decode(depositInfo.wireInfoHash))
+ .put(depositInfo.timestamp.roundedToByteArray())
+ .put(depositInfo.refundDeadline.roundedToByteArray())
+ .put(depositInfo.spendAmount.toByteArray())
+ .put(depositInfo.feeDeposit.toByteArray())
+ .put(Base32Crockford.decode(depositInfo.merchantPublicKey))
+ .put(Base32Crockford.decode(depositInfo.coinPublicKey))
+ .build()
+ val coinPriv = Base32Crockford.decode(depositInfo.coinPrivateKey);
+ val coinSig = crypto.eddsaSign(d, coinPriv)
+ return CoinDepositPermission(
+ coinPublicKey = depositInfo.coinPublicKey,
+ coinSignature = Base32Crockford.encode(coinSig),
+ contribution = depositInfo.spendAmount.toJSONString(),
+ denomPublicKey = depositInfo.denomPublicKey,
+ exchangeBaseUrl = depositInfo.exchangeBaseUrl,
+ denomSignature = depositInfo.denomSignature
+ )
+ }
+
+}