diff --git a/src/amounts.ts b/src/amounts.ts index fafbcb3ef..280cd636c 100644 --- a/src/amounts.ts +++ b/src/amounts.ts @@ -19,16 +19,19 @@ * Types and helper functions for dealing with Taler amounts. */ + /** * Imports. */ import { Checkable } from "./checkable"; + /** * Number of fractional units that one value unit represents. */ export const fractionalBase = 1e8; + /** * Non-negative financial amount. Fractional values are expressed as multiples * of 1e-8. @@ -60,6 +63,7 @@ export class AmountJson { static checked: (obj: any) => AmountJson; } + /** * Result of a possibly overflowing operation. */ @@ -74,6 +78,7 @@ export interface Result { saturated: boolean; } + /** * Get the largest amount that is safely representable. */ @@ -85,6 +90,7 @@ export function getMaxAmount(currency: string): AmountJson { }; } + /** * Get an amount that represents zero units of a currency. */ @@ -96,6 +102,7 @@ export function getZero(currency: string): AmountJson { }; } + /** * Add two amounts. Return the result and whether * the addition overflowed. The overflow is always handled @@ -124,6 +131,7 @@ export function add(first: AmountJson, ...rest: AmountJson[]): Result { return { amount: { currency, value, fraction }, saturated: false }; } + /** * Subtract two amounts. Return the result and whether * the subtraction overflowed. The overflow is always handled @@ -158,6 +166,7 @@ export function sub(a: AmountJson, ...rest: AmountJson[]): Result { return { amount: { currency, value, fraction }, saturated: false }; } + /** * Compare two amounts. Returns 0 when equal, -1 when a < b * and +1 when a > b. Throws when currencies don't match. @@ -186,6 +195,7 @@ export function cmp(a: AmountJson, b: AmountJson): number { } } + /** * Create a copy of an amount. */ @@ -197,6 +207,7 @@ export function copy(a: AmountJson): AmountJson { }; } + /** * Divide an amount. Throws on division by zero. */ @@ -215,6 +226,7 @@ export function divide(a: AmountJson, n: number): AmountJson { }; } + /** * Check if an amount is non-zero. */ @@ -222,6 +234,7 @@ export function isNonZero(a: AmountJson): boolean { return a.value > 0 || a.fraction > 0; } + /** * Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct. */ @@ -237,6 +250,11 @@ export function parse(s: string): AmountJson|undefined { }; } + +/** + * Parse amount in standard string form (like 'EUR:20.5'), + * throw if the input is not a valid amount. + */ export function parseOrThrow(s: string): AmountJson { const res = parse(s); if (!res) { @@ -245,6 +263,7 @@ export function parseOrThrow(s: string): AmountJson { return res; } + /** * Convert the amount to a float. */ @@ -252,6 +271,7 @@ export function toFloat(a: AmountJson): number { return a.value + (a.fraction / fractionalBase); } + /** * Convert a float to a Taler amount. * Loss of precision possible. @@ -264,6 +284,7 @@ export function fromFloat(floatVal: number, currency: string) { }; } + /** * Convert to standard human-readable string representation that's * also used in JSON formats. @@ -272,6 +293,10 @@ export function toString(a: AmountJson) { return `${a.currency}:${a.value + (a.fraction / fractionalBase)}`; } + +/** + * Check if the argument is a valid amount in string form. + */ export function check(a: any) { if (typeof a !== "string") { return false; diff --git a/src/i18n.tsx b/src/i18n.tsx index dfd1528e3..ddf4fb768 100644 --- a/src/i18n.tsx +++ b/src/i18n.tsx @@ -26,24 +26,32 @@ import {strings} from "./i18n/strings"; import * as jedLib from "jed"; import * as React from "react"; -let lang: string; -try { - lang = chrome.i18n.getUILanguage(); - // Chrome gives e.g. "en-US", but Firefox gives us "en_US" - lang = lang.replace("_", "-"); -} catch (e) { - lang = "en"; - console.warn("i18n default language not available"); + +const jed = setupJed(); + + +/** + * Set up jed library for internationalization, + * based on browser language settings. + */ +function setupJed(): any { + let lang: string; + try { + lang = chrome.i18n.getUILanguage(); + // Chrome gives e.g. "en-US", but Firefox gives us "en_US" + lang = lang.replace("_", "-"); + } catch (e) { + lang = "en"; + console.warn("i18n default language not available"); + } + + if (!strings[lang]) { + lang = "en-US"; + console.log(`language ${lang} not found, defaulting to english`); + } + return new jedLib.Jed(strings[lang]); } -if (!strings[lang]) { - lang = "en-US"; - console.log(`language ${lang} not found, defaulting to english`); -} - -const jed = new jedLib.Jed(strings[lang]); - - /** * Convert template strings to a msgid diff --git a/src/talerTypes.ts b/src/talerTypes.ts index 15e0009fd..f8fb72b93 100644 --- a/src/talerTypes.ts +++ b/src/talerTypes.ts @@ -896,9 +896,16 @@ export function isWireDetail(x: any): x is WireDetail { */ @Checkable.Class({extra: true}) export class Proposal { + /** + * Contract terms for the propoal. + */ @Checkable.Value(() => ContractTerms) contract_terms: ContractTerms; + /** + * Signature over contract, made by the merchant. The public key used for signing + * must be contract_terms.merchant_pub. + */ @Checkable.String() sig: string; diff --git a/src/wallet.ts b/src/wallet.ts index 1d15722e3..8655c59ca 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -2754,7 +2754,7 @@ export class Wallet { return this.activeTipOperations[key]; } const p = this.processTipImpl(tipToken); - this.activeTipOperations[key] = p + this.activeTipOperations[key] = p; try { return await p; } finally { @@ -2892,7 +2892,7 @@ export class Wallet { async getTipStatus(tipToken: TipToken): Promise { const tipId = tipToken.tip_id; const merchantDomain = new URI(tipToken.pickup_url).origin(); - let tipRecord = await this.q().get(Stores.tips, [tipId, merchantDomain]); + const tipRecord = await this.q().get(Stores.tips, [tipId, merchantDomain]); const amount = Amounts.parseOrThrow(tipToken.amount); const exchangeUrl = tipToken.exchange_url; this.processTip(tipToken); diff --git a/src/webex/compat.ts b/src/webex/compat.ts index 30ffd4a81..65ddfab4a 100644 --- a/src/webex/compat.ts +++ b/src/webex/compat.ts @@ -15,9 +15,9 @@ */ /** -* Compatibility helpers needed for browsers that don't implement -* WebExtension APIs consistently. -*/ + * Compatibility helpers needed for browsers that don't implement + * WebExtension APIs consistently. + */ export function isFirefox(): boolean { const rt = chrome.runtime as any; diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx index f1e98f22b..41eebda8e 100644 --- a/src/webex/pages/confirm-contract.tsx +++ b/src/webex/pages/confirm-contract.tsx @@ -379,7 +379,8 @@ class ContractPrompt extends React.Component - The total price is {amount} (plus {renderAmount(this.state.payStatus.coinSelection.totalFees)} fees). + The total price is {amount} + (plus {renderAmount(this.state.payStatus.coinSelection.totalFees)} fees). : The total price is {amount}. diff --git a/src/webex/pages/confirm-create-reserve.tsx b/src/webex/pages/confirm-create-reserve.tsx index 5be6fe351..cef647163 100644 --- a/src/webex/pages/confirm-create-reserve.tsx +++ b/src/webex/pages/confirm-create-reserve.tsx @@ -340,7 +340,7 @@ class ExchangeSelection extends ImplicitStateComponent { )} diff --git a/src/webex/pages/tip.tsx b/src/webex/pages/tip.tsx index 6fbb3005d..c13120c43 100644 --- a/src/webex/pages/tip.tsx +++ b/src/webex/pages/tip.tsx @@ -30,8 +30,8 @@ import * as i18n from "../../i18n"; import { acceptTip, - getTipStatus, getReserveCreationInfo, + getTipStatus, } from "../wxApi"; import { diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts index 32788d37b..e5da642f1 100644 --- a/src/webex/wxApi.ts +++ b/src/webex/wxApi.ts @@ -72,6 +72,9 @@ export interface UpgradeResponse { } +/** + * Error thrown when the function from the backend (via RPC) threw an error. + */ export class WalletApiError extends Error { constructor(message: string, public detail: any) { super(message); diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts index 0b4f0976e..b1aecbbdd 100644 --- a/src/webex/wxBackend.ts +++ b/src/webex/wxBackend.ts @@ -475,7 +475,10 @@ function waitMs(timeoutMs: number): Promise { } -function makeSyncWalletRedirect(url: string, tabId: number, oldUrl: string, params?: {[name: string]: string | undefined}): object { +function makeSyncWalletRedirect(url: string, + tabId: number, + oldUrl: string, + params?: {[name: string]: string | undefined}): object { const innerUrl = new URI(chrome.extension.getURL("/src/webex/pages/" + url)); if (params) { for (const key in params) { @@ -552,8 +555,8 @@ function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url: stri if (fields.contract_url) { return makeSyncWalletRedirect("confirm-contract.html", tabId, url, { contractUrl: fields.contract_url, - sessionId: fields.session_id, resourceUrl: fields.resource_url, + sessionId: fields.session_id, }); }