summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-08-30 17:08:54 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-08-30 17:08:54 +0200
commit008926b18470e7f394cd640302957b29728a9803 (patch)
tree45f914f5117116bb3af5010f9e7570e99b015952
parent24e021fef360448caf11ab5a489b570102e66f6f (diff)
downloadwallet-core-008926b18470e7f394cd640302957b29728a9803.tar.gz
wallet-core-008926b18470e7f394cd640302957b29728a9803.tar.bz2
wallet-core-008926b18470e7f394cd640302957b29728a9803.zip
compute full fees for refresh and spending
-rw-r--r--src/crypto/cryptoApi.ts5
-rw-r--r--src/crypto/cryptoWorker.ts4
-rw-r--r--src/i18n/de.po97
-rw-r--r--src/i18n/en-US.po83
-rw-r--r--src/i18n/fr.po83
-rw-r--r--src/i18n/it.po83
-rw-r--r--src/i18n/strings.ts60
-rw-r--r--src/i18n/taler-wallet-webex.pot83
-rw-r--r--src/types.ts36
-rw-r--r--src/wallet-test.ts34
-rw-r--r--src/wallet.ts186
-rw-r--r--src/webex/messages.ts6
-rw-r--r--src/webex/pages/confirm-contract.html1
-rw-r--r--src/webex/pages/confirm-contract.tsx43
-rw-r--r--src/webex/pages/refund.tsx17
-rw-r--r--src/webex/renderHtml.tsx32
-rw-r--r--src/webex/wxApi.ts5
-rw-r--r--src/webex/wxBackend.ts2
18 files changed, 478 insertions, 382 deletions
diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts
index 227c3d346..00013f0d3 100644
--- a/src/crypto/cryptoApi.ts
+++ b/src/crypto/cryptoApi.ts
@@ -26,6 +26,7 @@
import {
AmountJson,
CoinRecord,
+ CoinWithDenom,
ContractTerms,
DenominationRecord,
PayCoinInfo,
@@ -36,10 +37,6 @@ import {
WireFee,
} from "../types";
-import {
- CoinWithDenom,
-} from "../wallet";
-
import * as timer from "../timer";
import { startWorker } from "./startWorker";
diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts
index 1db6e62d5..92b766e9c 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -28,6 +28,7 @@ import {
CoinPaySig,
CoinRecord,
CoinStatus,
+ CoinWithDenom,
ContractTerms,
DenominationRecord,
PayCoinInfo,
@@ -41,9 +42,6 @@ import {
import {
canonicalJson,
} from "../helpers";
-import {
- CoinWithDenom,
-} from "../wallet";
import {
Amount,
diff --git a/src/i18n/de.po b/src/i18n/de.po
index cb57219c5..38ce00c45 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -27,28 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/webex/pages/confirm-contract.tsx:69
+#: src/webex/pages/confirm-contract.tsx:70
#, c-format
msgid "show more details\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:83
+#: src/webex/pages/confirm-contract.tsx:84
#, c-format
msgid "Accepted exchanges:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:88
+#: src/webex/pages/confirm-contract.tsx:89
#, c-format
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:154
+#: src/webex/pages/confirm-contract.tsx:156
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:156
+#: src/webex/pages/confirm-contract.tsx:158
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,67 +56,77 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:213
+#: src/webex/pages/confirm-contract.tsx:214
+#, c-format
+msgid "The merchant%1$s offers you to purchase:\n"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:232
+#, fuzzy, c-format
+msgid "Confirm payment"
+msgstr "Bezahlung bestätigen"
+
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, fuzzy, c-format
msgid "Withdrawal fees:"
msgstr "Abheben bei %1$s"
-#: src/webex/pages/confirm-create-reserve.tsx:214
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:215
+#: src/webex/pages/confirm-create-reserve.tsx:181
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:220
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:221
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:222
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, fuzzy, c-format
msgid "Withdraw Fee"
msgstr "Abheben bei %1$s"
-#: src/webex/pages/confirm-create-reserve.tsx:223
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:224
+#: src/webex/pages/confirm-create-reserve.tsx:190
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:278
+#: src/webex/pages/confirm-create-reserve.tsx:244
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:294
+#: src/webex/pages/confirm-create-reserve.tsx:260
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:362
+#: src/webex/pages/confirm-create-reserve.tsx:328
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:368
+#: src/webex/pages/confirm-create-reserve.tsx:334
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:374
+#: src/webex/pages/confirm-create-reserve.tsx:340
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -124,7 +134,7 @@ msgid ""
"If you withdraw from this exchange, it will be trusted in the future.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:383
+#: src/webex/pages/confirm-create-reserve.tsx:349
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -132,63 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:397
+#: src/webex/pages/confirm-create-reserve.tsx:363
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:408
-#, c-format
-msgid "A problem occured, see below. %1$s"
-msgstr ""
-
-#: src/webex/pages/confirm-create-reserve.tsx:414
+#: src/webex/pages/confirm-create-reserve.tsx:380
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:457
+#: src/webex/pages/confirm-create-reserve.tsx:423
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:462
+#: src/webex/pages/confirm-create-reserve.tsx:428
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:519
+#: src/webex/pages/confirm-create-reserve.tsx:485
#, c-format
msgid "You are about to withdraw %1$s from your bank account into your wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:607
+#: src/webex/pages/confirm-create-reserve.tsx:570
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:616
+#: src/webex/pages/confirm-create-reserve.tsx:579
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:630
+#: src/webex/pages/confirm-create-reserve.tsx:593
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:637
+#: src/webex/pages/confirm-create-reserve.tsx:600
#, c-format
msgid "Can't parse wire_types: %1$s"
msgstr ""
#. TODO:generic error reporting function or component.
-#: src/webex/pages/confirm-create-reserve.tsx:663
+#: src/webex/pages/confirm-create-reserve.tsx:626
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -311,19 +316,6 @@ msgstr "Bezahlung bestätigen"
msgid "Cancel"
msgstr "Saldo"
-#: src/webex/renderHtml.tsx:51
-#, fuzzy, c-format
-msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
-msgstr ""
-"%1$s\n"
-" möchte einen Vertrag über %2$s\n"
-" mit Ihnen abschließen."
-
-#: src/webex/renderHtml.tsx:56
-#, fuzzy, c-format
-msgid "You are about to purchase:"
-msgstr "Sie sind dabei, Folgendes zu kaufen:"
-
#: src/wire.ts:38
#, c-format
msgid "Invalid Wire"
@@ -345,6 +337,17 @@ msgid "Unknown Wire Detail"
msgstr ""
#, fuzzy
+#~ msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
+#~ msgstr ""
+#~ "%1$s\n"
+#~ " möchte einen Vertrag über %2$s\n"
+#~ " mit Ihnen abschließen."
+
+#, fuzzy
+#~ msgid "You are about to purchase:"
+#~ msgstr "Sie sind dabei, Folgendes zu kaufen:"
+
+#, fuzzy
#~ msgid "Withdrawal fees: %1$s"
#~ msgstr "Abheben bei %1$s"
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index a39c8331a..66d4bd118 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -27,28 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/webex/pages/confirm-contract.tsx:69
+#: src/webex/pages/confirm-contract.tsx:70
#, c-format
msgid "show more details\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:83
+#: src/webex/pages/confirm-contract.tsx:84
#, c-format
msgid "Accepted exchanges:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:88
+#: src/webex/pages/confirm-contract.tsx:89
#, c-format
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:154
+#: src/webex/pages/confirm-contract.tsx:156
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:156
+#: src/webex/pages/confirm-contract.tsx:158
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,67 +56,77 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:213
+#: src/webex/pages/confirm-contract.tsx:214
+#, c-format
+msgid "The merchant%1$s offers you to purchase:\n"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:232
+#, c-format
+msgid "Confirm payment"
+msgstr ""
+
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:214
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:215
+#: src/webex/pages/confirm-create-reserve.tsx:181
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:220
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:221
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:222
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:223
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:224
+#: src/webex/pages/confirm-create-reserve.tsx:190
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:278
+#: src/webex/pages/confirm-create-reserve.tsx:244
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:294
+#: src/webex/pages/confirm-create-reserve.tsx:260
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:362
+#: src/webex/pages/confirm-create-reserve.tsx:328
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:368
+#: src/webex/pages/confirm-create-reserve.tsx:334
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:374
+#: src/webex/pages/confirm-create-reserve.tsx:340
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -124,7 +134,7 @@ msgid ""
"If you withdraw from this exchange, it will be trusted in the future.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:383
+#: src/webex/pages/confirm-create-reserve.tsx:349
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -132,63 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:397
+#: src/webex/pages/confirm-create-reserve.tsx:363
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:408
-#, c-format
-msgid "A problem occured, see below. %1$s"
-msgstr ""
-
-#: src/webex/pages/confirm-create-reserve.tsx:414
+#: src/webex/pages/confirm-create-reserve.tsx:380
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:457
+#: src/webex/pages/confirm-create-reserve.tsx:423
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:462
+#: src/webex/pages/confirm-create-reserve.tsx:428
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:519
+#: src/webex/pages/confirm-create-reserve.tsx:485
#, c-format
msgid "You are about to withdraw %1$s from your bank account into your wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:607
+#: src/webex/pages/confirm-create-reserve.tsx:570
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:616
+#: src/webex/pages/confirm-create-reserve.tsx:579
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:630
+#: src/webex/pages/confirm-create-reserve.tsx:593
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:637
+#: src/webex/pages/confirm-create-reserve.tsx:600
#, c-format
msgid "Can't parse wire_types: %1$s"
msgstr ""
#. TODO:generic error reporting function or component.
-#: src/webex/pages/confirm-create-reserve.tsx:663
+#: src/webex/pages/confirm-create-reserve.tsx:626
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -311,16 +316,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: src/webex/renderHtml.tsx:51
-#, c-format
-msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
-msgstr ""
-
-#: src/webex/renderHtml.tsx:56
-#, c-format
-msgid "You are about to purchase:"
-msgstr ""
-
#: src/wire.ts:38
#, c-format
msgid "Invalid Wire"
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index dc271a749..d804bd204 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -27,28 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/webex/pages/confirm-contract.tsx:69
+#: src/webex/pages/confirm-contract.tsx:70
#, c-format
msgid "show more details\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:83
+#: src/webex/pages/confirm-contract.tsx:84
#, c-format
msgid "Accepted exchanges:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:88
+#: src/webex/pages/confirm-contract.tsx:89
#, c-format
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:154
+#: src/webex/pages/confirm-contract.tsx:156
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:156
+#: src/webex/pages/confirm-contract.tsx:158
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,67 +56,77 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:213
+#: src/webex/pages/confirm-contract.tsx:214
+#, c-format
+msgid "The merchant%1$s offers you to purchase:\n"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:232
+#, c-format
+msgid "Confirm payment"
+msgstr ""
+
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:214
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:215
+#: src/webex/pages/confirm-create-reserve.tsx:181
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:220
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:221
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:222
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:223
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:224
+#: src/webex/pages/confirm-create-reserve.tsx:190
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:278
+#: src/webex/pages/confirm-create-reserve.tsx:244
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:294
+#: src/webex/pages/confirm-create-reserve.tsx:260
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:362
+#: src/webex/pages/confirm-create-reserve.tsx:328
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:368
+#: src/webex/pages/confirm-create-reserve.tsx:334
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:374
+#: src/webex/pages/confirm-create-reserve.tsx:340
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -124,7 +134,7 @@ msgid ""
"If you withdraw from this exchange, it will be trusted in the future.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:383
+#: src/webex/pages/confirm-create-reserve.tsx:349
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -132,63 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:397
+#: src/webex/pages/confirm-create-reserve.tsx:363
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:408
-#, c-format
-msgid "A problem occured, see below. %1$s"
-msgstr ""
-
-#: src/webex/pages/confirm-create-reserve.tsx:414
+#: src/webex/pages/confirm-create-reserve.tsx:380
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:457
+#: src/webex/pages/confirm-create-reserve.tsx:423
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:462
+#: src/webex/pages/confirm-create-reserve.tsx:428
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:519
+#: src/webex/pages/confirm-create-reserve.tsx:485
#, c-format
msgid "You are about to withdraw %1$s from your bank account into your wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:607
+#: src/webex/pages/confirm-create-reserve.tsx:570
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:616
+#: src/webex/pages/confirm-create-reserve.tsx:579
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:630
+#: src/webex/pages/confirm-create-reserve.tsx:593
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:637
+#: src/webex/pages/confirm-create-reserve.tsx:600
#, c-format
msgid "Can't parse wire_types: %1$s"
msgstr ""
#. TODO:generic error reporting function or component.
-#: src/webex/pages/confirm-create-reserve.tsx:663
+#: src/webex/pages/confirm-create-reserve.tsx:626
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -311,16 +316,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: src/webex/renderHtml.tsx:51
-#, c-format
-msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
-msgstr ""
-
-#: src/webex/renderHtml.tsx:56
-#, c-format
-msgid "You are about to purchase:"
-msgstr ""
-
#: src/wire.ts:38
#, c-format
msgid "Invalid Wire"
diff --git a/src/i18n/it.po b/src/i18n/it.po
index dc271a749..d804bd204 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -27,28 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/webex/pages/confirm-contract.tsx:69
+#: src/webex/pages/confirm-contract.tsx:70
#, c-format
msgid "show more details\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:83
+#: src/webex/pages/confirm-contract.tsx:84
#, c-format
msgid "Accepted exchanges:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:88
+#: src/webex/pages/confirm-contract.tsx:89
#, c-format
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:154
+#: src/webex/pages/confirm-contract.tsx:156
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:156
+#: src/webex/pages/confirm-contract.tsx:158
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,67 +56,77 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:213
+#: src/webex/pages/confirm-contract.tsx:214
+#, c-format
+msgid "The merchant%1$s offers you to purchase:\n"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:232
+#, c-format
+msgid "Confirm payment"
+msgstr ""
+
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:214
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:215
+#: src/webex/pages/confirm-create-reserve.tsx:181
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:220
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:221
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:222
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:223
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:224
+#: src/webex/pages/confirm-create-reserve.tsx:190
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:278
+#: src/webex/pages/confirm-create-reserve.tsx:244
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:294
+#: src/webex/pages/confirm-create-reserve.tsx:260
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:362
+#: src/webex/pages/confirm-create-reserve.tsx:328
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:368
+#: src/webex/pages/confirm-create-reserve.tsx:334
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:374
+#: src/webex/pages/confirm-create-reserve.tsx:340
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -124,7 +134,7 @@ msgid ""
"If you withdraw from this exchange, it will be trusted in the future.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:383
+#: src/webex/pages/confirm-create-reserve.tsx:349
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -132,63 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:397
+#: src/webex/pages/confirm-create-reserve.tsx:363
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:408
-#, c-format
-msgid "A problem occured, see below. %1$s"
-msgstr ""
-
-#: src/webex/pages/confirm-create-reserve.tsx:414
+#: src/webex/pages/confirm-create-reserve.tsx:380
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:457
+#: src/webex/pages/confirm-create-reserve.tsx:423
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:462
+#: src/webex/pages/confirm-create-reserve.tsx:428
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:519
+#: src/webex/pages/confirm-create-reserve.tsx:485
#, c-format
msgid "You are about to withdraw %1$s from your bank account into your wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:607
+#: src/webex/pages/confirm-create-reserve.tsx:570
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:616
+#: src/webex/pages/confirm-create-reserve.tsx:579
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:630
+#: src/webex/pages/confirm-create-reserve.tsx:593
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:637
+#: src/webex/pages/confirm-create-reserve.tsx:600
#, c-format
msgid "Can't parse wire_types: %1$s"
msgstr ""
#. TODO:generic error reporting function or component.
-#: src/webex/pages/confirm-create-reserve.tsx:663
+#: src/webex/pages/confirm-create-reserve.tsx:626
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -311,16 +316,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: src/webex/renderHtml.tsx:51
-#, c-format
-msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
-msgstr ""
-
-#: src/webex/renderHtml.tsx:56
-#, c-format
-msgid "You are about to purchase:"
-msgstr ""
-
#: src/wire.ts:38
#, c-format
msgid "Invalid Wire"
diff --git a/src/i18n/strings.ts b/src/i18n/strings.ts
index 75672cbd3..41c8d72a2 100644
--- a/src/i18n/strings.ts
+++ b/src/i18n/strings.ts
@@ -39,6 +39,12 @@ strings['de'] = {
"You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.": [
""
],
+ "The merchant%1$s offers you to purchase:\n": [
+ ""
+ ],
+ "Confirm payment": [
+ "Bezahlung bestätigen"
+ ],
"Withdrawal fees:": [
"Abheben bei %1$s"
],
@@ -84,9 +90,6 @@ strings['de'] = {
"Waiting for a response from\n %1$s": [
""
],
- "A problem occured, see below. %1$s": [
- ""
- ],
"Information about fees will be available when an exchange provider is selected.": [
""
],
@@ -180,12 +183,6 @@ strings['de'] = {
"Cancel": [
"Saldo"
],
- "The merchant%1$swants to enter a contract over%2$s with you.\n": [
- "%1$s\n möchte einen Vertrag über %2$s\n mit Ihnen abschließen."
- ],
- "You are about to purchase:": [
- "Sie sind dabei, Folgendes zu kaufen:"
- ],
"Invalid Wire": [
""
],
@@ -225,6 +222,12 @@ strings['en-US'] = {
"You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.": [
""
],
+ "The merchant%1$s offers you to purchase:\n": [
+ ""
+ ],
+ "Confirm payment": [
+ ""
+ ],
"Withdrawal fees:": [
""
],
@@ -270,9 +273,6 @@ strings['en-US'] = {
"Waiting for a response from\n %1$s": [
""
],
- "A problem occured, see below. %1$s": [
- ""
- ],
"Information about fees will be available when an exchange provider is selected.": [
""
],
@@ -366,12 +366,6 @@ strings['en-US'] = {
"Cancel": [
""
],
- "The merchant%1$swants to enter a contract over%2$s with you.\n": [
- ""
- ],
- "You are about to purchase:": [
- ""
- ],
"Invalid Wire": [
""
],
@@ -411,6 +405,12 @@ strings['fr'] = {
"You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.": [
""
],
+ "The merchant%1$s offers you to purchase:\n": [
+ ""
+ ],
+ "Confirm payment": [
+ ""
+ ],
"Withdrawal fees:": [
""
],
@@ -456,9 +456,6 @@ strings['fr'] = {
"Waiting for a response from\n %1$s": [
""
],
- "A problem occured, see below. %1$s": [
- ""
- ],
"Information about fees will be available when an exchange provider is selected.": [
""
],
@@ -552,12 +549,6 @@ strings['fr'] = {
"Cancel": [
""
],
- "The merchant%1$swants to enter a contract over%2$s with you.\n": [
- ""
- ],
- "You are about to purchase:": [
- ""
- ],
"Invalid Wire": [
""
],
@@ -597,6 +588,12 @@ strings['it'] = {
"You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.": [
""
],
+ "The merchant%1$s offers you to purchase:\n": [
+ ""
+ ],
+ "Confirm payment": [
+ ""
+ ],
"Withdrawal fees:": [
""
],
@@ -642,9 +639,6 @@ strings['it'] = {
"Waiting for a response from\n %1$s": [
""
],
- "A problem occured, see below. %1$s": [
- ""
- ],
"Information about fees will be available when an exchange provider is selected.": [
""
],
@@ -738,12 +732,6 @@ strings['it'] = {
"Cancel": [
""
],
- "The merchant%1$swants to enter a contract over%2$s with you.\n": [
- ""
- ],
- "You are about to purchase:": [
- ""
- ],
"Invalid Wire": [
""
],
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index dc271a749..d804bd204 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -27,28 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/webex/pages/confirm-contract.tsx:69
+#: src/webex/pages/confirm-contract.tsx:70
#, c-format
msgid "show more details\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:83
+#: src/webex/pages/confirm-contract.tsx:84
#, c-format
msgid "Accepted exchanges:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:88
+#: src/webex/pages/confirm-contract.tsx:89
#, c-format
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:154
+#: src/webex/pages/confirm-contract.tsx:156
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:156
+#: src/webex/pages/confirm-contract.tsx:158
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,67 +56,77 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:213
+#: src/webex/pages/confirm-contract.tsx:214
+#, c-format
+msgid "The merchant%1$s offers you to purchase:\n"
+msgstr ""
+
+#: src/webex/pages/confirm-contract.tsx:232
+#, c-format
+msgid "Confirm payment"
+msgstr ""
+
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:214
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:215
+#: src/webex/pages/confirm-create-reserve.tsx:181
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:220
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:221
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:222
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:223
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:224
+#: src/webex/pages/confirm-create-reserve.tsx:190
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:278
+#: src/webex/pages/confirm-create-reserve.tsx:244
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:294
+#: src/webex/pages/confirm-create-reserve.tsx:260
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:362
+#: src/webex/pages/confirm-create-reserve.tsx:328
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:368
+#: src/webex/pages/confirm-create-reserve.tsx:334
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:374
+#: src/webex/pages/confirm-create-reserve.tsx:340
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -124,7 +134,7 @@ msgid ""
"If you withdraw from this exchange, it will be trusted in the future.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:383
+#: src/webex/pages/confirm-create-reserve.tsx:349
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -132,63 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:397
+#: src/webex/pages/confirm-create-reserve.tsx:363
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:408
-#, c-format
-msgid "A problem occured, see below. %1$s"
-msgstr ""
-
-#: src/webex/pages/confirm-create-reserve.tsx:414
+#: src/webex/pages/confirm-create-reserve.tsx:380
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:457
+#: src/webex/pages/confirm-create-reserve.tsx:423
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:462
+#: src/webex/pages/confirm-create-reserve.tsx:428
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:519
+#: src/webex/pages/confirm-create-reserve.tsx:485
#, c-format
msgid "You are about to withdraw %1$s from your bank account into your wallet."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:607
+#: src/webex/pages/confirm-create-reserve.tsx:570
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:616
+#: src/webex/pages/confirm-create-reserve.tsx:579
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:630
+#: src/webex/pages/confirm-create-reserve.tsx:593
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:637
+#: src/webex/pages/confirm-create-reserve.tsx:600
#, c-format
msgid "Can't parse wire_types: %1$s"
msgstr ""
#. TODO:generic error reporting function or component.
-#: src/webex/pages/confirm-create-reserve.tsx:663
+#: src/webex/pages/confirm-create-reserve.tsx:626
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -311,16 +316,6 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: src/webex/renderHtml.tsx:51
-#, c-format
-msgid "The merchant%1$swants to enter a contract over%2$s with you.\n"
-msgstr ""
-
-#: src/webex/renderHtml.tsx:56
-#, c-format
-msgid "You are about to purchase:"
-msgstr ""
-
#: src/wire.ts:38
#, c-format
msgid "Invalid Wire"
diff --git a/src/types.ts b/src/types.ts
index d016b7fea..90fe7cf9c 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -822,6 +822,10 @@ export enum CoinStatus {
* Coin fully paid back.
*/
PaybackDone,
+ /**
+ * Coin was dirty but can't be refreshed.
+ */
+ Useless,
}
@@ -1467,7 +1471,10 @@ export function mkAmount(value: number, fraction: number, currency: string): Amo
/**
* Possible results for checkPay.
*/
-export type CheckPayResult = "paid" | "payment-possible" | "insufficient-balance";
+export interface CheckPayResult {
+ status: "paid" | "payment-possible" | "insufficient-balance";
+ coinSelection?: CoinSelectionResult;
+}
/**
* Possible results for confirmPay.
@@ -1695,3 +1702,30 @@ export interface PurchaseRecord {
refundsPending: { [refundSig: string]: RefundPermission };
refundsDone: { [refundSig: string]: RefundPermission };
}
+
+
+/**
+ * Result of selecting coins, contains the exchange, and selected
+ * coins with their denomination.
+ */
+export interface CoinSelectionResult {
+ exchangeUrl: string;
+ cds: CoinWithDenom[];
+ totalFees: AmountJson;
+}
+
+
+/**
+ * Named tuple of coin and denomination.
+ */
+export interface CoinWithDenom {
+ /**
+ * A coin. Must have the same denomination public key as the associated
+ * denomination.
+ */
+ coin: CoinRecord;
+ /**
+ * An associated denomination.
+ */
+ denom: DenominationRecord;
+}
diff --git a/src/wallet-test.ts b/src/wallet-test.ts
index acd776d67..037cc7592 100644
--- a/src/wallet-test.ts
+++ b/src/wallet-test.ts
@@ -29,7 +29,7 @@ function a(x: string): types.AmountJson {
}
-function fakeCwd(current: string, value: string, feeDeposit: string): wallet.CoinWithDenom {
+function fakeCwd(current: string, value: string, feeDeposit: string): types.CoinWithDenom {
return {
coin: {
blindingKey: "(mock)",
@@ -64,89 +64,89 @@ function fakeCwd(current: string, value: string, feeDeposit: string): wallet.Coi
test("coin selection 1", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.1"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:2.0"), a("EUR:0.1"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:2.0"), a("EUR:0.1"));
if (!res) {
t.fail();
return;
}
- t.true(res.length === 2);
+ t.true(res.cds.length === 2);
t.pass();
});
test("coin selection 2", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
// Merchant covers the fee, this one shouldn't be used
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:2.0"), a("EUR:0.5"));
if (!res) {
t.fail();
return;
}
- t.true(res.length === 2);
+ t.true(res.cds.length === 2);
t.pass();
});
test("coin selection 3", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
// this coin should be selected instead of previous one with fee
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.0"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:2.0"), a("EUR:0.5"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:2.0"), a("EUR:0.5"));
if (!res) {
t.fail();
return;
}
- t.true(res.length === 2);
+ t.true(res.cds.length === 2);
t.pass();
});
test("coin selection 4", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:2.0"), a("EUR:0.2"));
if (!res) {
t.fail();
return;
}
- t.true(res.length === 3);
+ t.true(res.cds.length === 3);
t.pass();
});
test("coin selection 5", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:4.0"), a("EUR:0.2"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:4.0"), a("EUR:0.2"));
t.true(!res);
t.pass();
});
test("coin selection 6", (t) => {
- const cds: wallet.CoinWithDenom[] = [
+ const cds: types.CoinWithDenom[] = [
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
fakeCwd("EUR:1.0", "EUR:1.0", "EUR:0.5"),
];
- const res = wallet.selectPayCoins(cds, a("EUR:2.0"), a("EUR:0.2"));
+ const res = wallet.selectPayCoins([], cds, a("EUR:2.0"), a("EUR:0.2"));
t.true(!res);
t.pass();
});
diff --git a/src/wallet.ts b/src/wallet.ts
index 3d095fc06..f194755e8 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -51,7 +51,9 @@ import {
CheckPayResult,
CoinPaySig,
CoinRecord,
+ CoinSelectionResult,
CoinStatus,
+ CoinWithDenom,
ConfirmPayResult,
ConfirmReserveRequest,
ContractTerms,
@@ -72,8 +74,10 @@ import {
PaybackConfirmation,
PreCoinRecord,
ProposalRecord,
+ PurchaseRecord,
QueryPaymentResult,
RefreshSessionRecord,
+ RefundPermission,
ReserveCreationInfo,
ReserveRecord,
ReturnCoinsRequest,
@@ -82,27 +86,10 @@ import {
WalletBalanceEntry,
WireFee,
WireInfo,
- RefundPermission,
- PurchaseRecord,
} from "./types";
import URI = require("urijs");
-/**
- * Named tuple of coin and denomination.
- */
-export interface CoinWithDenom {
- /**
- * A coin. Must have the same denomination public key as the associated
- * denomination.
- */
- coin: CoinRecord;
- /**
- * An associated denomination.
- */
- denom: DenominationRecord;
-}
-
/**
* Element of the payback list that the
@@ -370,30 +357,62 @@ function isWithdrawableDenom(d: DenominationRecord) {
}
+
+function strcmp(s1: string, s2: string): number {
+ if (s1 < s2) {
+ return -1;
+ }
+ if (s1 > s2) {
+ return 1;
+ }
+ return 0;
+}
+
+
+interface SelectPayCoinsResult {
+ cds: CoinWithDenom[];
+ totalFees: AmountJson;
+}
+
+
/**
- * Result of selecting coins, contains the exchange, and selected
- * coins with their denomination.
+ * Get the amount that we lose when refreshing a coin of the given denomination
+ * with a certain amount left.
+ *
+ * If the amount left is zero, then the refresh cost
+ * is also considered to be zero. If a refresh isn't possible (e.g. due to lack of
+ * the right denominations), then the cost is the full amount left.
+ *
+ * Considers refresh fees, withdrawal fees after refresh and amounts too small
+ * to refresh.
*/
-export type CoinSelectionResult = {exchangeUrl: string, cds: CoinWithDenom[]}|undefined;
+export function getTotalRefreshCost(denoms: DenominationRecord[], refreshedDenom: DenominationRecord, amountLeft: AmountJson): AmountJson {
+ const withdrawAmount = Amounts.sub(amountLeft, refreshedDenom.feeRefresh).amount;
+ const withdrawDenoms = getWithdrawDenomList(withdrawAmount, denoms);
+ const resultingAmount = Amounts.add(Amounts.getZero(withdrawAmount.currency), ...withdrawDenoms.map((d) => d.value)).amount;
+ const totalCost = Amounts.sub(amountLeft, resultingAmount).amount;
+ console.log("total refresh cost for", amountToPretty(amountLeft), "is", amountToPretty(totalCost));
+ return totalCost;
+}
+
/**
* Select coins for a payment under the merchant's constraints.
+ *
+ * @param denoms all available denoms, used to compute refresh fees
*/
-export function selectPayCoins(cds: CoinWithDenom[], paymentAmount: AmountJson,
- depositFeeLimit: AmountJson): CoinWithDenom[]|undefined {
+export function selectPayCoins(denoms: DenominationRecord[], cds: CoinWithDenom[], paymentAmount: AmountJson,
+ depositFeeLimit: AmountJson): SelectPayCoinsResult|undefined {
if (cds.length === 0) {
return undefined;
}
- // Sort by ascending deposit fee
- cds.sort((o1, o2) => Amounts.cmp(o1.denom.feeDeposit,
- o2.denom.feeDeposit));
+ // Sort by ascending deposit fee and denomPub if deposit fee is the same
+ // (to guarantee deterministic results)
+ cds.sort((o1, o2) => Amounts.cmp(o1.denom.feeDeposit, o2.denom.feeDeposit) || strcmp(o1.denom.denomPub, o2.denom.denomPub));
const currency = cds[0].denom.value.currency;
const cdsResult: CoinWithDenom[] = [];
- let accFee: AmountJson = Amounts.getZero(currency);
+ let accDepositFee: AmountJson = Amounts.getZero(currency);
let accAmount: AmountJson = Amounts.getZero(currency);
- let isBelowFee = false;
- let coversAmount = false;
- let coversAmountWithFee = false;
for (const {coin, denom} of cds) {
if (coin.suspended) {
continue;
@@ -405,18 +424,30 @@ export function selectPayCoins(cds: CoinWithDenom[], paymentAmount: AmountJson,
continue;
}
cdsResult.push({coin, denom});
- accFee = Amounts.add(denom.feeDeposit, accFee).amount;
+ accDepositFee = Amounts.add(denom.feeDeposit, accDepositFee).amount;
+ let leftAmount = Amounts.sub(coin.currentAmount, Amounts.sub(paymentAmount, accAmount).amount).amount;
accAmount = Amounts.add(coin.currentAmount, accAmount).amount;
- coversAmount = Amounts.cmp(accAmount, paymentAmount) >= 0;
- coversAmountWithFee = Amounts.cmp(accAmount,
+ const coversAmount = Amounts.cmp(accAmount, paymentAmount) >= 0;
+ const coversAmountWithFee = Amounts.cmp(accAmount,
Amounts.add(paymentAmount,
denom.feeDeposit).amount) >= 0;
- isBelowFee = Amounts.cmp(accFee, depositFeeLimit) <= 0;
+ const isBelowFee = Amounts.cmp(accDepositFee, depositFeeLimit) <= 0;
- console.log("coin selection", { coversAmount, isBelowFee, accFee, accAmount, paymentAmount });
+ console.log("coin selection", { coversAmount, isBelowFee, accDepositFee, accAmount, paymentAmount });
if ((coversAmount && isBelowFee) || coversAmountWithFee) {
- return cdsResult;
+ let depositFeeToCover = Amounts.sub(accDepositFee, depositFeeLimit).amount;
+ leftAmount = Amounts.sub(leftAmount, depositFeeToCover).amount;
+ console.log("deposit fee to cover", amountToPretty(depositFeeToCover));
+
+ let totalFees: AmountJson = Amounts.getZero(currency);
+ if (coversAmountWithFee && !isBelowFee) {
+ // these are the fees the customer has to pay
+ // because the merchant doesn't cover them
+ totalFees = Amounts.sub(depositFeeLimit, accDepositFee).amount;
+ }
+ totalFees = Amounts.add(totalFees, getTotalRefreshCost(denoms, denom, leftAmount)).amount;
+ return { cds: cdsResult, totalFees };
}
}
return undefined;
@@ -729,6 +760,8 @@ export class Wallet {
return [];
}
+ const denoms = await this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl).toArray();
+
// Denomination of the first coin, we assume that all other
// coins have the same currency
const firstDenom = await this.q().get(Stores.denominations,
@@ -763,7 +796,11 @@ export class Wallet {
console.log("coin return: selecting from possible coins", { cds, amount } );
- return selectPayCoins(cds, amount, amount);
+ const res = selectPayCoins(denoms, cds, amount, amount);
+ if (res) {
+ return res.cds;
+ }
+ return undefined
}
@@ -771,7 +808,7 @@ export class Wallet {
* Get exchanges and associated coins that are still spendable,
* but only if the sum the coins' remaining value exceeds the payment amount.
*/
- private async getCoinsForPayment(args: CoinsForPaymentArgs): Promise<CoinSelectionResult> {
+ private async getCoinsForPayment(args: CoinsForPaymentArgs): Promise<CoinSelectionResult|undefined> {
const {
allowedAuditors,
allowedExchanges,
@@ -821,6 +858,7 @@ export class Wallet {
.iterIndex(Stores.coins.exchangeBaseUrlIndex,
exchange.baseUrl)
.toArray();
+ const denoms = await this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl).toArray();
if (!coins || coins.length === 0) {
continue;
}
@@ -862,6 +900,7 @@ export class Wallet {
continue;
}
+ let totalFees = Amounts.getZero(currency);
let wireFee: AmountJson|undefined;
for (const fee of (fees.feesForType[wireMethod] || [])) {
if (fee.startStamp >= wireFeeTime && fee.endStamp <= wireFeeTime) {
@@ -873,15 +912,18 @@ export class Wallet {
if (wireFee) {
const amortizedWireFee = Amounts.divide(wireFee, wireFeeAmortization);
if (Amounts.cmp(wireFeeLimit, amortizedWireFee) < 0) {
+ totalFees = Amounts.add(amortizedWireFee, totalFees).amount;
remainingAmount = Amounts.add(amortizedWireFee, remainingAmount).amount;
}
}
- const res = selectPayCoins(cds, remainingAmount, depositFeeLimit);
+ const res = selectPayCoins(denoms, cds, remainingAmount, depositFeeLimit);
if (res) {
+ totalFees = Amounts.add(totalFees, res.totalFees).amount;
return {
- cds: res,
+ cds: res.cds,
exchangeUrl: exchange.baseUrl,
+ totalFees,
};
}
}
@@ -1014,7 +1056,7 @@ export class Wallet {
// First check if we already payed for it.
const purchase = await this.q().get(Stores.purchases, proposal.contractTermsHash);
if (purchase) {
- return "paid";
+ return { status: "paid" };
}
// If not already payed, check if we could pay for it.
@@ -1031,9 +1073,9 @@ export class Wallet {
if (!res) {
console.log("not confirming payment, insufficient coins");
- return "insufficient-balance";
+ return { status: "insufficient-balance" };
}
- return "payment-possible";
+ return { status: "payment-possible", coinSelection: res };
}
@@ -1653,6 +1695,7 @@ export class Wallet {
console.log("suspending coin", c);
c.suspended = true;
q.put(Stores.coins, c);
+ this.notifier.notify();
});
await q.finish();
}
@@ -1840,11 +1883,14 @@ export class Wallet {
if (c.suspended) {
return balance;
}
- if (!(c.status === CoinStatus.Fresh)) {
+ if (c.status === CoinStatus.Fresh) {
+ addTo(balance, "available", c.currentAmount, c.exchangeBaseUrl);
+ return balance;
+ }
+ if (c.status === CoinStatus.Dirty) {
+ addTo(balance, "pendingIncoming", c.currentAmount, c.exchangeBaseUrl);
return balance;
}
- console.log("collecting balance");
- addTo(balance, "available", c.currentAmount, c.exchangeBaseUrl);
return balance;
}
@@ -1978,6 +2024,9 @@ export class Wallet {
if (newCoinDenoms.length === 0) {
console.log(`not refreshing, available amount ${amountToPretty(availableAmount)} too small`);
+ coin.status = CoinStatus.Useless;
+ await this.q().put(Stores.coins, coin);
+ this.notifier.notify();
return undefined;
}
@@ -2007,6 +2056,7 @@ export class Wallet {
query.put(Stores.refresh, refreshSession, "refreshKey")
.mutate(Stores.coins, coin.coinPub, mutateCoin);
await query.finish();
+ this.notifier.notify();
const key = query.key("refreshKey");
if (!key || typeof key !== "number") {
@@ -2026,7 +2076,15 @@ export class Wallet {
console.log("got old session for", oldCoinPub, session);
this.continueRefreshSession(session);
}
- let refreshSession = await this.createRefreshSession(oldCoinPub);
+ const coin = await this.q().get(Stores.coins, oldCoinPub);
+ if (!coin) {
+ console.warn("can't refresh, coin not in database");
+ return;
+ }
+ if (coin.status === CoinStatus.Useless || coin.status === CoinStatus.Fresh) {
+ return;
+ }
+ const refreshSession = await this.createRefreshSession(oldCoinPub);
if (!refreshSession) {
// refreshing not necessary
console.log("not refreshing", oldCoinPub);
@@ -2106,6 +2164,7 @@ export class Wallet {
refreshSession.norevealIndex = norevealIndex;
await this.q().put(Stores.refresh, refreshSession).finish();
+ this.notifier.notify();
}
@@ -2186,6 +2245,7 @@ export class Wallet {
.putAll(Stores.coins, coins)
.put(Stores.refresh, refreshSession)
.finish();
+ this.notifier.notify();
}
@@ -2344,6 +2404,7 @@ export class Wallet {
// from the reserve for the payback request.
reserve.hasPayback = true;
await this.q().put(Stores.coins, coin).put(Stores.reserves, reserve);
+ this.notifier.notify();
const paybackRequest = await this.cryptoApi.createPaybackRequest(coin);
const reqUrl = new URI("payback").absoluteTo(coin.exchangeBaseUrl);
@@ -2361,6 +2422,7 @@ export class Wallet {
}
coin.status = CoinStatus.PaybackDone;
await this.q().put(Stores.coins, coin);
+ this.notifier.notify();
await this.updateReserve(reservePub!);
}
@@ -2502,6 +2564,7 @@ export class Wallet {
.put(Stores.coinsReturns, coinsReturnRecord)
.putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
.finish();
+ this.notifier.notify();
this.depositReturnedCoins(coinsReturnRecord);
}
@@ -2558,6 +2621,7 @@ export class Wallet {
}
}
await this.q().put(Stores.coinsReturns, currentCrr);
+ this.notifier.notify();
}
}
@@ -2666,4 +2730,34 @@ export class Wallet {
async getPurchase(contractTermsHash: string): Promise<PurchaseRecord|undefined> {
return this.q().get(Stores.purchases, contractTermsHash);
}
+
+ async getFullRefundFees(refundPermissions: RefundPermission[]): Promise<AmountJson> {
+ if (refundPermissions.length === 0) {
+ throw Error("no refunds given");
+ }
+ const coin0 = await this.q().get(Stores.coins, refundPermissions[0].coin_pub)
+ if (!coin0) {
+ throw Error("coin not found");
+ }
+ let feeAcc = Amounts.getZero(refundPermissions[0].refund_amount.currency);
+
+ const denoms = await this.q().iterIndex(Stores.denominations.exchangeBaseUrlIndex, coin0.exchangeBaseUrl).toArray();
+ for (const rp of refundPermissions) {
+ const coin = await this.q().get(Stores.coins, rp.coin_pub);
+ if (!coin) {
+ throw Error("coin not found");
+ }
+ const denom = await this.q().get(Stores.denominations, [coin0.exchangeBaseUrl, coin.denomPub]);
+ if (!denom) {
+ throw Error(`denom not found (${coin.denomPub})`);
+ }
+ // FIXME: this assumes that the refund already happened.
+ // When it hasn't, the refresh cost is inaccurate. To fix this,
+ // we need introduce a flag to tell if a coin was refunded or
+ // refreshed normally (and what about incremental refunds?)
+ const refreshCost = getTotalRefreshCost(denoms, denom, Amounts.sub(rp.refund_amount, rp.refund_fee).amount);
+ feeAcc = Amounts.add(feeAcc, refreshCost, rp.refund_fee).amount;
+ }
+ return feeAcc;
+ }
}
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index 7de28b9e9..122bd8fe2 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -191,7 +191,11 @@ export interface MessageMap {
"get-purchase": {
request: any;
response: void;
- }
+ };
+ "get-full-refund-fees": {
+ request: { refundPermissions: types.RefundPermission[] };
+ response: void;
+ };
}
/**
diff --git a/src/webex/pages/confirm-contract.html b/src/webex/pages/confirm-contract.html
index 394de582a..223d413d8 100644
--- a/src/webex/pages/confirm-contract.html
+++ b/src/webex/pages/confirm-contract.html
@@ -5,6 +5,7 @@
<meta charset="UTF-8">
<title>Taler Wallet: Confirm Reserve Creation</title>
+ <link rel="stylesheet" type="text/css" href="../style/pure.css">
<link rel="stylesheet" type="text/css" href="../style/wallet.css">
<link rel="icon" href="/img/icon.png">
diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx
index fa71b1028..5436cb5a6 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -25,12 +25,13 @@
*/
import * as i18n from "../../i18n";
import {
+ CheckPayResult,
ContractTerms,
ExchangeRecord,
ProposalRecord,
} from "../../types";
-import { renderContractTerms } from "../renderHtml";
+import { renderAmount } from "../renderHtml";
import * as wxApi from "../wxApi";
import * as React from "react";
@@ -113,6 +114,7 @@ interface ContractPromptState {
* when pressing pay.
*/
holdCheck: boolean;
+ payStatus?: CheckPayResult;
}
class ContractPrompt extends React.Component<ContractPromptProps, ContractPromptState> {
@@ -150,7 +152,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
return;
}
const payStatus = await wxApi.checkPay(this.props.proposalId);
- if (payStatus === "insufficient-balance") {
+ if (payStatus.status === "insufficient-balance") {
const msgInsufficient = i18n.str`You have insufficient funds of the requested currency in your wallet.`;
// tslint:disable-next-line:max-line-length
const msgNoMatch = i18n.str`You do not have any funds from an exchange that is accepted by this merchant. None of the exchanges accepted by the merchant is known to your wallet.`;
@@ -166,10 +168,10 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
this.setState({error: msgInsufficient});
}
this.setState({payDisabled: true});
- } else if (payStatus === "paid") {
- this.setState({alreadyPaid: true, payDisabled: false, error: null});
+ } else if (payStatus.status === "paid") {
+ this.setState({alreadyPaid: true, payDisabled: false, error: null, payStatus});
} else {
- this.setState({payDisabled: false, error: null});
+ this.setState({payDisabled: false, error: null, payStatus});
}
}
@@ -189,7 +191,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
document.location.href = proposal.contractTerms.fulfillment_url;
break;
}
- this.setState({holdCheck: false});
+ this.setState({holdCheck: true});
}
@@ -198,15 +200,36 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
return <span>...</span>;
}
const c = this.state.proposal.contractTerms;
+ let merchantName;
+ if (c.merchant && c.merchant.name) {
+ merchantName = <strong>{c.merchant.name}</strong>;
+ } else {
+ merchantName = <strong>(pub: {c.merchant_pub})</strong>;
+ }
+ const amount = <strong>{renderAmount(c.amount)}</strong>;
+ console.log("payStatus", this.state.payStatus);
return (
<div>
<div>
- {renderContractTerms(c)}
+ <i18n.Translate wrap="p">
+ The merchant <span>{merchantName}</span> {" "}
+ offers you to purchase:
+ </i18n.Translate>
+ <ul>
+ {c.products.map(
+ (p: any, i: number) => (<li key={i}>{p.description}: {renderAmount(p.price)}</li>))
+ }
+ </ul>
+ {(this.state.payStatus && this.state.payStatus.coinSelection) ?
+ <p>The total price is <span>{amount}</span> (plus <span>{renderAmount(this.state.payStatus.coinSelection.totalFees)}</span> fees).</p>
+ :
+ <p>The total price is <span>{amount}</span>.</p>
+ }
</div>
- <button onClick={() => this.doPayment()}
+ <button className="pure-button button-success"
disabled={this.state.payDisabled}
- className="accept">
- Confirm payment
+ onClick={() => this.doPayment()}>
+ {i18n.str`Confirm payment`}
</button>
<div>
{(this.state.alreadyPaid ? <p className="okaybox">You already paid for this, clicking "Confirm payment" will not cost money again.</p> : <p />)}
diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx
index b9506bf29..d2c21c2f4 100644
--- a/src/webex/pages/refund.tsx
+++ b/src/webex/pages/refund.tsx
@@ -37,11 +37,12 @@ interface RefundStatusViewProps {
interface RefundStatusViewState {
purchase?: types.PurchaseRecord;
+ refundFees?: types.AmountJson;
gotResult: boolean;
}
-const RefundDetail = ({purchase}: {purchase: types.PurchaseRecord}) => {
+const RefundDetail = ({purchase, fullRefundFees}: {purchase: types.PurchaseRecord, fullRefundFees: types.AmountJson}) => {
const pendingKeys = Object.keys(purchase.refundsPending);
const doneKeys = Object.keys(purchase.refundsDone);
if (pendingKeys.length == 0 && doneKeys.length == 0) {
@@ -54,22 +55,18 @@ const RefundDetail = ({purchase}: {purchase: types.PurchaseRecord}) => {
}
let amountPending = types.Amounts.getZero(currency);
- let feesPending = types.Amounts.getZero(currency)
for (let k of pendingKeys) {
amountPending = types.Amounts.add(amountPending, purchase.refundsPending[k].refund_amount).amount;
- feesPending = types.Amounts.add(feesPending, purchase.refundsPending[k].refund_fee).amount;
}
let amountDone = types.Amounts.getZero(currency);
- let feesDone = types.Amounts.getZero(currency);
for (let k of doneKeys) {
amountDone = types.Amounts.add(amountDone, purchase.refundsDone[k].refund_amount).amount;
- feesDone = types.Amounts.add(feesDone, purchase.refundsDone[k].refund_fee).amount;
}
return (
<div>
- <p>Refund fully received: <AmountDisplay amount={amountDone} /> (refund fees: <AmountDisplay amount={feesDone} />)</p>
- <p>Refund incoming: <AmountDisplay amount={amountPending} /> (refund fees: <AmountDisplay amount={feesPending} />)</p>
+ <p>Refund fully received: <AmountDisplay amount={amountDone} /> (refund fees: <AmountDisplay amount={fullRefundFees} />)</p>
+ <p>Refund incoming: <AmountDisplay amount={amountPending} /></p>
</div>
);
};
@@ -108,7 +105,7 @@ class RefundStatusView extends React.Component<RefundStatusViewProps, RefundStat
<h1>Refund Status</h1>
<p>Status of purchase <strong>{summary}</strong> from merchant <strong>{merchantName}</strong> (order id {purchase.contractTerms.order_id}).</p>
<p>Total amount: <AmountDisplay amount={purchase.contractTerms.amount} /></p>
- {purchase.finished ? <RefundDetail purchase={purchase} /> : <p>Purchase not completed.</p>}
+ {purchase.finished ? <RefundDetail purchase={purchase} fullRefundFees={this.state.refundFees!} /> : <p>Purchase not completed.</p>}
</div>
);
}
@@ -116,7 +113,9 @@ class RefundStatusView extends React.Component<RefundStatusViewProps, RefundStat
async update() {
const purchase = await wxApi.getPurchase(this.props.contractTermsHash);
console.log("got purchase", purchase);
- this.setState({ purchase, gotResult: true });
+ const refundsDone = Object.keys(purchase.refundsDone).map((x) => purchase.refundsDone[x]);
+ const refundFees = await wxApi.getFullRefundFees( {refundPermissions: refundsDone });
+ this.setState({ purchase, gotResult: true, refundFees });
}
}
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index 2a5b50533..d26f726af 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -24,45 +24,13 @@
/**
* Imports.
*/
-import { amountToPretty } from "../helpers";
-import * as i18n from "../i18n";
import {
AmountJson,
Amounts,
- ContractTerms,
} from "../types";
import * as React from "react";
-/**
- * Render contract terms for the end user to view.
- */
-export function renderContractTerms(contractTerms: ContractTerms): JSX.Element {
- let merchantName;
- if (contractTerms.merchant && contractTerms.merchant.name) {
- merchantName = <strong>{contractTerms.merchant.name}</strong>;
- } else {
- merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>;
- }
- const amount = <strong>{amountToPretty(contractTerms.amount)}</strong>;
-
- return (
- <div>
- <i18n.Translate wrap="p">
- The merchant <span>{merchantName}</span>
- wants to enter a contract over <span>{amount}</span>{" "}
- with you.
- </i18n.Translate>
- <p>{i18n.str`You are about to purchase:`}</p>
- <ul>
- {contractTerms.products.map(
- (p: any, i: number) => (<li key={i}>{`${p.description}: ${amountToPretty(p.price)}`}</li>))
- }
- </ul>
- </div>
- );
-}
-
/**
* Render amount as HTML, which non-breaking space between
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index 1423da53b..096d855e0 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -33,6 +33,7 @@ import {
PreCoinRecord,
PurchaseRecord,
QueryPaymentResult,
+ RefundPermission,
ReserveCreationInfo,
ReserveRecord,
SenderWireInfos,
@@ -345,3 +346,7 @@ export function acceptRefund(refundData: any): Promise<number> {
export function getPurchase(contractTermsHash: string): Promise<PurchaseRecord> {
return callBackend("get-purchase", { contractTermsHash });
}
+
+export function getFullRefundFees(args: { refundPermissions: RefundPermission[] }): Promise<AmountJson> {
+ return callBackend("get-full-refund-fees", { refundPermissions: args.refundPermissions });
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index db2ffbfbd..16da3d97d 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -323,6 +323,8 @@ function handleMessage(sender: MessageSender,
throw Error("contractTermsHash missing");
}
return needsWallet().getPurchase(contractTermsHash);
+ case "get-full-refund-fees":
+ return needsWallet().getFullRefundFees(detail.refundPermissions);
default:
// Exhaustiveness check.
// See https://www.typescriptlang.org/docs/handbook/advanced-types.html