summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/checkable.ts7
-rw-r--r--src/crypto/cryptoWorker.ts6
-rw-r--r--src/helpers.ts1
-rw-r--r--src/i18n.tsx20
-rw-r--r--src/i18n/de.po65
-rw-r--r--src/i18n/en-US.po65
-rw-r--r--src/i18n/fr.po65
-rw-r--r--src/i18n/it.po65
-rw-r--r--src/i18n/strings.ts12
-rw-r--r--src/i18n/taler-wallet-webex.pot65
-rw-r--r--src/libtoolVersion.ts9
-rw-r--r--src/logging.ts5
-rw-r--r--src/memidb-test.ts18
-rw-r--r--src/query.ts3
-rw-r--r--src/timer.ts8
-rw-r--r--src/types.ts49
-rw-r--r--src/wallet.ts131
-rw-r--r--src/webex/messages.ts10
-rw-r--r--src/webex/notify.ts24
-rw-r--r--src/webex/pages/confirm-contract.tsx17
-rw-r--r--src/webex/pages/confirm-create-reserve.tsx17
-rw-r--r--src/webex/pages/error.tsx11
-rw-r--r--src/webex/pages/payback.tsx2
-rw-r--r--src/webex/pages/popup.tsx11
-rw-r--r--src/webex/pages/refund.tsx30
-rw-r--r--src/webex/pages/reset-required.tsx17
-rw-r--r--src/webex/pages/return-coins.tsx6
-rw-r--r--src/webex/renderHtml.tsx7
-rw-r--r--src/webex/wxApi.ts19
-rw-r--r--src/webex/wxBackend.ts23
-rw-r--r--src/wire.ts2
31 files changed, 477 insertions, 313 deletions
diff --git a/src/checkable.ts b/src/checkable.ts
index 8e942d7cc..124eb6587 100644
--- a/src/checkable.ts
+++ b/src/checkable.ts
@@ -67,6 +67,7 @@ export namespace Checkable {
props: Prop[];
}
+ // tslint:disable-next-line:no-shadowed-variable
export const SchemaError = (function SchemaError(this: any, message: string) {
const that: any = this as any;
that.name = "SchemaError";
@@ -167,6 +168,7 @@ export namespace Checkable {
function checkValue(target: any, prop: Prop, path: Path): any {
const type = prop.type;
+ const typeName = type.name || "??";
if (!type) {
throw Error(`assertion failed (prop is ${JSON.stringify(prop)})`);
}
@@ -183,7 +185,7 @@ export namespace Checkable {
if (innerProp.optional) {
continue;
}
- throw new SchemaError(`Property ${innerProp.propertyKey} missing on ${path} of ${type.name||"??"}`);
+ throw new SchemaError(`Property ${innerProp.propertyKey} missing on ${path} of ${typeName}`);
}
if (!remainingPropNames.delete(innerProp.propertyKey)) {
throw new SchemaError("assertion failed");
@@ -195,7 +197,8 @@ export namespace Checkable {
}
if (!prop.extraAllowed && remainingPropNames.size !== 0) {
- throw new SchemaError(`superfluous properties ${JSON.stringify(Array.from(remainingPropNames.values()))} of ${type.name||"??"}`);
+ const err = `superfluous properties ${JSON.stringify(Array.from(remainingPropNames.values()))} of ${typeName}`;
+ throw new SchemaError(err);
}
return obj;
}
diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts
index 92b766e9c..0a93fcb07 100644
--- a/src/crypto/cryptoWorker.ts
+++ b/src/crypto/cryptoWorker.ts
@@ -23,6 +23,9 @@
* Imports.
*/
import {
+ canonicalJson,
+} from "../helpers";
+import {
AmountJson,
Amounts,
CoinPaySig,
@@ -39,9 +42,6 @@ import {
ReserveRecord,
WireFee,
} from "../types";
-import {
- canonicalJson,
-} from "../helpers";
import {
Amount,
diff --git a/src/helpers.ts b/src/helpers.ts
index eff5fa731..6dc080b2e 100644
--- a/src/helpers.ts
+++ b/src/helpers.ts
@@ -22,6 +22,7 @@
* Imports.
*/
import {AmountJson, Amounts} from "./types";
+
import URI = require("urijs");
/**
diff --git a/src/i18n.tsx b/src/i18n.tsx
index 437c4a6a0..cbc687090 100644
--- a/src/i18n.tsx
+++ b/src/i18n.tsx
@@ -47,24 +47,24 @@ const jed = new jedLib.Jed(strings[lang]);
/**
* Convert template strings to a msgid
*/
-function toI18nString(strings: ReadonlyArray<string>) {
- let str = "";
- for (let i = 0; i < strings.length; i++) {
- str += strings[i];
- if (i < strings.length - 1) {
- str += `%${i + 1}$s`;
+function toI18nString(stringSeq: ReadonlyArray<string>) {
+ let s = "";
+ for (let i = 0; i < stringSeq.length; i++) {
+ s += stringSeq[i];
+ if (i < stringSeq.length - 1) {
+ s += `%${i + 1}$s`;
}
}
- return str;
+ return s;
}
/**
* Internationalize a string template with arbitrary serialized values.
*/
-export function str(strings: TemplateStringsArray, ...values: any[]) {
- const str = toI18nString(strings);
- const tr = jed.translate(str).ifPlural(1, str).fetch(...values);
+export function str(stringSeq: TemplateStringsArray, ...values: any[]) {
+ const s = toI18nString(stringSeq);
+ const tr = jed.translate(s).ifPlural(1, s).fetch(...values);
return tr;
}
diff --git a/src/i18n/de.po b/src/i18n/de.po
index 1318654af..5cef25386 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -66,67 +66,67 @@ msgstr ""
msgid "Confirm payment"
msgstr "Bezahlung bestätigen"
-#: src/webex/pages/confirm-create-reserve.tsx:179
+#: src/webex/pages/confirm-create-reserve.tsx:178
#, fuzzy, c-format
msgid "Withdrawal fees:"
msgstr "Abheben bei %1$s"
-#: src/webex/pages/confirm-create-reserve.tsx:180
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:181
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:186
+#: src/webex/pages/confirm-create-reserve.tsx:185
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:187
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:188
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, fuzzy, c-format
msgid "Withdraw Fee"
msgstr "Abheben bei %1$s"
-#: src/webex/pages/confirm-create-reserve.tsx:189
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:190
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:244
+#: src/webex/pages/confirm-create-reserve.tsx:243
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:260
+#: src/webex/pages/confirm-create-reserve.tsx:259
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:328
+#: src/webex/pages/confirm-create-reserve.tsx:327
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:334
+#: src/webex/pages/confirm-create-reserve.tsx:333
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:340
+#: src/webex/pages/confirm-create-reserve.tsx:339
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -134,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:349
+#: src/webex/pages/confirm-create-reserve.tsx:348
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -142,58 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:363
+#: src/webex/pages/confirm-create-reserve.tsx:362
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:380
+#: src/webex/pages/confirm-create-reserve.tsx:379
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:423
+#: src/webex/pages/confirm-create-reserve.tsx:422
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:428
+#: src/webex/pages/confirm-create-reserve.tsx:427
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:485
+#: src/webex/pages/confirm-create-reserve.tsx:484
#, 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:570
+#: src/webex/pages/confirm-create-reserve.tsx:569
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:579
+#: src/webex/pages/confirm-create-reserve.tsx:578
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:593
+#: src/webex/pages/confirm-create-reserve.tsx:592
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:600
+#: src/webex/pages/confirm-create-reserve.tsx:599
#, 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:626
+#: src/webex/pages/confirm-create-reserve.tsx:625
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -262,24 +262,24 @@ msgid ""
" %2$s.\n"
msgstr "Bank bestätig anlegen der Reserve (%1$s) bei %2$s"
-#: src/webex/pages/popup.tsx:359
+#: src/webex/pages/popup.tsx:358
#, fuzzy, c-format
msgid ""
"Started to withdraw\n"
" %1$s from%2$s(%3$s).\n"
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
-#: src/webex/pages/popup.tsx:369
+#: src/webex/pages/popup.tsx:368
#, c-format
msgid "Merchant%1$soffered contract%2$s;\n"
msgstr ""
-#: src/webex/pages/popup.tsx:379
+#: src/webex/pages/popup.tsx:378
#, fuzzy, c-format
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
-#: src/webex/pages/popup.tsx:389
+#: src/webex/pages/popup.tsx:388
#, fuzzy, c-format
msgid ""
"Paid%1$sto merchant%2$s.\n"
@@ -288,15 +288,20 @@ msgstr "Reserve (%1$s) mit %2$s bei %3$s erzeugt"
#: src/webex/pages/popup.tsx:398
#, c-format
+msgid "Merchant%1$sgave a refund over%2$s.\n"
+msgstr ""
+
+#: src/webex/pages/popup.tsx:405
+#, c-format
msgid "Unknown event (%1$s)"
msgstr ""
-#: src/webex/pages/popup.tsx:441
+#: src/webex/pages/popup.tsx:448
#, c-format
msgid "Error: could not retrieve event history"
msgstr ""
-#: src/webex/pages/popup.tsx:466
+#: src/webex/pages/popup.tsx:473
#, c-format
msgid "Your wallet has no events recorded."
msgstr "Ihre Geldbörse verzeichnet keine Vorkommnisse."
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index 1418b0f58..eb8e36240 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -66,67 +66,67 @@ msgstr ""
msgid "Confirm payment"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:179
+#: src/webex/pages/confirm-create-reserve.tsx:178
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:180
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:181
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:186
+#: src/webex/pages/confirm-create-reserve.tsx:185
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:187
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:188
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:189
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:190
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:244
+#: src/webex/pages/confirm-create-reserve.tsx:243
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:260
+#: src/webex/pages/confirm-create-reserve.tsx:259
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:328
+#: src/webex/pages/confirm-create-reserve.tsx:327
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:334
+#: src/webex/pages/confirm-create-reserve.tsx:333
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:340
+#: src/webex/pages/confirm-create-reserve.tsx:339
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -134,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:349
+#: src/webex/pages/confirm-create-reserve.tsx:348
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -142,58 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:363
+#: src/webex/pages/confirm-create-reserve.tsx:362
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:380
+#: src/webex/pages/confirm-create-reserve.tsx:379
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:423
+#: src/webex/pages/confirm-create-reserve.tsx:422
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:428
+#: src/webex/pages/confirm-create-reserve.tsx:427
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:485
+#: src/webex/pages/confirm-create-reserve.tsx:484
#, 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:570
+#: src/webex/pages/confirm-create-reserve.tsx:569
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:579
+#: src/webex/pages/confirm-create-reserve.tsx:578
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:593
+#: src/webex/pages/confirm-create-reserve.tsx:592
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:600
+#: src/webex/pages/confirm-create-reserve.tsx:599
#, 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:626
+#: src/webex/pages/confirm-create-reserve.tsx:625
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -262,24 +262,24 @@ msgid ""
" %2$s.\n"
msgstr ""
-#: src/webex/pages/popup.tsx:359
+#: src/webex/pages/popup.tsx:358
#, c-format
msgid ""
"Started to withdraw\n"
" %1$s from%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:369
+#: src/webex/pages/popup.tsx:368
#, c-format
msgid "Merchant%1$soffered contract%2$s;\n"
msgstr ""
-#: src/webex/pages/popup.tsx:379
+#: src/webex/pages/popup.tsx:378
#, c-format
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:389
+#: src/webex/pages/popup.tsx:388
#, c-format
msgid ""
"Paid%1$sto merchant%2$s.\n"
@@ -288,15 +288,20 @@ msgstr ""
#: src/webex/pages/popup.tsx:398
#, c-format
+msgid "Merchant%1$sgave a refund over%2$s.\n"
+msgstr ""
+
+#: src/webex/pages/popup.tsx:405
+#, c-format
msgid "Unknown event (%1$s)"
msgstr ""
-#: src/webex/pages/popup.tsx:441
+#: src/webex/pages/popup.tsx:448
#, c-format
msgid "Error: could not retrieve event history"
msgstr ""
-#: src/webex/pages/popup.tsx:466
+#: src/webex/pages/popup.tsx:473
#, c-format
msgid "Your wallet has no events recorded."
msgstr ""
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index 33e2a1755..1d55c916d 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -66,67 +66,67 @@ msgstr ""
msgid "Confirm payment"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:179
+#: src/webex/pages/confirm-create-reserve.tsx:178
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:180
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:181
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:186
+#: src/webex/pages/confirm-create-reserve.tsx:185
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:187
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:188
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:189
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:190
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:244
+#: src/webex/pages/confirm-create-reserve.tsx:243
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:260
+#: src/webex/pages/confirm-create-reserve.tsx:259
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:328
+#: src/webex/pages/confirm-create-reserve.tsx:327
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:334
+#: src/webex/pages/confirm-create-reserve.tsx:333
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:340
+#: src/webex/pages/confirm-create-reserve.tsx:339
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -134,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:349
+#: src/webex/pages/confirm-create-reserve.tsx:348
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -142,58 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:363
+#: src/webex/pages/confirm-create-reserve.tsx:362
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:380
+#: src/webex/pages/confirm-create-reserve.tsx:379
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:423
+#: src/webex/pages/confirm-create-reserve.tsx:422
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:428
+#: src/webex/pages/confirm-create-reserve.tsx:427
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:485
+#: src/webex/pages/confirm-create-reserve.tsx:484
#, 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:570
+#: src/webex/pages/confirm-create-reserve.tsx:569
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:579
+#: src/webex/pages/confirm-create-reserve.tsx:578
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:593
+#: src/webex/pages/confirm-create-reserve.tsx:592
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:600
+#: src/webex/pages/confirm-create-reserve.tsx:599
#, 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:626
+#: src/webex/pages/confirm-create-reserve.tsx:625
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -262,24 +262,24 @@ msgid ""
" %2$s.\n"
msgstr ""
-#: src/webex/pages/popup.tsx:359
+#: src/webex/pages/popup.tsx:358
#, c-format
msgid ""
"Started to withdraw\n"
" %1$s from%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:369
+#: src/webex/pages/popup.tsx:368
#, c-format
msgid "Merchant%1$soffered contract%2$s;\n"
msgstr ""
-#: src/webex/pages/popup.tsx:379
+#: src/webex/pages/popup.tsx:378
#, c-format
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:389
+#: src/webex/pages/popup.tsx:388
#, c-format
msgid ""
"Paid%1$sto merchant%2$s.\n"
@@ -288,15 +288,20 @@ msgstr ""
#: src/webex/pages/popup.tsx:398
#, c-format
+msgid "Merchant%1$sgave a refund over%2$s.\n"
+msgstr ""
+
+#: src/webex/pages/popup.tsx:405
+#, c-format
msgid "Unknown event (%1$s)"
msgstr ""
-#: src/webex/pages/popup.tsx:441
+#: src/webex/pages/popup.tsx:448
#, c-format
msgid "Error: could not retrieve event history"
msgstr ""
-#: src/webex/pages/popup.tsx:466
+#: src/webex/pages/popup.tsx:473
#, c-format
msgid "Your wallet has no events recorded."
msgstr ""
diff --git a/src/i18n/it.po b/src/i18n/it.po
index 33e2a1755..1d55c916d 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -66,67 +66,67 @@ msgstr ""
msgid "Confirm payment"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:179
+#: src/webex/pages/confirm-create-reserve.tsx:178
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:180
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:181
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:186
+#: src/webex/pages/confirm-create-reserve.tsx:185
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:187
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:188
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:189
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:190
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:244
+#: src/webex/pages/confirm-create-reserve.tsx:243
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:260
+#: src/webex/pages/confirm-create-reserve.tsx:259
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:328
+#: src/webex/pages/confirm-create-reserve.tsx:327
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:334
+#: src/webex/pages/confirm-create-reserve.tsx:333
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:340
+#: src/webex/pages/confirm-create-reserve.tsx:339
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -134,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:349
+#: src/webex/pages/confirm-create-reserve.tsx:348
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -142,58 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:363
+#: src/webex/pages/confirm-create-reserve.tsx:362
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:380
+#: src/webex/pages/confirm-create-reserve.tsx:379
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:423
+#: src/webex/pages/confirm-create-reserve.tsx:422
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:428
+#: src/webex/pages/confirm-create-reserve.tsx:427
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:485
+#: src/webex/pages/confirm-create-reserve.tsx:484
#, 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:570
+#: src/webex/pages/confirm-create-reserve.tsx:569
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:579
+#: src/webex/pages/confirm-create-reserve.tsx:578
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:593
+#: src/webex/pages/confirm-create-reserve.tsx:592
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:600
+#: src/webex/pages/confirm-create-reserve.tsx:599
#, 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:626
+#: src/webex/pages/confirm-create-reserve.tsx:625
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -262,24 +262,24 @@ msgid ""
" %2$s.\n"
msgstr ""
-#: src/webex/pages/popup.tsx:359
+#: src/webex/pages/popup.tsx:358
#, c-format
msgid ""
"Started to withdraw\n"
" %1$s from%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:369
+#: src/webex/pages/popup.tsx:368
#, c-format
msgid "Merchant%1$soffered contract%2$s;\n"
msgstr ""
-#: src/webex/pages/popup.tsx:379
+#: src/webex/pages/popup.tsx:378
#, c-format
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:389
+#: src/webex/pages/popup.tsx:388
#, c-format
msgid ""
"Paid%1$sto merchant%2$s.\n"
@@ -288,15 +288,20 @@ msgstr ""
#: src/webex/pages/popup.tsx:398
#, c-format
+msgid "Merchant%1$sgave a refund over%2$s.\n"
+msgstr ""
+
+#: src/webex/pages/popup.tsx:405
+#, c-format
msgid "Unknown event (%1$s)"
msgstr ""
-#: src/webex/pages/popup.tsx:441
+#: src/webex/pages/popup.tsx:448
#, c-format
msgid "Error: could not retrieve event history"
msgstr ""
-#: src/webex/pages/popup.tsx:466
+#: src/webex/pages/popup.tsx:473
#, c-format
msgid "Your wallet has no events recorded."
msgstr ""
diff --git a/src/i18n/strings.ts b/src/i18n/strings.ts
index 41c8d72a2..b83b4ca13 100644
--- a/src/i18n/strings.ts
+++ b/src/i18n/strings.ts
@@ -165,6 +165,9 @@ strings['de'] = {
"Paid%1$sto merchant%2$s.\n (%3$s)\n": [
"Reserve (%1$s) mit %2$s bei %3$s erzeugt"
],
+ "Merchant%1$sgave a refund over%2$s.\n": [
+ ""
+ ],
"Unknown event (%1$s)": [
""
],
@@ -348,6 +351,9 @@ strings['en-US'] = {
"Paid%1$sto merchant%2$s.\n (%3$s)\n": [
""
],
+ "Merchant%1$sgave a refund over%2$s.\n": [
+ ""
+ ],
"Unknown event (%1$s)": [
""
],
@@ -531,6 +537,9 @@ strings['fr'] = {
"Paid%1$sto merchant%2$s.\n (%3$s)\n": [
""
],
+ "Merchant%1$sgave a refund over%2$s.\n": [
+ ""
+ ],
"Unknown event (%1$s)": [
""
],
@@ -714,6 +723,9 @@ strings['it'] = {
"Paid%1$sto merchant%2$s.\n (%3$s)\n": [
""
],
+ "Merchant%1$sgave a refund over%2$s.\n": [
+ ""
+ ],
"Unknown event (%1$s)": [
""
],
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index 33e2a1755..1d55c916d 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -66,67 +66,67 @@ msgstr ""
msgid "Confirm payment"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:179
+#: src/webex/pages/confirm-create-reserve.tsx:178
#, c-format
msgid "Withdrawal fees:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:180
+#: src/webex/pages/confirm-create-reserve.tsx:179
#, c-format
msgid "Rounding loss:"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:181
+#: src/webex/pages/confirm-create-reserve.tsx:180
#, c-format
msgid "Earliest expiration (for deposit): %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:186
+#: src/webex/pages/confirm-create-reserve.tsx:185
#, c-format
msgid "# Coins"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:187
+#: src/webex/pages/confirm-create-reserve.tsx:186
#, c-format
msgid "Value"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:188
+#: src/webex/pages/confirm-create-reserve.tsx:187
#, c-format
msgid "Withdraw Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:189
+#: src/webex/pages/confirm-create-reserve.tsx:188
#, c-format
msgid "Refresh Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:190
+#: src/webex/pages/confirm-create-reserve.tsx:189
#, c-format
msgid "Deposit Fee"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:244
+#: src/webex/pages/confirm-create-reserve.tsx:243
#, c-format
msgid "Select"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:260
+#: src/webex/pages/confirm-create-reserve.tsx:259
#, c-format
msgid "Error: URL may not be relative"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:328
+#: src/webex/pages/confirm-create-reserve.tsx:327
#, c-format
msgid "The exchange is trusted by the wallet.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:334
+#: src/webex/pages/confirm-create-reserve.tsx:333
#, c-format
msgid "The exchange is audited by a trusted auditor.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:340
+#: src/webex/pages/confirm-create-reserve.tsx:339
#, c-format
msgid ""
"Warning: The exchange is neither directly trusted nor audited by a trusted "
@@ -134,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:349
+#: src/webex/pages/confirm-create-reserve.tsx:348
#, c-format
msgid ""
"Using exchange provider%1$s.\n"
@@ -142,58 +142,58 @@ msgid ""
" %2$s in fees.\n"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:363
+#: src/webex/pages/confirm-create-reserve.tsx:362
#, c-format
msgid ""
"Waiting for a response from\n"
" %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:380
+#: src/webex/pages/confirm-create-reserve.tsx:379
#, c-format
msgid ""
"Information about fees will be available when an exchange provider is "
"selected."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:423
+#: src/webex/pages/confirm-create-reserve.tsx:422
#, c-format
msgid "Accept fees and withdraw"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:428
+#: src/webex/pages/confirm-create-reserve.tsx:427
#, c-format
msgid "Change Exchange Provider"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:485
+#: src/webex/pages/confirm-create-reserve.tsx:484
#, 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:570
+#: src/webex/pages/confirm-create-reserve.tsx:569
#, c-format
msgid ""
"Oops, something went wrong. The wallet responded with error status (%1$s)."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:579
+#: src/webex/pages/confirm-create-reserve.tsx:578
#, c-format
msgid "Checking URL, please wait ..."
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:593
+#: src/webex/pages/confirm-create-reserve.tsx:592
#, c-format
msgid "Can't parse amount: %1$s"
msgstr ""
-#: src/webex/pages/confirm-create-reserve.tsx:600
+#: src/webex/pages/confirm-create-reserve.tsx:599
#, 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:626
+#: src/webex/pages/confirm-create-reserve.tsx:625
#, c-format
msgid "Fatal error: \"%1$s\"."
msgstr ""
@@ -262,24 +262,24 @@ msgid ""
" %2$s.\n"
msgstr ""
-#: src/webex/pages/popup.tsx:359
+#: src/webex/pages/popup.tsx:358
#, c-format
msgid ""
"Started to withdraw\n"
" %1$s from%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:369
+#: src/webex/pages/popup.tsx:368
#, c-format
msgid "Merchant%1$soffered contract%2$s;\n"
msgstr ""
-#: src/webex/pages/popup.tsx:379
+#: src/webex/pages/popup.tsx:378
#, c-format
msgid "Withdrew%1$sfrom%2$s(%3$s).\n"
msgstr ""
-#: src/webex/pages/popup.tsx:389
+#: src/webex/pages/popup.tsx:388
#, c-format
msgid ""
"Paid%1$sto merchant%2$s.\n"
@@ -288,15 +288,20 @@ msgstr ""
#: src/webex/pages/popup.tsx:398
#, c-format
+msgid "Merchant%1$sgave a refund over%2$s.\n"
+msgstr ""
+
+#: src/webex/pages/popup.tsx:405
+#, c-format
msgid "Unknown event (%1$s)"
msgstr ""
-#: src/webex/pages/popup.tsx:441
+#: src/webex/pages/popup.tsx:448
#, c-format
msgid "Error: could not retrieve event history"
msgstr ""
-#: src/webex/pages/popup.tsx:466
+#: src/webex/pages/popup.tsx:473
#, c-format
msgid "Your wallet has no events recorded."
msgstr ""
diff --git a/src/libtoolVersion.ts b/src/libtoolVersion.ts
index 8800fde03..cc2435b94 100644
--- a/src/libtoolVersion.ts
+++ b/src/libtoolVersion.ts
@@ -16,7 +16,7 @@
/**
* Semantic versioning, but libtool-style.
- * See https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+ * See https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
*/
@@ -32,7 +32,7 @@ export interface VersionMatchResult {
* Is the first version older (-1), newser (+1) or
* identical (0)?
*/
- currentCmp: number
+ currentCmp: number;
}
interface Version {
@@ -41,6 +41,9 @@ interface Version {
age: number;
}
+/**
+ * Compare two libtool-style version strings.
+ */
export function compare(me: string, other: string): VersionMatchResult|undefined {
const meVer = parseVersion(me);
const otherVer = parseVersion(other);
@@ -60,7 +63,7 @@ export function compare(me: string, other: string): VersionMatchResult|undefined
function parseVersion(v: string): Version|undefined {
const [currentStr, revisionStr, ageStr, ...rest] = v.split(":");
- if (rest.length != 0) {
+ if (rest.length !== 0) {
return undefined;
}
const current = Number.parseInt(currentStr);
diff --git a/src/logging.ts b/src/logging.ts
index 2c559e8d9..ca073c10c 100644
--- a/src/logging.ts
+++ b/src/logging.ts
@@ -221,8 +221,9 @@ const reportCache: { [reportId: string]: any } = {};
* Formatted as RFC4122 version 4 UUID.
*/
function getInsecureUuid() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c: string) => {
+ const r = Math.random() * 16 | 0;
+ const v = c === "x" ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
diff --git a/src/memidb-test.ts b/src/memidb-test.ts
index 8f8498a6e..b6e4792d3 100644
--- a/src/memidb-test.ts
+++ b/src/memidb-test.ts
@@ -30,13 +30,13 @@ test.cb("db open", (t) => {
t.is(evt.newVersion, 1);
t.truthy(req.result);
t.pass();
- }
+ };
req.onsuccess = (evt) => {
t.is(ncb, 1);
t.is(req.result, evt.target);
t.truthy(req.result);
t.end();
- }
+ };
});
test.cb("store creation", (t) => {
@@ -57,10 +57,10 @@ test.cb("store creation", (t) => {
t.is(store3.name, "c-store");
t.deepEqual(Array.from(db.objectStoreNames), ["a-store", "b-store", "c-store"]);
t.pass();
- }
+ };
req.onsuccess = (evt) => {
t.end();
- }
+ };
});
@@ -71,10 +71,10 @@ test.cb("put and get", (t) => {
const db: IDBDatabase = req.result;
const store1 = db.createObjectStore("mystore");
store1.put({answer: 42}, "a");
- }
+ };
req.onsuccess = (evt) => {
- t.end()
- }
+ t.end();
+ };
});
@@ -88,7 +88,7 @@ test("key path evaluation", (t) => {
b: "hello",
"": "spam",
arr: ["foo", "bar"],
- }
+ };
t.deepEqual(memidb.evaluateKeyPath(obj, ""), obj);
t.deepEqual(memidb.evaluateKeyPath(obj, "a.b.c"), 42);
t.deepEqual(memidb.evaluateKeyPath(obj, "a.b"), {c: 42});
@@ -106,7 +106,7 @@ test("key path evaluation with replacement", (t) => {
c: 42,
},
},
- }
+ };
memidb.evaluateKeyPath(obj, "a.b.c", 24);
t.is(obj.a.b.c, 24);
memidb.evaluateKeyPath(obj, "a.b", 24);
diff --git a/src/query.ts b/src/query.ts
index d7689f2bc..653e91a1b 100644
--- a/src/query.ts
+++ b/src/query.ts
@@ -278,7 +278,8 @@ abstract class QueryStreamBase<T> implements QueryStream<T> {
keyFn: (obj: T) => I): QueryStream<JoinResult<T, S>> {
this.root.addStoreAccess(store.name, false);
return new QueryStreamKeyJoin<T, S>(this, store.name, keyFn);
- }
+ }
+
filter(f: (x: any) => boolean): QueryStream<T> {
return new QueryStreamFilter(this, f);
}
diff --git a/src/timer.ts b/src/timer.ts
index 289b46f16..9439b7199 100644
--- a/src/timer.ts
+++ b/src/timer.ts
@@ -79,7 +79,9 @@ export function after(delayMs: number, callback: () => void): TimerHandle {
const nullTimerHandle = {
clear() {
- }
+ // do nothing
+ return;
+ },
};
/**
@@ -109,7 +111,7 @@ export class TimerGroup {
return nullTimerHandle;
}
const h = after(delayMs, callback);
- let myId = this.idGen++;
+ const myId = this.idGen++;
this.timerMap[myId] = h;
const tm = this.timerMap;
@@ -128,7 +130,7 @@ export class TimerGroup {
return nullTimerHandle;
}
const h = every(delayMs, callback);
- let myId = this.idGen++;
+ const myId = this.idGen++;
this.timerMap[myId] = h;
const tm = this.timerMap;
diff --git a/src/types.ts b/src/types.ts
index 4dea8f3b4..20517b7a2 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -839,7 +839,6 @@ export enum CoinStatus {
}
-
/**
* State of returning a list of coins
* to the customer's bank account.
@@ -1198,6 +1197,10 @@ export class ProposalRecord {
@Checkable.Optional(Checkable.Number)
id?: number;
+ /**
+ * Timestamp (in ms) of when the record
+ * was created.
+ */
@Checkable.Number
timestamp: number;
@@ -1450,10 +1453,17 @@ export namespace Amounts {
};
}
+ /**
+ * Convert the amount to a float.
+ */
export function toFloat(a: AmountJson): number {
return a.value + (a.fraction / fractionalBase);
}
+ /**
+ * Convert a float to a Taler amount.
+ * Loss of precision possible.
+ */
export function fromFloat(floatVal: number, currency: string) {
return {
currency,
@@ -1495,7 +1505,7 @@ export interface CheckPayResult {
export type ConfirmPayResult = "paid" | "insufficient-balance";
-/*
+/**
* Activity history record.
*/
export interface HistoryRecord {
@@ -1672,17 +1682,52 @@ export class ReturnCoinsRequest {
}
+/**
+ * Refund permission in the format that the merchant gives it to us.
+ */
export interface RefundPermission {
+ /**
+ * Amount to be refunded.
+ */
refund_amount: AmountJson;
+
+ /**
+ * Fee for the refund.
+ */
refund_fee: AmountJson;
+
+ /**
+ * Contract terms hash to identify the contract that this
+ * refund is for.
+ */
h_contract_terms: string;
+
+ /**
+ * Public key of the coin being refunded.
+ */
coin_pub: string;
+
+ /**
+ * Refund transaction ID between merchant and exchange.
+ */
rtransaction_id: number;
+
+ /**
+ * Public key of the merchant.
+ */
merchant_pub: string;
+
+ /**
+ * Signature made by the merchant over the refund permission.
+ */
merchant_sig: string;
}
+/**
+ * Record that stores status information about one purchase, starting from when
+ * the customer accepts a proposal. Includes refund status if applicable.
+ */
export interface PurchaseRecord {
contractTermsHash: string;
contractTerms: ContractTerms;
diff --git a/src/wallet.ts b/src/wallet.ts
index 2f848c870..703c7b4aa 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -86,8 +86,8 @@ import {
WireFee,
WireInfo,
} from "./types";
-import URI = require("urijs");
+import URI = require("urijs");
/**
@@ -229,7 +229,6 @@ class WireDetailJson {
}
-
/**
* Badge that shows activity for the wallet.
*/
@@ -277,6 +276,11 @@ export interface DepositCoin {
depositedSig?: string;
}
+/**
+ * Record stored in the wallet's database when the user sends coins back to
+ * their own bank account. Stores the status of coins that are deposited to
+ * the wallet itself, where the wallet acts as a "merchant" for the customer.
+ */
export interface CoinsReturnRecord {
/**
* Hash of the contract for sending coins to our own bank account.
@@ -356,7 +360,6 @@ function isWithdrawableDenom(d: DenominationRecord) {
}
-
function strcmp(s1: string, s2: string): number {
if (s1 < s2) {
return -1;
@@ -385,10 +388,13 @@ interface SelectPayCoinsResult {
* Considers refresh fees, withdrawal fees after refresh and amounts too small
* to refresh.
*/
-export function getTotalRefreshCost(denoms: DenominationRecord[], refreshedDenom: DenominationRecord, amountLeft: AmountJson): AmountJson {
+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 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;
@@ -407,7 +413,8 @@ export function selectPayCoins(denoms: DenominationRecord[], cds: CoinWithDenom[
}
// 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));
+ 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 accDepositFee: AmountJson = Amounts.getZero(currency);
@@ -435,7 +442,7 @@ export function selectPayCoins(denoms: DenominationRecord[], cds: CoinWithDenom[
console.log("coin selection", { coversAmount, isBelowFee, accDepositFee, accAmount, paymentAmount });
if ((coversAmount && isBelowFee) || coversAmountWithFee) {
- let depositFeeToCover = Amounts.sub(accDepositFee, depositFeeLimit).amount;
+ const depositFeeToCover = Amounts.sub(accDepositFee, depositFeeLimit).amount;
leftAmount = Amounts.sub(leftAmount, depositFeeToCover).amount;
console.log("deposit fee to cover", amountToPretty(depositFeeToCover));
@@ -798,7 +805,7 @@ export class Wallet {
if (res) {
return res.cds;
}
- return undefined
+ return undefined;
}
@@ -1076,10 +1083,10 @@ export class Wallet {
}
console.log("query for payment succeeded:", t);
return {
- contractTermsHash: t.contractTermsHash,
contractTerms: t.contractTerms,
- payReq: t.payReq,
+ contractTermsHash: t.contractTermsHash,
found: true,
+ payReq: t.payReq,
};
}
@@ -1100,7 +1107,7 @@ export class Wallet {
// random, exponential backoff truncated at 3 minutes
const nextDelay = Math.min(2 * retryDelayMs + retryDelayMs * Math.random(), 3000 * 60);
console.warn(`Failed to deplete reserve, trying again in ${retryDelayMs} ms`);
- this.timerGroup.after(retryDelayMs, () => this.processReserve(reserveRecord, nextDelay))
+ this.timerGroup.after(retryDelayMs, () => this.processReserve(reserveRecord, nextDelay));
} finally {
this.stopOperation(opId);
}
@@ -1115,7 +1122,8 @@ export class Wallet {
// Throttle concurrent executions of this function, so we don't withdraw too many coins at once.
if (this.processPreCoinConcurrent >= 4 || this.processPreCoinThrottle[preCoin.exchangeBaseUrl]) {
console.log("delaying processPreCoin");
- this.timerGroup.after(retryDelayMs, () => this.processPreCoin(preCoin, Math.min(retryDelayMs * 2, 5 * 60 * 1000)));
+ this.timerGroup.after(retryDelayMs,
+ () => this.processPreCoin(preCoin, Math.min(retryDelayMs * 2, 5 * 60 * 1000)));
return;
}
console.log("executing processPreCoin");
@@ -1163,7 +1171,7 @@ export class Wallet {
"ms", e);
// exponential backoff truncated at one minute
const nextRetryDelayMs = Math.min(retryDelayMs * 2, 5 * 60 * 1000);
- this.timerGroup.after(retryDelayMs, () => this.processPreCoin(preCoin, nextRetryDelayMs))
+ this.timerGroup.after(retryDelayMs, () => this.processPreCoin(preCoin, nextRetryDelayMs));
const currentThrottle = this.processPreCoinThrottle[preCoin.exchangeBaseUrl] || 0;
this.processPreCoinThrottle[preCoin.exchangeBaseUrl] = currentThrottle + 1;
@@ -1436,12 +1444,12 @@ export class Wallet {
.toArray()
);
possibleDenoms.sort((d1, d2) => {
- let a1 = Amounts.add(d1.feeWithdraw, d1.value).amount;
- let a2 = Amounts.add(d2.feeWithdraw, d2.value).amount;
+ const a1 = Amounts.add(d1.feeWithdraw, d1.value).amount;
+ const a2 = Amounts.add(d2.feeWithdraw, d2.value).amount;
return Amounts.cmp(a1, a2);
});
- for (let denom of possibleDenoms) {
+ for (const denom of possibleDenoms) {
if (denom.status === DenominationStatus.VerifiedGood) {
return Amounts.add(denom.feeWithdraw, denom.value).amount;
}
@@ -1591,7 +1599,7 @@ export class Wallet {
if (exchangeInfo.protocolVersion) {
versionMatch = LibtoolVersion.compare(WALLET_PROTOCOL_VERSION, exchangeInfo.protocolVersion);
- if (versionMatch && !versionMatch.compatible && versionMatch.currentCmp == -1) {
+ if (versionMatch && !versionMatch.compatible && versionMatch.currentCmp === -1) {
console.log("wallet version might be outdated, checking for updates");
chrome.runtime.requestUpdateCheck((status, details) => {
console.log("update check status:", status);
@@ -1609,10 +1617,10 @@ export class Wallet {
overhead: Amounts.sub(amount, actualCoinCost).amount,
selectedDenoms,
trustedAuditorPubs,
+ versionMatch,
wireFees,
wireInfo,
withdrawFee: acc,
- versionMatch,
};
return ret;
}
@@ -1837,7 +1845,10 @@ export class Wallet {
* Add amount to a balance field, both for
* the slicing by exchange and currency.
*/
- function addTo(balance: WalletBalance, field: keyof WalletBalanceEntry, amount: AmountJson, exchange: string): void {
+ function addTo(balance: WalletBalance,
+ field: keyof WalletBalanceEntry,
+ amount: AmountJson,
+ exchange: string): void {
const z = Amounts.getZero(amount.currency);
const balanceIdentity = {available: z, paybackAmount: z, pendingIncoming: z, pendingPayment: z};
let entryCurr = balance.byCurrency[amount.currency];
@@ -1925,9 +1936,9 @@ export class Wallet {
return sw;
}
- const balance = {
- byExchange: {},
+ const balanceStore = {
byCurrency: {},
+ byExchange: {},
};
// Mapping from exchange pub to smallest
// possible amount we can withdraw
@@ -1941,17 +1952,17 @@ export class Wallet {
const tx = this.q();
tx.iter(Stores.coins)
- .reduce(collectBalances, balance);
+ .reduce(collectBalances, balanceStore);
tx.iter(Stores.refresh)
- .reduce(collectPendingRefresh, balance);
+ .reduce(collectPendingRefresh, balanceStore);
tx.iter(Stores.reserves)
- .reduce(collectPendingWithdraw, balance);
+ .reduce(collectPendingWithdraw, balanceStore);
tx.iter(Stores.reserves)
- .reduce(collectPaybacks, balance);
+ .reduce(collectPaybacks, balanceStore);
tx.iter(Stores.purchases)
- .reduce(collectPayments, balance);
+ .reduce(collectPayments, balanceStore);
await tx.finish();
- return balance;
+ return balanceStore;
}
@@ -2231,28 +2242,28 @@ export class Wallet {
// FIXME: do pagination instead of generating the full history
const proposals = await this.q().iter<ProposalRecord>(Stores.proposals).toArray();
- for (let p of proposals) {
+ for (const p of proposals) {
history.push({
- type: "offer-contract",
- timestamp: p.timestamp,
detail: {
contractTermsHash: p.contractTermsHash,
merchantName: p.contractTerms.merchant.name,
},
+ timestamp: p.timestamp,
+ type: "offer-contract",
});
}
const purchases = await this.q().iter<PurchaseRecord>(Stores.purchases).toArray();
- for (let p of purchases) {
+ for (const p of purchases) {
history.push({
- type: "pay",
- timestamp: p.timestamp,
detail: {
amount: p.contractTerms.amount,
contractTermsHash: p.contractTermsHash,
fulfillmentUrl: p.contractTerms.fulfillment_url,
merchantName: p.contractTerms.merchant.name,
},
+ timestamp: p.timestamp,
+ type: "pay",
});
if (p.timestamp_refund) {
const amountsPending = Object.keys(p.refundsPending).map((x) => p.refundsPending[x].refund_amount);
@@ -2261,44 +2272,44 @@ export class Wallet {
const amount = Amounts.add(Amounts.getZero(p.contractTerms.amount.currency), ...amounts).amount;
history.push({
- type: "refund",
- timestamp: p.timestamp_refund,
detail: {
- refundAmount: amount,
contractTermsHash: p.contractTermsHash,
fulfillmentUrl: p.contractTerms.fulfillment_url,
merchantName: p.contractTerms.merchant.name,
+ refundAmount: amount,
},
+ timestamp: p.timestamp_refund,
+ type: "refund",
});
}
}
const reserves: ReserveRecord[] = await this.q().iter<ReserveRecord>(Stores.reserves).toArray();
- for (let r of reserves) {
+ for (const r of reserves) {
history.push({
- type: "create-reserve",
- timestamp: r.created,
detail: {
exchangeBaseUrl: r.exchange_base_url,
requestedAmount: r.requested_amount,
reservePub: r.reserve_pub,
},
+ timestamp: r.created,
+ type: "create-reserve",
});
if (r.timestamp_depleted) {
history.push({
- type: "depleted-reserve",
- timestamp: r.timestamp_depleted,
detail: {
exchangeBaseUrl: r.exchange_base_url,
requestedAmount: r.requested_amount,
reservePub: r.reserve_pub,
},
+ timestamp: r.timestamp_depleted,
+ type: "depleted-reserve",
});
}
}
history.sort((h1, h2) => Math.sign(h1.timestamp - h2.timestamp));
-
+
return {history};
}
@@ -2563,20 +2574,20 @@ export class Wallet {
H_wire: wireHash,
amount: req.amount,
auditors: [],
- wire_method: wireType,
- pay_deadline: `/Date(${stampSecNow + 60 * 5})/`,
+ exchanges: [ { master_pub: exchange.masterPublicKey, url: exchange.baseUrl } ],
+ extra: {},
+ fulfillment_url: "",
locations: [],
max_fee: req.amount,
merchant: {},
merchant_pub: pub,
- exchanges: [ { master_pub: exchange.masterPublicKey, url: exchange.baseUrl } ],
+ order_id: "none",
+ pay_deadline: `/Date(${stampSecNow + 60 * 5})/`,
+ pay_url: "",
products: [],
refund_deadline: `/Date(${stampSecNow + 60 * 5})/`,
timestamp: `/Date(${stampSecNow})/`,
- order_id: "none",
- pay_url: "",
- fulfillment_url: "",
- extra: {},
+ wire_method: wireType,
};
const contractTermsHash = await this.cryptoApi.hashString(canonicalJson(contractTerms));
@@ -2589,12 +2600,12 @@ export class Wallet {
const coinsReturnRecord: CoinsReturnRecord = {
coins,
- exchange: exchange.baseUrl,
contractTerms,
contractTermsHash,
+ exchange: exchange.baseUrl,
merchantPriv: priv,
wire: req.senderWire,
- }
+ };
await this.q()
.put(Stores.coinsReturns, coinsReturnRecord)
@@ -2611,19 +2622,19 @@ export class Wallet {
continue;
}
const req = {
- f: c.coinPaySig.f,
- wire: coinsReturnRecord.wire,
H_wire: coinsReturnRecord.contractTerms.H_wire,
- h_contract_terms: coinsReturnRecord.contractTermsHash,
coin_pub: c.coinPaySig.coin_pub,
+ coin_sig: c.coinPaySig.coin_sig,
denom_pub: c.coinPaySig.denom_pub,
- ub_sig: c.coinPaySig.ub_sig,
- timestamp: coinsReturnRecord.contractTerms.timestamp,
- wire_transfer_deadline: coinsReturnRecord.contractTerms.pay_deadline,
+ f: c.coinPaySig.f,
+ h_contract_terms: coinsReturnRecord.contractTermsHash,
+ merchant_pub: coinsReturnRecord.contractTerms.merchant_pub,
pay_deadline: coinsReturnRecord.contractTerms.pay_deadline,
refund_deadline: coinsReturnRecord.contractTerms.refund_deadline,
- merchant_pub: coinsReturnRecord.contractTerms.merchant_pub,
- coin_sig: c.coinPaySig.coin_sig,
+ timestamp: coinsReturnRecord.contractTerms.timestamp,
+ ub_sig: c.coinPaySig.ub_sig,
+ wire: coinsReturnRecord.wire,
+ wire_transfer_deadline: coinsReturnRecord.contractTerms.pay_deadline,
};
console.log("req", req);
const reqUrl = (new URI("deposit")).absoluteTo(coinsReturnRecord.exchange);
@@ -2773,7 +2784,7 @@ export class Wallet {
if (refundPermissions.length === 0) {
throw Error("no refunds given");
}
- const coin0 = await this.q().get(Stores.coins, refundPermissions[0].coin_pub)
+ const coin0 = await this.q().get(Stores.coins, refundPermissions[0].coin_pub);
if (!coin0) {
throw Error("coin not found");
}
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index ca51abf1d..0ca903154 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -56,14 +56,14 @@ export interface MessageMap {
"create-reserve": {
request: {
amount: types.AmountJson;
- exchange: string
+ exchange: string
};
response: void;
- };
+ };
"confirm-reserve": {
request: { reservePub: string };
response: void;
- }
+ };
"generate-nonce": {
request: { }
response: string;
@@ -99,7 +99,7 @@ export interface MessageMap {
"reserve-creation-info": {
request: { baseUrl: string, amount: types.AmountJson };
response: types.ReserveCreationInfo;
- }
+ };
"get-history": {
request: { };
response: types.HistoryRecord[];
@@ -139,7 +139,7 @@ export interface MessageMap {
"withdraw-payback-reserve": {
request: { reservePub: string };
response: void;
- }
+ };
"get-precoins": {
request: { exchangeBaseUrl: string };
response: types.PreCoinRecord[];
diff --git a/src/webex/notify.ts b/src/webex/notify.ts
index 7086ca95d..cc8086ceb 100644
--- a/src/webex/notify.ts
+++ b/src/webex/notify.ts
@@ -30,7 +30,7 @@ import wxApi = require("./wxApi");
import { QueryPaymentResult } from "../types";
-import axios from 'axios';
+import axios from "axios";
declare var cloneInto: any;
@@ -111,17 +111,17 @@ async function handlePaymentResponse(maybeFoundResponse: QueryPaymentResult) {
let resp;
try {
const config = {
- timeout: 5000, /* 5 seconds */
headers: { "Content-Type": "application/json;charset=UTF-8" },
- validateStatus: (s: number) => s == 200,
- }
+ timeout: 5000, /* 5 seconds */
+ validateStatus: (s: number) => s === 200,
+ };
resp = await axios.post(walletResp.contractTerms.pay_url, walletResp.payReq, config);
} catch (e) {
// Gives the user the option to retry / abort and refresh
wxApi.logAndDisplayError({
- name: "pay-post-failed",
contractTerms: walletResp.contractTerms,
message: e.message,
+ name: "pay-post-failed",
response: e.response,
});
throw e;
@@ -195,11 +195,11 @@ async function downloadContract(url: string, nonce: string): Promise<any> {
console.log("downloading contract from '" + url + "'");
let resp;
try {
- resp = await axios.get(url, { validateStatus: (s) => s == 200 });
+ resp = await axios.get(url, { validateStatus: (s) => s === 200 });
} catch (e) {
wxApi.logAndDisplayError({
- name: "contract-download-failed",
message: e.message,
+ name: "contract-download-failed",
response: e.response,
sameTab: true,
});
@@ -236,11 +236,11 @@ async function processProposal(proposal: any) {
// bad contract / name not included
}
- let proposalId = await wxApi.saveProposal({
- timestamp: (new Date()).getTime(),
+ const proposalId = await wxApi.saveProposal({
contractTerms: proposal.data,
contractTermsHash: proposal.hash,
merchantSig: proposal.sig,
+ timestamp: (new Date()).getTime(),
});
const uri = new URI(chrome.extension.getURL("/src/webex/pages/confirm-contract.html"));
@@ -265,13 +265,13 @@ function talerPay(msg: any): Promise<any> {
let resp;
try {
const config = {
- validateStatus: (s: number) => s == 200,
- }
+ validateStatus: (s: number) => s === 200,
+ };
resp = await axios.get(msg.refund_url, config);
} catch (e) {
wxApi.logAndDisplayError({
- name: "refund-download-failed",
message: e.message,
+ name: "refund-download-failed",
response: e.response,
sameTab: true,
});
diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx
index 5436cb5a6..f2e22bec4 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -124,9 +124,9 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
alreadyPaid: false,
error: null,
exchanges: null,
- proposal: null,
- payDisabled: true,
holdCheck: false,
+ payDisabled: true,
+ proposal: null,
};
}
@@ -220,8 +220,11 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
(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>
+ {(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>
}
@@ -232,7 +235,11 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
{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 />)}
+ {(this.state.alreadyPaid
+ ? <p className="okaybox">
+ You already paid for this, clicking "Confirm payment" will not cost money again.
+ </p>
+ : <p />)}
{(this.state.error ? <p className="errorbox">{this.state.error}</p> : <p />)}
</div>
<Details exchanges={this.state.exchanges} contractTerms={c} collapsed={!this.state.error}/>
diff --git a/src/webex/pages/confirm-create-reserve.tsx b/src/webex/pages/confirm-create-reserve.tsx
index 7d543860f..0e1cb17df 100644
--- a/src/webex/pages/confirm-create-reserve.tsx
+++ b/src/webex/pages/confirm-create-reserve.tsx
@@ -43,10 +43,10 @@ import {
import {Collapsible, renderAmount} from "../renderHtml";
+import * as moment from "moment";
import * as React from "react";
import * as ReactDOM from "react-dom";
import URI = require("urijs");
-import * as moment from "moment";
function delay<T>(delayMs: number, value: T): Promise<T> {
@@ -80,7 +80,6 @@ class EventTrigger {
}
-
function renderAuditorDetails(rci: ReserveCreationInfo|null) {
console.log("rci", rci);
if (!rci) {
@@ -393,7 +392,7 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
if (rci.versionMatch.compatible) {
return null;
}
- if (rci.versionMatch.currentCmp == -1) {
+ if (rci.versionMatch.currentCmp === -1) {
return (
<p className="errorbox">
Your wallet might be outdated. The exchange has a higher, incompatible
@@ -401,7 +400,7 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
</p>
);
}
- if (rci.versionMatch.currentCmp == 1) {
+ if (rci.versionMatch.currentCmp === 1) {
return (
<p className="errorbox">
The chosen exchange might be outdated. The exchange has a lower, incompatible
@@ -522,10 +521,10 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
}
async confirmReserveImpl(rci: ReserveCreationInfo,
- exchange: string,
- amount: AmountJson,
- callback_url: string,
- sender_wire: object | undefined) {
+ exchange: string,
+ amount: AmountJson,
+ callback_url: string,
+ sender_wire: object | undefined) {
const rawResp = await createReserve({
amount,
exchange: canonicalizeBaseUrl(exchange),
@@ -612,9 +611,9 @@ async function main() {
amount,
callback_url,
currencyRecord,
+ sender_wire,
suggestedExchangeUrl,
wt_types,
- sender_wire,
};
ReactDOM.render(<ExchangeSelection {...args} />, document.getElementById(
diff --git a/src/webex/pages/error.tsx b/src/webex/pages/error.tsx
index 2edef5e5b..dee8ce44e 100644
--- a/src/webex/pages/error.tsx
+++ b/src/webex/pages/error.tsx
@@ -55,9 +55,14 @@ class ErrorView extends React.Component<ErrorProps, { }> {
return (
<div id="main">
<h1>Failed to send payment</h1>
- <p>Failed to send payment for <strong>{summary}</strong> to merchant <strong>{report.contractTerms.merchant.name}</strong>.</p>
- <p>You can <a href={report.contractTerms.fulfillment_url}>retry</a> the payment. If this problem persists,
- please contact the mechant with the error details below.</p>
+ <p>
+ Failed to send payment for <strong>{summary}</strong>{" "}
+ to merchant <strong>{report.contractTerms.merchant.name}</strong>.
+ </p>
+ <p>
+ You can <a href={report.contractTerms.fulfillment_url}>retry</a> the payment.{" "}
+ If this problem persists, please contact the mechant with the error details below.
+ </p>
<Collapsible initiallyCollapsed={true} title="Error Details">
<pre>
{JSON.stringify(report, null, " ")}
diff --git a/src/webex/pages/payback.tsx b/src/webex/pages/payback.tsx
index 51ad8612c..c2a092460 100644
--- a/src/webex/pages/payback.tsx
+++ b/src/webex/pages/payback.tsx
@@ -24,12 +24,12 @@
/**
* Imports.
*/
-import { renderAmount } from "../renderHtml";
import {
ReserveRecord,
} from "../../types";
import { ImplicitStateComponent, StateHolder } from "../components";
+import { renderAmount } from "../renderHtml";
import {
getPaybackReserves,
withdrawPaybackReserve,
diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx
index 4e4e9687c..9c012449c 100644
--- a/src/webex/pages/popup.tsx
+++ b/src/webex/pages/popup.tsx
@@ -105,12 +105,12 @@ class Router extends React.Component<any, any> {
foundChild = child;
}
});
- const child: React.ReactChild | null = foundChild || defaultChild;
- if (!child) {
+ const c: React.ReactChild | null = foundChild || defaultChild;
+ if (!c) {
throw Error("unknown route");
}
- Router.setRoute((child as any).props.route);
- return <div>{child}</div>;
+ Router.setRoute((c as any).props.route);
+ return <div>{c}</div>;
}
}
@@ -367,7 +367,8 @@ function formatHistoryItem(historyItem: HistoryRecord) {
const link = chrome.extension.getURL("view-contract.html");
return (
<i18n.Translate wrap="p">
- Merchant <em>{abbrev(d.merchantName, 15)}</em> offered contract <a href={link}>{abbrev(d.contractTermsHash)}</a>;
+ Merchant <em>{abbrev(d.merchantName, 15)}</em> offered{" "}
+ contract <a href={link}>{abbrev(d.contractTermsHash)}</a>.
</i18n.Translate>
);
}
diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx
index 73bed30ee..e76fdfff3 100644
--- a/src/webex/pages/refund.tsx
+++ b/src/webex/pages/refund.tsx
@@ -26,10 +26,10 @@ import * as React from "react";
import * as ReactDOM from "react-dom";
import URI = require("urijs");
-import * as wxApi from "../wxApi";
import * as types from "../../types";
import { AmountDisplay } from "../renderHtml";
+import * as wxApi from "../wxApi";
interface RefundStatusViewProps {
contractTermsHash: string;
@@ -41,25 +41,30 @@ interface RefundStatusViewState {
gotResult: boolean;
}
+interface RefundDetailProps {
+ purchase: types.PurchaseRecord;
+ fullRefundFees: types.AmountJson;
+}
-const RefundDetail = ({purchase, fullRefundFees}: {purchase: types.PurchaseRecord, fullRefundFees: types.AmountJson}) => {
+const RefundDetail = ({purchase, fullRefundFees}: RefundDetailProps) => {
const pendingKeys = Object.keys(purchase.refundsPending);
const doneKeys = Object.keys(purchase.refundsDone);
- if (pendingKeys.length == 0 && doneKeys.length == 0) {
+ if (pendingKeys.length === 0 && doneKeys.length === 0) {
return <p>No refunds</p>;
}
- const currency = { ...purchase.refundsDone, ...purchase.refundsPending }[([...pendingKeys, ...doneKeys][0])].refund_amount.currency;
+ const firstRefundKey = [...pendingKeys, ...doneKeys][0];
+ const currency = { ...purchase.refundsDone, ...purchase.refundsPending }[firstRefundKey].refund_amount.currency;
if (!currency) {
throw Error("invariant");
}
let amountPending = types.Amounts.getZero(currency);
- for (let k of pendingKeys) {
+ for (const k of pendingKeys) {
amountPending = types.Amounts.add(amountPending, purchase.refundsPending[k].refund_amount).amount;
}
let amountDone = types.Amounts.getZero(currency);
- for (let k of doneKeys) {
+ for (const k of doneKeys) {
amountDone = types.Amounts.add(amountDone, purchase.refundsDone[k].refund_amount).amount;
}
@@ -68,7 +73,9 @@ const RefundDetail = ({purchase, fullRefundFees}: {purchase: types.PurchaseRecor
return (
<div>
{hasPending ? <p>Refund pending: <AmountDisplay amount={amountPending} /></p> : null}
- <p>Refund received: <AmountDisplay amount={amountDone} /> (refund fees: <AmountDisplay amount={fullRefundFees} />)</p>
+ <p>
+ Refund received: <AmountDisplay amount={amountDone} /> (refund fees: <AmountDisplay amount={fullRefundFees} />)
+ </p>
</div>
);
};
@@ -105,9 +112,14 @@ class RefundStatusView extends React.Component<RefundStatusViewProps, RefundStat
return (
<div id="main">
<h1>Refund Status</h1>
- <p>Status of purchase <strong>{summary}</strong> from merchant <strong>{merchantName}</strong> (order id {purchase.contractTerms.order_id}).</p>
+ <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} fullRefundFees={this.state.refundFees!} /> : <p>Purchase not completed.</p>}
+ {purchase.finished
+ ? <RefundDetail purchase={purchase} fullRefundFees={this.state.refundFees!} />
+ : <p>Purchase not completed.</p>}
</div>
);
}
diff --git a/src/webex/pages/reset-required.tsx b/src/webex/pages/reset-required.tsx
index 90ea51abe..6631705af 100644
--- a/src/webex/pages/reset-required.tsx
+++ b/src/webex/pages/reset-required.tsx
@@ -27,7 +27,14 @@ import * as ReactDOM from "react-dom";
import * as wxApi from "../wxApi";
class State {
+ /**
+ * Did the user check the confirmation check box?
+ */
checked: boolean;
+
+ /**
+ * Do we actually need to reset the db?
+ */
resetRequired: boolean;
}
@@ -47,9 +54,15 @@ class ResetNotification extends React.Component<any, State> {
return (
<div>
<h1>Manual Reset Reqired</h1>
- <p>The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.</p>
+ <p>
+ The wallet's database in your browser is incompatible with the {" "}
+ currently installed wallet. Please reset manually.
+ </p>
<p>Once the database format has stabilized, we will provide automatic upgrades.</p>
- <input id="check" type="checkbox" checked={this.state.checked} onChange={(e) => this.setState({checked: e.target.checked})} />{" "}
+ <input id="check"
+ type="checkbox"
+ checked={this.state.checked}
+ onChange={(e) => this.setState({checked: e.target.checked})} />{" "}
<label htmlFor="check">
I understand that I will lose all my data
</label>
diff --git a/src/webex/pages/return-coins.tsx b/src/webex/pages/return-coins.tsx
index 1fdadd2e9..453ae4784 100644
--- a/src/webex/pages/return-coins.tsx
+++ b/src/webex/pages/return-coins.tsx
@@ -95,7 +95,7 @@ class ReturnSelectionItem extends React.Component<ReturnSelectionItemProps, Retu
<select value={this.state.selectedWire} onChange={(evt) => this.setState({selectedWire: evt.target.value})}>
<option style={{display: "none"}}>Select account</option>
{this.state.supportedWires.map((w, n) =>
- <option value={n.toString()} key={JSON.stringify(w)}>{n+1}: {wire.summarizeWire(w)}</option>
+ <option value={n.toString()} key={JSON.stringify(w)}>{n + 1}: {wire.summarizeWire(w)}</option>,
)}
</select>.
</p>
@@ -252,7 +252,9 @@ class ReturnCoins extends React.Component<any, ReturnCoinsState> {
<p>You can send coins back into your own bank account. Note that
you're acting as a merchant when doing this, and thus the same fees apply.</p>
{this.state.lastConfirmedDetail
- ? <p className="okaybox">Transfer of {renderAmount(this.state.lastConfirmedDetail.amount)} successfully initiated.</p>
+ ? <p className="okaybox">
+ Transfer of {renderAmount(this.state.lastConfirmedDetail.amount)} successfully initiated.
+ </p>
: null}
<ReturnSelectionList
selectDetail={(d) => this.selectDetail(d)}
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index d26f726af..792ba2f2c 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -61,16 +61,21 @@ export function abbrev(s: string, n: number = 5) {
}
-
interface CollapsibleState {
collapsed: boolean;
}
+
interface CollapsibleProps {
initiallyCollapsed: boolean;
title: string;
}
+
+/**
+ * Component that shows/hides its children when clicking
+ * a heading.
+ */
export class Collapsible extends React.Component<CollapsibleProps, CollapsibleState> {
constructor(props: CollapsibleProps) {
super(props);
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index c1c6eb2d3..7afc116ba 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -40,7 +40,7 @@ import {
WalletBalance,
} from "../types";
-import { MessageType, MessageMap } from "./messages";
+import { MessageMap, MessageType } from "./messages";
/**
@@ -328,18 +328,33 @@ export function logAndDisplayError(args: any): Promise<void> {
return callBackend("log-and-display-error", args);
}
-export function getReport(reportUid: string): Promise<void> {
+/**
+ * Get an error report from the logging database for the
+ * given report UID.
+ */
+export function getReport(reportUid: string): Promise<any> {
return callBackend("get-report", { reportUid });
}
+/**
+ * Apply a refund that we got from the merchant.
+ */
export function acceptRefund(refundData: any): Promise<number> {
return callBackend("accept-refund", refundData);
}
+/**
+ * Look up a purchase in the wallet database from
+ * the contract terms hash.
+ */
export function getPurchase(contractTermsHash: string): Promise<PurchaseRecord> {
return callBackend("get-purchase", { contractTermsHash });
}
+/**
+ * Get the refund fees for a refund permission, including
+ * subsequent refresh and unrefreshable coins.
+ */
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 e7f571b92..7393c8880 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -230,7 +230,7 @@ function handleMessage(sender: MessageSender,
if (typeof detail.exchangeBaseUrl !== "string") {
return Promise.reject(Error("exchangBaseUrl missing"));
}
- return needsWallet().getPreCoins(detail.exchangeBaseUrl);
+ return needsWallet().getPreCoins(detail.exchangeBaseUrl);
}
case "get-denoms": {
if (typeof detail.exchangeBaseUrl !== "string") {
@@ -287,10 +287,10 @@ function handleMessage(sender: MessageSender,
dbResetRequired = true;
}
const resp: wxApi.UpgradeResponse = {
- dbResetRequired,
currentDbVersion: WALLET_DB_VERSION.toString(),
+ dbResetRequired,
oldDbVersion: (oldDbVersion || "unknown").toString(),
- }
+ };
return resp;
}
case "log-and-display-error":
@@ -307,12 +307,13 @@ function handleMessage(sender: MessageSender,
return logging.getReport(detail.reportUid);
case "accept-refund":
return needsWallet().acceptRefund(detail.refund_permissions);
- case "get-purchase":
+ case "get-purchase": {
const contractTermsHash = detail.contractTermsHash;
if (!contractTermsHash) {
throw Error("contractTermsHash missing");
}
return needsWallet().getPurchase(contractTermsHash);
+ }
case "get-full-refund-fees":
return needsWallet().getFullRefundFees(detail.refundPermissions);
default:
@@ -452,7 +453,7 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
return;
}
- if (operation == "confirm-reserve") {
+ if (operation === "confirm-reserve") {
const reservePub = headers["x-taler-reserve-pub"];
if (reservePub !== undefined) {
console.log(`confirming reserve ${reservePub} via 201`);
@@ -462,7 +463,7 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
return;
}
- if (operation == "create-reserve") {
+ if (operation === "create-reserve") {
const amount = headers["x-taler-amount"];
if (!amount) {
console.log("202 not understood (X-Taler-Amount missing)");
@@ -477,13 +478,13 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
try {
amountParsed = JSON.parse(amount);
} catch (e) {
- const uri = new URI(chrome.extension.getURL("/src/webex/pages/error.html"));
+ const errUri = new URI(chrome.extension.getURL("/src/webex/pages/error.html"));
const p = {
message: `Can't parse amount ("${amount}"): ${e.message}`,
};
- const redirectUrl = uri.query(p).href();
+ const errRedirectUrl = errUri.query(p).href();
// FIXME: use direct redirect when https://bugzilla.mozilla.org/show_bug.cgi?id=707624 is fixed
- chrome.tabs.update(tabId, {url: redirectUrl});
+ chrome.tabs.update(tabId, {url: errRedirectUrl});
return;
}
const wtTypes = headers["x-taler-wt-types"];
@@ -495,9 +496,9 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
amount,
bank_url: url,
callback_url: new URI(callbackUrl) .absoluteTo(url),
+ sender_wire: headers["x-taler-sender-wire"],
suggested_exchange_url: headers["x-taler-suggested-exchange"],
wt_types: wtTypes,
- sender_wire: headers["x-taler-sender-wire"],
};
const uri = new URI(chrome.extension.getURL("/src/webex/pages/confirm-create-reserve.html"));
const redirectUrl = uri.query(params).href();
@@ -584,7 +585,7 @@ export async function wxMain() {
chrome.runtime.onUpdateAvailable.addListener((details) => {
console.log("update available:", details);
chrome.runtime.reload();
- })
+ });
window.onerror = (m, source, lineno, colno, error) => {
logging.record("error", m + error, undefined, source || "(unknown)", lineno || 0, colno || 0);
diff --git a/src/wire.ts b/src/wire.ts
index d61e8eab2..c06a30bbd 100644
--- a/src/wire.ts
+++ b/src/wire.ts
@@ -29,7 +29,7 @@ import * as i18n from "./i18n";
/**
* Short summary of the wire information.
- *
+ *
* Might abbreviate and return the same summary for different
* wire details.
*/