summaryrefslogtreecommitdiff
path: root/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange')
-rw-r--r--wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt91
-rw-r--r--wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt119
-rw-r--r--wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt316
-rw-r--r--wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/UpdateTest.kt37
-rw-r--r--wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt175
5 files changed, 738 insertions, 0 deletions
diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt
new file mode 100644
index 0000000..c52638b
--- /dev/null
+++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/DenominationTest.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.lib.wallet.exchange
+
+import net.taler.lib.common.Amount
+import net.taler.lib.common.Timestamp
+import net.taler.lib.common.Timestamp.Companion.NEVER
+import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedBad
+import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedGood
+import net.taler.lib.wallet.exchange.Denominations.denomination1
+import net.taler.lib.wallet.exchange.Denominations.denomination10
+import net.taler.lib.wallet.exchange.Denominations.denomination2
+import net.taler.lib.wallet.exchange.Denominations.denomination5
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+class DenominationTest {
+
+ @Test
+ fun testGetEarliestDepositExpiry() {
+ // empty selection info never expires
+ val infoEmpty = DenominationSelectionInfo(
+ totalCoinValue = Amount.zero("TESTKUDOS"),
+ totalWithdrawCost = Amount.zero("TESTKUDOS"),
+ selectedDenominations = emptyList()
+ )
+ assertEquals(Timestamp(NEVER), infoEmpty.getEarliestDepositExpiry())
+
+ // earliest expiry of single denomination is that of the denomination
+ val info1 = infoEmpty.copy(
+ selectedDenominations = listOf(SelectedDenomination(1, denomination10))
+ )
+ assertEquals(denomination10.stampExpireDeposit, info1.getEarliestDepositExpiry())
+
+ // denomination that expires earlier gets selected
+ val info2 = infoEmpty.copy(
+ selectedDenominations = listOf(
+ SelectedDenomination(3, denomination5.copy(stampExpireDeposit = Timestamp(42))),
+ SelectedDenomination(2, denomination2.copy(stampExpireDeposit = Timestamp(2))),
+ SelectedDenomination(1, denomination1.copy(stampExpireDeposit = Timestamp(1)))
+ )
+ )
+ assertEquals(Timestamp(1), info2.getEarliestDepositExpiry())
+
+ // denomination that expires at all is earlier than the one that never expires
+ val info3 = infoEmpty.copy(
+ selectedDenominations = listOf(
+ SelectedDenomination(2, denomination2.copy(stampExpireDeposit = Timestamp(NEVER))),
+ SelectedDenomination(1, denomination1.copy(stampExpireDeposit = Timestamp(1)))
+ )
+ )
+ assertEquals(Timestamp(1), info3.getEarliestDepositExpiry())
+ }
+
+ @Test
+ fun testIsWithdrawableDenomination() {
+ // denomination is withdrawable
+ assertTrue(denomination1.isWithdrawable())
+ // denomination is withdrawable when VerifiedGood
+ assertTrue(denomination1.copy(status = VerifiedGood).isWithdrawable())
+ // fails with VerifiedBad
+ assertFalse(denomination1.copy(status = VerifiedBad).isWithdrawable())
+ // fails when revoked
+ assertFalse(denomination1.copy(isRevoked = true).isWithdrawable())
+ // fails when not started
+ assertFalse(denomination1.copy(stampStart = Timestamp(Timestamp.now().ms + 9999)).isWithdrawable())
+ // fails when expired
+ assertFalse(denomination1.copy(stampExpireWithdraw = Timestamp.now()).isWithdrawable())
+ // fails when almost expired
+ assertFalse(denomination1.copy(stampExpireWithdraw = Timestamp(Timestamp.now().ms + 5000)).isWithdrawable())
+ // succeeds when not quite expired
+ assertTrue(denomination1.copy(stampExpireWithdraw = Timestamp(Timestamp.now().ms + 51000)).isWithdrawable())
+ }
+
+}
diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt
new file mode 100644
index 0000000..10a2772
--- /dev/null
+++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/Denominations.kt
@@ -0,0 +1,119 @@
+/*
+ * 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.lib.wallet.exchange
+
+import net.taler.lib.common.Amount
+import net.taler.lib.common.Timestamp
+import net.taler.lib.wallet.exchange.DenominationStatus.Unverified
+import net.taler.lib.wallet.exchange.DenominationStatus.VerifiedGood
+
+object Denominations {
+
+ private val validStart = Timestamp.now()
+ private val validExpireWithdraw =
+ Timestamp(Timestamp.now().ms + 1000L * 60L * 60L * 24L * 365L)
+ val denomination10 = DenominationRecord(
+ denomPub = "020000X0X3G1EBB22XJ4HD6R8545R294TMCMA13ZRW7R101KJENFGTNTZSPGA0XP898FJEVHY4SJTC0SM264K0Y7Q6E24S35JSFZXD6VAJDJX8FCERBTNFV5DZR8V4GV7DAD062CPZBEVGNDEJQCTHVFJP84QWVPYJFNZSS3EJEK3WKJVG5EM3X2JPM1C97AB26VSZXWNYNC2CNJN7KG2001",
+ denomPubHash = "7GB2YKDWKQ3DS2GA9XCVXVPMPJQA9M7Q0DFDHCX5M71J4E2PEHAJK3QF3KTJTWJA33KG0BX6XX0TTRMMZ8CEBM4GSE2N5FSV7GYRGH0",
+ exchangeBaseUrl = "https://example.org",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ isOffered = true,
+ isRevoked = false,
+ masterSig = "N9ADAGY43VTDA000NMW9NFKY8HBTTNPEWP9W1A1ATCAFVA1A9F1MD7HAJ6M4QQ3SVYJXCV1S9Z1ZMKXP9YKD3PFGNK0VQD1ZZ502420",
+ stampExpireDeposit = validExpireWithdraw,
+ stampExpireLegal = validExpireWithdraw,
+ stampExpireWithdraw = validExpireWithdraw,
+ stampStart = validStart,
+ status = Unverified,
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 10)
+ )
+ val denomination8 = denomination10.copy(
+ denomPub = "020000X61XTJPQHC9Z3GEF8BD0YTPGH819V6YQDW7MZ74PH9GC2WZGH1YPBHB6F6AJG7C91G19KTSSP9GA64SFZ26T06QK6XEQNREEFV6EMVRCQRYXV3YVA5ANJQRFJVMQG3DQG6Q0ANQWRBZGZSX43MNJQ0NGZY2X1VHJ0351RC83RMPYV1JFSZ2J1JZ2MN5AJF6QMCBBJN0V5TF3EG2001",
+ denomPubHash = "M496WWEBC8KN4MYB73V78F4DCXXMFWR2X33GWDA92X98MC04E120H9NVNKN70J3NP7ZZ91BE7CX65NYHQEG5EQK5Y78E7ZE3YV8E868",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 2000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 4000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 5000000, value = 0),
+ masterSig = "GNWDZNQHFECF2SPVWZ5D0KV7YEGJ0J86ND815B512ZSBNKSCSN7PCKE5GJTXV0WZNS3AYTDJYER3W1HXSST4TMBMAR3FY3ETRNRS20G",
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 8)
+ )
+ val denomination5 = denomination10.copy(
+ denomPub = "020000XFF9HD3GJXVA9ARQD76BW2G9K65F6CVDPWSRYVE5HY7EVVBK1PK1XX2HE2P3BA3A9MJT9ESY1XNKK7TTF8DRE33C22EHPNNBPPQC1D1MHEE3YJHNF8PG0W6DTE406R6VHCZ0VHEE5HNTEPWMAHJ5J0VVY1ESGAXWE1SGSY82FCQARWV45MNGYZMBN2M55CG3SQXJ8STRPHEM1G2001",
+ denomPubHash = "4HKTYHDDCJXJW7Z215E3TFQWBRYKZA4VS41CZKBE8HH1T97FV4X9WSM62Q7WEZTZX3Y60T4Y8M4R0YYA3PVSEND1MZCJBTD4QZDMCJR",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ masterSig = "0TBJSTZTWMKBT71ET1B7RVFB1VT84E10G3SENPSMPRYTFBH07WSDS5VA9PW5T0EYEABDKGAYDRQ0XA62GYQXZ4SBV2CTHHFY0TFNC18",
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 5)
+ )
+ val denomination4 = denomination10.copy(
+ denomPub = "020000Y3JVXB3XTC7JTK3CYEMSXHEX8956DN9B4Z6WB3J1H8D5Y3BVTY8EE5BC5JSRJKM0VAK6BXSHVRGQ6N43BF132DPNSJDG4CD8JA4A856HVCNFSNP0DY21TJYN8GJ36R1T0VKTVH2SRMT4QN1QQZC0VQ5ZV2EJJMCSVYVKV8MZC9NG5K9PGNQKBV64E34H1K9RSFEJE7306ZH07G2001",
+ denomPubHash = "XRKJ5750TW2ZNQYGQ87TESYF2X942RBCG7EKXB8QKMFGB433EK3567SDSE9EFNBYTEH3PHPTK22V8XNSJ090DHYX8EW9BE1Q8JCZW7G",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 4000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 2000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ masterSig = "VFKWHPFNEKD36A0A0TWVTEN98P4TCVBTRMJFJF1E1Q2578J9DXAY53Y7Q2D3BX01WKPM7QBCVF9WBMB4GTXVFP08QPZP086RV9PAP2G",
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 4)
+ )
+ val denomination2 = denomination10.copy(
+ denomPub = "020000XB8Y8WVSBM0WBY6NMS0MTNN71PEA6KGKTV5FF27RRR8V1V0GPWYAFDMD2XT6E265QPNH079KM25ZZ97NGFRDVHW0Y7JPWA9C8MJY8DB7APYBRMD9XYA0N1569VFW2NPP4FGQJ865RVE94F35NSG0M4W80CG6WXXWW1ERRM7F2AGRZE9FS049183ANEDFB7QN4H62GDWS7039GG2001",
+ denomPubHash = "CTH34KGWJKQ3C264DQJCRPX97G5SWGWQQ8EMBXVH4DKGTPJ78ZA5CWZB9SDT538Z6S118VQ3RNX3CVC1YXEFN0PXR0D896MDNCGZW3G",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 4000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 2000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ masterSig = "BTZYYEYBZK1EJJ47MQHEY7Q8ARBK4PT0N92TYEEPEZ54P0NTN6FT50AGKCCQCWQ8J74D8MTZFAX3PRDWSH30JPVREAQKGVGEVYXN00G",
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 2)
+ )
+ val denomination1 = denomination10.copy(
+ denomPub = "020000XBEVGYETENRYN30AMTT006NPFG5QNHHJXESR9YRZ0J1Y0V00ASMSK7SGKBZJW1GKW05AGNXZDGHAT8RP5M87H2QZTCZHNWW0W4SFWSHWEMRK57DQ3Z7EYQ3XMFX8E2QNZNT9TB4J0MMDP833Y0K7RCQ3X5A584ZBQ9M0T03KTF1QTS2Z7J0BRCEVMK7CCM5WYCAVDPP44Z23HG2001",
+ denomPubHash = "KHRCTNBZHY653V3WZBNMTGGM3MSS471EZ4F6X32HJMN17A47WBBM5WHCRNK8F27KB6Q45YMEN832BKYNKBK1GCRXKDP0XTYC3CYTRWR",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 2000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 2000000, value = 0),
+ masterSig = "X029BKSB9PRKE831VDV1X3ND441E0NNQCDJ2S9NKPG7F17R0Y6QCGKWCSHCHE96NW5XS13RK880H90ZSFY7HNJ17F4NSR1EM5FR2M10",
+ value = Amount(currency = "TESTKUDOS", fraction = 0, value = 1)
+ )
+ val denomination0d1 = denomination10.copy(
+ denomPub = "020000YVVE91KXE9S8JV5P4PWZJWBJD39Y6S00FA3CV6RP77A8PTKJWNE3W0W8ZHDR3CSKA17FT56PMC97RWV3RNG753B1WQYXEWNJA76GD5T2PA33BN08CQ07KP4M2K9R6A3N9VD6W8D3DK55W18Y7TBKAHCJBQ3AZ50VHSF1ZPM2XVJ238SKK1379WNHMK4VDJQ35H20QSF3GPWPKG2001",
+ denomPubHash = "C26V15X3BESS1CZCSP4BNSRJ8BK8DSGFHNB0WG1GZ6ZF6FR37WGSVEQ85A61X6Z103P8MY7XGQZ60VAX78V3E5GERWJTJAP0Q5QB7A8",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 3000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ masterSig = "JSJXWJXN4532C07CBH4DZZ6YC5S3TPH3H8FG8RMGX0Z647GX2NYEK02NRN3C4GDS9Q0ZT6QE7T8EGYGEF9RZ9FCV65TZWC1ZP83DT1R",
+ value = Amount(currency = "TESTKUDOS", fraction = 10000000, value = 0)
+ )
+ val denomination0d01 = denomination10.copy(
+ denomPub = "020000X67SMNYMCR1HFZW4KEATXGXRA983JE5VW1JE4108XB7Z40BTJC1MV59Y9K4Y35E3MPPF73BJQA3KVT0FBT89R6ZYNZ77TSC5DMFV5E55DT4JB4S9K4C2V7GM8Z8QZ0KMCH0YK4PAX1WSKCEQFNRVKD3VH9WTVQ0CNV7Z1JVRHBKCSZNX62TRQ6JRZ05JEANT3C41SQ6MKSQZKG2001",
+ denomPubHash = "VS0E7ABRZ9NZMTDAHVKQ4QH1S1Q2PYWXFXKF0P84VSHCDBM4S6QK1G1D495TABN4AXVX049P7JESNRRQVHW37BNER4XKZSQT3XA61DG",
+ feeDeposit = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeRefresh = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeRefund = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ feeWithdraw = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0),
+ masterSig = "CF3638K8QBG91D66JZRRGWV8J53A0ZGBYJDMKYK293DNAA2ASM1M346C0YG9V7HWH8E2A7FPVR0HH2QE7DHD9GW0EN19VSER4S5F23R",
+ status = VerifiedGood,
+ value = Amount(currency = "TESTKUDOS", fraction = 1000000, value = 0)
+ )
+
+}
diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt
new file mode 100644
index 0000000..a40c7cd
--- /dev/null
+++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/KeysTest.kt
@@ -0,0 +1,316 @@
+/*
+ * 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.lib.wallet.exchange
+
+import net.taler.lib.common.Amount
+import net.taler.lib.common.Timestamp
+import net.taler.lib.wallet.getMockHttpClient
+import net.taler.lib.wallet.giveJsonResponse
+import net.taler.lib.wallet.runCoroutine
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class KeysTest {
+
+ private val httpClient = getMockHttpClient()
+
+ @Test
+ fun testFetchKeys() {
+ val expectedKeys = Keys(
+ denoms = listOf(
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:5"),
+ denom_pub = "040000Z9TH9RPTA1BXF6Z89HM7JGXTPD5G8NNBWQWF7RWQGNAATN84QBWME1TGSWZ79WPQ62S2W2VHG2XBH66JDJ0KM8Q2FQ3FGBZQGNJVFNA9F66E6S3P36KTMWMKWDXWM9EX1YHSHQ841AHRR8JVDY96CZ13AJF6JW95K59AE8CSTH5ZS9NVS0102X92GK8JW2QX2S4EE25QNHK6XMXH3944QMXPFS7SFCMV623BM62VNPVX8JM424YXPJ09TXZAH2CF3QM5HDVRSTDRDGVBF6KZVRFM852TMVMYPVGFA9YQF6HWNJ8H5VCQ3Z9WWNMQ3T76X4F1P6W2J266K8B3W9HKW2WJNK3XHRAVC4GCF07TC0ZNAT0EDAAKV429YAXWSK952BPTY98GVP5XZQG2SE0Q5CF3PV04002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "2SDD44VVBD52XEV0A9R878BC60J51VKK0H5ZS6CPJ7Z738A8V4KPXCF70KFZAY2567400C2GEWNNVXF6PYD7HKX3D2M63WCNPJSE010"
+ ),
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:2"),
+ denom_pub = "040000XV91V0M7H906Y7R371YX2XAK1V5B2TRFD8ZM9WYJ495TP08NCVEDNFXS2KZBJR4808VZ52PNNQSYVQ2T3J7867MZQY1QZ9N8YQWQWCKSYAY8A07E5SYAK0G0KRTCN5VZ7JXE2YCNT7Q3RT9TGAZBSK5V1ZRRK6HX4C1YFKPWWP4TBVJ8DJMS43WKR4CR4S9T02YXVGR6GSDMR7GHBD89JHCEQ8V2K58Y5XVDGRRQYNBG9Q5XWDMV7GKN24JCPCEKSZZP5XYPXYJX2Z2JZ179M9FQV0PEWFJ4DP7AP14XE54FH97YP9398KA31ECVDY7PHMKMZ6E79Z9FSCXH3WSCXMHBWFGWPRG5ZG1P6HR71VKH4F0Y998JNE4G40JH2VSXP3035AR7HAMJGB56CYHH60EWD904002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "WX1RDTW1W1K7FPFQQ9MCJ8V5CJP8ZX2SGHQG2YS34BY8AMSR3YQ92HE2HT1JMP4W06J63RZ0BR2MKDBX54GV6QKD4R00N9HXN2S283R"
+ ),
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:1"),
+ denom_pub = "040000XCBJE9TDDZATYSDR51D0DKMY5NW8FMJ8YQ1Y4F40SPPTKFMD3FWH38NSQZ1YB621TCFH5RBN5J3SFR5SG4789G27FA90E605GG9AXYTXXPJ9HYPAVAVS6V4XCSC17HKX2M2NSX5D0PPETDGKQD04G498VS36YY4WTB5SYG4SV9MKPVZ5WG2WNP3MA77TFZSHK5HBHZBEW0S1TRKGSCDNBRHYB240M84YM1Y7EJ7BXKJK4GRR1GS16DJ2RA1YEQ1AAXH0GP6RRAEJE8D2JFSH05P3KR1GB97NMX6VD8DCAX45416F888EYQR4M6R820FJVZ6FYV9CCMZ3M10B64N6G4QFNKFNAV2ENPVVG4A3R0AAA6STJ7E5Z05GEKW35SHM14HY9CEGM7D1ZEKHZJYA9P6WH504002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "65G9FWQPA4YKJEM7D37079D4MY81D47KD1280RG7BRH85XZQ2N13FJPV9N8AEASK9CTGNX1HKX0GTRBJ5C49H4YRY0E4CYVPNH06W18"
+ ),
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:10"),
+ denom_pub = "040000XZDZK4BPPPXR7MYKK2AF4WF95EH3VF8WEX7WDX4HEWXSB5XX10N4V5RHFSK0TSBKNC9CRNVGK3WJ42S3Z9SB4Q3M4DQQ7DKCGKED6WBKENHT8JX51K1VR5JKCMAFBNM6DR5MNRGKFC2MDRQ0Y4BCXHKEMRD65C6JPBKYW9HJH66FGT22WMBV0AV7P60CKR13MQG6FKWW3TZW3XXHVY2VX9MJN6VQFPS6NQGGTNXZV2SK2X5MJAJME7RN9BNZ5ZBTW1CYMVCHBSVGBFPRC68W78PW44VP402VD12KG2AWKPD4DRBAA85HM1DN1KADYQ498QHYGEB3T3HH990HRV8PSNBGYCHB87JTVYMJ4N2PSP2FCX0H6FRTW1FQY05EB7D8BFXM95DNRCHVQSHBZ9RP7NZFA304002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "M423J7CJPACTPBYCFVR87B44JAJKAB2ME8C263WGHJSA8V8444SX428MVC9NF4GD08CKS9HY0WB4B8SEZ3HJFWKXNSH80RBJXQC822G"
+ ),
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:0.1"),
+ denom_pub = "040000YKYFF6GX979JS10MEZ16BQ7TT6XBTE0TBX6VJ9KSG7K4D91SWJVDETNKQJXAFK9SAB3S31FZFA0Y0X22TKRXKCT7Z4GZCCRJJ12T1A5M4DWRTZDFRD3FE495NXHVPFM96KXMKH1HABTDDFZN0NWQ3NBJ6GNXD40NJ95E955X948JHBDJZWM3TEAK4XFJX8056XFDHVNXSF4VN14RR1WD1J5K7JPS61SKRNF3HT6NZA823PZW2KPV2KVBMMP615A922ZNJGVQDTW5TYWTK5DCBGG1YEKQRYF39NX9X722FZK98BTMHHH6WZFCKBT096G9BKSHSJW3VE8KKPCN8XGWYYPD3158HRKSA28BJQ9XJVVB6FDCGZ154WWGGSGW82BDYDH7ZHJBMS046AG0ND4ZCVR2JQ04002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "RKZKGR0KYKY0VZ26339DZKV8EZJ2HRRQMFSAJDHBG3YHEQNZFHKM8WPYCH9WHXTWBB10GQN9QJKFDJJF2H6D5FT801GF87G153PTJ18"
+ ),
+ Denomination(
+ value = Amount.fromJSONString("TESTKUDOS:1000"),
+ denom_pub = "040000Y9PBY1HPBDD4KSK9PBA86TRY13JQ4284T4E0G4SEREQ8YM88PZHKW1ACKT1RTWVTBXX83G54NFVYRJQX9PTDXDJ1CXSS42G8NYMW97NA6NNNASV69W1JX39NTS1NVKXPW4WMBASATSNBTXHRT92FFN2NAJFGK876BNN3TPTH57C76ADAQV43VFF7CYAWWNYZAYGQQ1XY1NK34FJD778VFGYCZ1G9J8XPNB92ZKJBZEZKSNBRNH27GM5A736AFSGP7B4JSCGD0F4FMD1PDVB26MM9ZK8C1TDKXQ5DJ09AQQ55P7Q3A133ASPGBH6SCJTJYH8C9A451B0SP4GDX2ZFRSX5FP93PY4VKEB36KCAQ5E2MRZNWFB6T0JK0W7Z7NXP5FW2VQ4PNV7B2NQ3WFMCVRSDSV04002",
+ fee_withdraw = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_deposit = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refresh = Amount.fromJSONString("TESTKUDOS:0.01"),
+ fee_refund = Amount.fromJSONString("TESTKUDOS:0.01"),
+ stamp_start = Timestamp(1582484881000),
+ stamp_expire_withdraw = Timestamp(1677092881000),
+ stamp_expire_legal = Timestamp(1897844881000),
+ stamp_expire_deposit = Timestamp(1740164881000),
+ master_sig = "FJPQKECRKVQSTB9Y983KDGD65Z1JHQKNSCC6YPMBN3Z4VW0AGC5MQM9BPB0YYD1SCMETPD6QB4X80HWE0ZDGWNZB1KND5TP567T4G3G"
+ )
+ ),
+ master_public_key = "DY95EXAHQ2BKM2WK9YHZHYG1R7PPMMJPY14FNGP662DAKE35AKQG",
+ auditors = emptyList(),
+ list_issue_date = Timestamp(1592161681000),
+ recoup = emptyList(),
+ signkeys = listOf(
+ SigningKey(
+ stamp_start = Timestamp(1592161681000),
+ stamp_expire = Timestamp(1594580881000),
+ stamp_end = Timestamp(1655233681000),
+ key = "0FMRBH8FZYYMSQ2RHTYYGK2BV33JVSW6MTYCV7Y833GVNXFDYK10",
+ master_sig = "368HV41Z4FNDXQ7EP6TNAMBSKP44PJAZW27EPH7XJNVG2A6HZQM7ZPMCB6B30HG50S95YD1K2BAJVPEYMGF2DR7EEY0NFBQZZ1B8P1G"
+ ),
+ SigningKey(
+ stamp_start = Timestamp(1594580881000),
+ stamp_expire = Timestamp(1597000081000),
+ stamp_end = Timestamp(1657652881000),
+ key = "XMNYM62DQW0XDQACCYDMFTM5GY7SZST60NH7XS9GY18H8Q9N7QN0",
+ master_sig = "4HRJN36VVJ87ZC2HZXP7QDSZN30YQE8FCNWZS3RCA1HGNY9Q0JPMVJZ79RDHKS4GYXV29PM27DGCN0VB0BCZFF2FC6FMF3A6ZNKC238"
+ )
+ ),
+ version = "7:0:0"
+ )
+
+ httpClient.giveJsonResponse("https://exchange.test.taler.net/keys") {
+ """{
+ "version": "7:0:0",
+ "master_public_key": "DY95EXAHQ2BKM2WK9YHZHYG1R7PPMMJPY14FNGP662DAKE35AKQG",
+ "reserve_closing_delay": {
+ "d_ms": 2419200000
+ },
+ "signkeys": [
+ {
+ "stamp_start": {
+ "t_ms": 1592161681000
+ },
+ "stamp_expire": {
+ "t_ms": 1594580881000
+ },
+ "stamp_end": {
+ "t_ms": 1655233681000
+ },
+ "master_sig": "368HV41Z4FNDXQ7EP6TNAMBSKP44PJAZW27EPH7XJNVG2A6HZQM7ZPMCB6B30HG50S95YD1K2BAJVPEYMGF2DR7EEY0NFBQZZ1B8P1G",
+ "key": "0FMRBH8FZYYMSQ2RHTYYGK2BV33JVSW6MTYCV7Y833GVNXFDYK10"
+ },
+ {
+ "stamp_start": {
+ "t_ms": 1594580881000
+ },
+ "stamp_expire": {
+ "t_ms": 1597000081000
+ },
+ "stamp_end": {
+ "t_ms": 1657652881000
+ },
+ "master_sig": "4HRJN36VVJ87ZC2HZXP7QDSZN30YQE8FCNWZS3RCA1HGNY9Q0JPMVJZ79RDHKS4GYXV29PM27DGCN0VB0BCZFF2FC6FMF3A6ZNKC238",
+ "key": "XMNYM62DQW0XDQACCYDMFTM5GY7SZST60NH7XS9GY18H8Q9N7QN0"
+ }
+ ],
+ "recoup": [],
+ "denoms": [
+ {
+ "master_sig": "2SDD44VVBD52XEV0A9R878BC60J51VKK0H5ZS6CPJ7Z738A8V4KPXCF70KFZAY2567400C2GEWNNVXF6PYD7HKX3D2M63WCNPJSE010",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000Z9TH9RPTA1BXF6Z89HM7JGXTPD5G8NNBWQWF7RWQGNAATN84QBWME1TGSWZ79WPQ62S2W2VHG2XBH66JDJ0KM8Q2FQ3FGBZQGNJVFNA9F66E6S3P36KTMWMKWDXWM9EX1YHSHQ841AHRR8JVDY96CZ13AJF6JW95K59AE8CSTH5ZS9NVS0102X92GK8JW2QX2S4EE25QNHK6XMXH3944QMXPFS7SFCMV623BM62VNPVX8JM424YXPJ09TXZAH2CF3QM5HDVRSTDRDGVBF6KZVRFM852TMVMYPVGFA9YQF6HWNJ8H5VCQ3Z9WWNMQ3T76X4F1P6W2J266K8B3W9HKW2WJNK3XHRAVC4GCF07TC0ZNAT0EDAAKV429YAXWSK952BPTY98GVP5XZQG2SE0Q5CF3PV04002",
+ "value": "TESTKUDOS:5",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ },
+ {
+ "master_sig": "WX1RDTW1W1K7FPFQQ9MCJ8V5CJP8ZX2SGHQG2YS34BY8AMSR3YQ92HE2HT1JMP4W06J63RZ0BR2MKDBX54GV6QKD4R00N9HXN2S283R",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000XV91V0M7H906Y7R371YX2XAK1V5B2TRFD8ZM9WYJ495TP08NCVEDNFXS2KZBJR4808VZ52PNNQSYVQ2T3J7867MZQY1QZ9N8YQWQWCKSYAY8A07E5SYAK0G0KRTCN5VZ7JXE2YCNT7Q3RT9TGAZBSK5V1ZRRK6HX4C1YFKPWWP4TBVJ8DJMS43WKR4CR4S9T02YXVGR6GSDMR7GHBD89JHCEQ8V2K58Y5XVDGRRQYNBG9Q5XWDMV7GKN24JCPCEKSZZP5XYPXYJX2Z2JZ179M9FQV0PEWFJ4DP7AP14XE54FH97YP9398KA31ECVDY7PHMKMZ6E79Z9FSCXH3WSCXMHBWFGWPRG5ZG1P6HR71VKH4F0Y998JNE4G40JH2VSXP3035AR7HAMJGB56CYHH60EWD904002",
+ "value": "TESTKUDOS:2",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ },
+ {
+ "master_sig": "65G9FWQPA4YKJEM7D37079D4MY81D47KD1280RG7BRH85XZQ2N13FJPV9N8AEASK9CTGNX1HKX0GTRBJ5C49H4YRY0E4CYVPNH06W18",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000XCBJE9TDDZATYSDR51D0DKMY5NW8FMJ8YQ1Y4F40SPPTKFMD3FWH38NSQZ1YB621TCFH5RBN5J3SFR5SG4789G27FA90E605GG9AXYTXXPJ9HYPAVAVS6V4XCSC17HKX2M2NSX5D0PPETDGKQD04G498VS36YY4WTB5SYG4SV9MKPVZ5WG2WNP3MA77TFZSHK5HBHZBEW0S1TRKGSCDNBRHYB240M84YM1Y7EJ7BXKJK4GRR1GS16DJ2RA1YEQ1AAXH0GP6RRAEJE8D2JFSH05P3KR1GB97NMX6VD8DCAX45416F888EYQR4M6R820FJVZ6FYV9CCMZ3M10B64N6G4QFNKFNAV2ENPVVG4A3R0AAA6STJ7E5Z05GEKW35SHM14HY9CEGM7D1ZEKHZJYA9P6WH504002",
+ "value": "TESTKUDOS:1",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ },
+ {
+ "master_sig": "M423J7CJPACTPBYCFVR87B44JAJKAB2ME8C263WGHJSA8V8444SX428MVC9NF4GD08CKS9HY0WB4B8SEZ3HJFWKXNSH80RBJXQC822G",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000XZDZK4BPPPXR7MYKK2AF4WF95EH3VF8WEX7WDX4HEWXSB5XX10N4V5RHFSK0TSBKNC9CRNVGK3WJ42S3Z9SB4Q3M4DQQ7DKCGKED6WBKENHT8JX51K1VR5JKCMAFBNM6DR5MNRGKFC2MDRQ0Y4BCXHKEMRD65C6JPBKYW9HJH66FGT22WMBV0AV7P60CKR13MQG6FKWW3TZW3XXHVY2VX9MJN6VQFPS6NQGGTNXZV2SK2X5MJAJME7RN9BNZ5ZBTW1CYMVCHBSVGBFPRC68W78PW44VP402VD12KG2AWKPD4DRBAA85HM1DN1KADYQ498QHYGEB3T3HH990HRV8PSNBGYCHB87JTVYMJ4N2PSP2FCX0H6FRTW1FQY05EB7D8BFXM95DNRCHVQSHBZ9RP7NZFA304002",
+ "value": "TESTKUDOS:10",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ },
+ {
+ "master_sig": "RKZKGR0KYKY0VZ26339DZKV8EZJ2HRRQMFSAJDHBG3YHEQNZFHKM8WPYCH9WHXTWBB10GQN9QJKFDJJF2H6D5FT801GF87G153PTJ18",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000YKYFF6GX979JS10MEZ16BQ7TT6XBTE0TBX6VJ9KSG7K4D91SWJVDETNKQJXAFK9SAB3S31FZFA0Y0X22TKRXKCT7Z4GZCCRJJ12T1A5M4DWRTZDFRD3FE495NXHVPFM96KXMKH1HABTDDFZN0NWQ3NBJ6GNXD40NJ95E955X948JHBDJZWM3TEAK4XFJX8056XFDHVNXSF4VN14RR1WD1J5K7JPS61SKRNF3HT6NZA823PZW2KPV2KVBMMP615A922ZNJGVQDTW5TYWTK5DCBGG1YEKQRYF39NX9X722FZK98BTMHHH6WZFCKBT096G9BKSHSJW3VE8KKPCN8XGWYYPD3158HRKSA28BJQ9XJVVB6FDCGZ154WWGGSGW82BDYDH7ZHJBMS046AG0ND4ZCVR2JQ04002",
+ "value": "TESTKUDOS:0.1",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ },
+ {
+ "master_sig": "FJPQKECRKVQSTB9Y983KDGD65Z1JHQKNSCC6YPMBN3Z4VW0AGC5MQM9BPB0YYD1SCMETPD6QB4X80HWE0ZDGWNZB1KND5TP567T4G3G",
+ "stamp_start": {
+ "t_ms": 1582484881000
+ },
+ "stamp_expire_withdraw": {
+ "t_ms": 1677092881000
+ },
+ "stamp_expire_deposit": {
+ "t_ms": 1740164881000
+ },
+ "stamp_expire_legal": {
+ "t_ms": 1897844881000
+ },
+ "denom_pub": "040000Y9PBY1HPBDD4KSK9PBA86TRY13JQ4284T4E0G4SEREQ8YM88PZHKW1ACKT1RTWVTBXX83G54NFVYRJQX9PTDXDJ1CXSS42G8NYMW97NA6NNNASV69W1JX39NTS1NVKXPW4WMBASATSNBTXHRT92FFN2NAJFGK876BNN3TPTH57C76ADAQV43VFF7CYAWWNYZAYGQQ1XY1NK34FJD778VFGYCZ1G9J8XPNB92ZKJBZEZKSNBRNH27GM5A736AFSGP7B4JSCGD0F4FMD1PDVB26MM9ZK8C1TDKXQ5DJ09AQQ55P7Q3A133ASPGBH6SCJTJYH8C9A451B0SP4GDX2ZFRSX5FP93PY4VKEB36KCAQ5E2MRZNWFB6T0JK0W7Z7NXP5FW2VQ4PNV7B2NQ3WFMCVRSDSV04002",
+ "value": "TESTKUDOS:1000",
+ "fee_withdraw": "TESTKUDOS:0.01",
+ "fee_deposit": "TESTKUDOS:0.01",
+ "fee_refresh": "TESTKUDOS:0.01",
+ "fee_refund": "TESTKUDOS:0.01"
+ }
+ ],
+ "auditors": [],
+ "list_issue_date": {
+ "t_ms": 1592161681000
+ },
+ "eddsa_pub": "0FMRBH8FZYYMSQ2RHTYYGK2BV33JVSW6MTYCV7Y833GVNXFDYK10",
+ "eddsa_sig": "2GB384567SZM9CM7RJT51N04D2ZK7NAHWZRT6BA0FFNXTAB71D4T1WVQTXZEPDM07X1MJ46ZBC189SCM4EG4V8TQJRP2WAZCKPAJJ2R"
+ }""".trimIndent()
+ }
+ runCoroutine {
+ val keys = Keys.fetch(httpClient, "https://exchange.test.taler.net/")
+ assertEquals(expectedKeys, keys)
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/UpdateTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/UpdateTest.kt
new file mode 100644
index 0000000..15e6d80
--- /dev/null
+++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/UpdateTest.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.lib.wallet.exchange
+
+import net.taler.lib.wallet.runCoroutine
+import kotlin.test.Ignore
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+class UpdateTest {
+
+ private val exchange = Exchange()
+
+ @Ignore // live test that requires internet connectivity
+ @Test
+ fun testLiveUpdate() {
+ runCoroutine {
+ val record = exchange.updateFromUrl("http://exchange.test.taler.net/")
+ assertTrue(record.addComplete)
+ }
+ }
+
+}
diff --git a/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt
new file mode 100644
index 0000000..16671a9
--- /dev/null
+++ b/wallet/src/commonTest/kotlin/net/taler/lib/wallet/exchange/WireTest.kt
@@ -0,0 +1,175 @@
+/*
+ * 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.lib.wallet.exchange
+
+import net.taler.lib.common.Amount
+import net.taler.lib.common.Timestamp
+import net.taler.lib.wallet.getMockHttpClient
+import net.taler.lib.wallet.giveJsonResponse
+import net.taler.lib.wallet.runCoroutine
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class WireTest {
+
+ private val httpClient = getMockHttpClient()
+
+ @Test
+ fun testFetchWire() {
+ val expectedWire = Wire(
+ accounts = listOf(
+ AccountInfo(
+ paytoUri = "payto://x-taler-bank/bank.test.taler.net/Exchange",
+ masterSig = "5DMYMQCEFWG7B21RAX8XQ585V689K8DSSR065F04E2JK6G9AF1WM8EVDCHHBMVWRY3P02EWEE4M6YVKPY6B43H2CPCWHDP13RM1WR10"
+ )
+ ),
+ fees = mapOf(
+ "x-taler-bank" to listOf(
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.04"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1577833200000),
+ endStamp = Timestamp(1609455600000),
+ signature = "9DS6TXPTM8ZBBTJS9VCRSD9FVS56ZY9EVWCF4HDA3Y2DNWSVMGS7XXPWE295EZ3E98KVV1SWDJ11CP0A0VDSRDZTM6RD2RPRG19ZA2G"
+ ),
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.04"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1609455600000),
+ endStamp = Timestamp(1640991600000),
+ signature = "81852REBNR3ZRQHKQ2FPT6CPACED0MA0CW4V9CPDS3NP2JX6X8BE5YE5W1AKR9XPASEXSKQH6FEXHP7VJB64XWA7FDGH5DKCD3Q700G"
+ ),
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.05"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1640991600000),
+ endStamp = Timestamp(1672527600000),
+ signature = "REYMSGH4QBNF339Q8TD5VJMMY6BV7KFTC1Y69YD69Y9E8Z5HXGNAKCQKT490MHBSF48894YADT1ATGDMSRZAQJJFVXF6HX9JEYDT61G"
+ ),
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.06"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1672527600000),
+ endStamp = Timestamp(1704063600000),
+ signature = "BXB47D936XT7XDHGA3VA3461CY1GMQWFPVMSBY01N5SN6PBCGYRS8HSY19FJ0P5HVX3TGS9TAHY9X7RP4BQHPM4DMMS30TJ0EKG5A3G"
+ ),
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.07"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1704063600000),
+ endStamp = Timestamp(1735686000000),
+ signature = "RFF1KV54BH9TJ8KBE8YEY8DM0R468PZYGW82G16P97EDHNN3XZVN4KK5E9CBZQ730WPJT0RKR3TTYPBWGTR0YQ064XZZDHJHHZN1418"
+ ),
+ WireFee(
+ wireFee = Amount.fromJSONString("TESTKUDOS:0.08"),
+ closingFee = Amount.fromJSONString("TESTKUDOS:0.01"),
+ startStamp = Timestamp(1735686000000),
+ endStamp = Timestamp(1767222000000),
+ signature = "Q89VKJ54MF3DVG0NKK4N6VB96NCT0PRSTNBJ0SSB42SQTHB10JC68XJSDM6PRBBPEJ8CHDE9VVRZWW20VFSZFDTRA332JKDSBBFWY1G"
+ )
+ )
+ )
+ )
+ httpClient.giveJsonResponse("https://exchange.test.taler.net/wire") {
+ """{
+ "accounts": [
+ {
+ "payto_uri": "payto://x-taler-bank/bank.test.taler.net/Exchange",
+ "master_sig": "5DMYMQCEFWG7B21RAX8XQ585V689K8DSSR065F04E2JK6G9AF1WM8EVDCHHBMVWRY3P02EWEE4M6YVKPY6B43H2CPCWHDP13RM1WR10"
+ }
+ ],
+ "fees": {
+ "x-taler-bank": [
+ {
+ "wire_fee": "TESTKUDOS:0.04",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1577833200000
+ },
+ "end_date": {
+ "t_ms": 1609455600000
+ },
+ "sig": "9DS6TXPTM8ZBBTJS9VCRSD9FVS56ZY9EVWCF4HDA3Y2DNWSVMGS7XXPWE295EZ3E98KVV1SWDJ11CP0A0VDSRDZTM6RD2RPRG19ZA2G"
+ },
+ {
+ "wire_fee": "TESTKUDOS:0.04",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1609455600000
+ },
+ "end_date": {
+ "t_ms": 1640991600000
+ },
+ "sig": "81852REBNR3ZRQHKQ2FPT6CPACED0MA0CW4V9CPDS3NP2JX6X8BE5YE5W1AKR9XPASEXSKQH6FEXHP7VJB64XWA7FDGH5DKCD3Q700G"
+ },
+ {
+ "wire_fee": "TESTKUDOS:0.05",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1640991600000
+ },
+ "end_date": {
+ "t_ms": 1672527600000
+ },
+ "sig": "REYMSGH4QBNF339Q8TD5VJMMY6BV7KFTC1Y69YD69Y9E8Z5HXGNAKCQKT490MHBSF48894YADT1ATGDMSRZAQJJFVXF6HX9JEYDT61G"
+ },
+ {
+ "wire_fee": "TESTKUDOS:0.06",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1672527600000
+ },
+ "end_date": {
+ "t_ms": 1704063600000
+ },
+ "sig": "BXB47D936XT7XDHGA3VA3461CY1GMQWFPVMSBY01N5SN6PBCGYRS8HSY19FJ0P5HVX3TGS9TAHY9X7RP4BQHPM4DMMS30TJ0EKG5A3G"
+ },
+ {
+ "wire_fee": "TESTKUDOS:0.07",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1704063600000
+ },
+ "end_date": {
+ "t_ms": 1735686000000
+ },
+ "sig": "RFF1KV54BH9TJ8KBE8YEY8DM0R468PZYGW82G16P97EDHNN3XZVN4KK5E9CBZQ730WPJT0RKR3TTYPBWGTR0YQ064XZZDHJHHZN1418"
+ },
+ {
+ "wire_fee": "TESTKUDOS:0.08",
+ "closing_fee": "TESTKUDOS:0.01",
+ "start_date": {
+ "t_ms": 1735686000000
+ },
+ "end_date": {
+ "t_ms": 1767222000000
+ },
+ "sig": "Q89VKJ54MF3DVG0NKK4N6VB96NCT0PRSTNBJ0SSB42SQTHB10JC68XJSDM6PRBBPEJ8CHDE9VVRZWW20VFSZFDTRA332JKDSBBFWY1G"
+ }
+ ]
+ },
+ "master_public_key": "DY95EXAHQ2BKM2WK9YHZHYG1R7PPMMJPY14FNGP662DAKE35AKQG"
+ }""".trimIndent()
+ }
+
+ runCoroutine {
+ val wire = Wire.fetch(httpClient, "https://exchange.test.taler.net/")
+ assertEquals(expectedWire, wire)
+ }
+ }
+
+}