make linter less grumpy
This commit is contained in:
parent
f36bb7a04e
commit
47787c0b0b
29
.eslintrc.js
29
.eslintrc.js
@ -1,13 +1,26 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["@typescript-eslint"],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:react/recommended",
|
||||
],
|
||||
rules: {},
|
||||
rules: {
|
||||
"no-constant-condition": ["error", { "checkLoops": false }],
|
||||
"prefer-const": ["warn", { destructuring: "all" }],
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }],
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"warn",
|
||||
{ allowExpressions: true },
|
||||
],
|
||||
"@typescript-eslint/no-use-before-define": [
|
||||
"error",
|
||||
{ functions: false, classes: false },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
3
Makefile
3
Makefile
@ -84,3 +84,6 @@ endif
|
||||
rollup: tsc
|
||||
./node_modules/.bin/rollup -c
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
./node_modules/.bin/eslint 'src/**/*'
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -620,7 +620,7 @@ export async function processDownloadProposal(
|
||||
proposalId: string,
|
||||
forceNow = false,
|
||||
): Promise<void> {
|
||||
const onOpErr = (err: OperationError) =>
|
||||
const onOpErr = (err: OperationError): Promise<void> =>
|
||||
incrementProposalRetry(ws, proposalId, err);
|
||||
await guardOperationException(
|
||||
() => processDownloadProposalImpl(ws, proposalId, forceNow),
|
||||
@ -631,7 +631,7 @@ export async function processDownloadProposal(
|
||||
async function resetDownloadProposalRetry(
|
||||
ws: InternalWalletState,
|
||||
proposalId: string,
|
||||
) {
|
||||
): Promise<void> {
|
||||
await ws.db.mutate(Stores.proposals, proposalId, (x) => {
|
||||
if (x.retryInfo.active) {
|
||||
x.retryInfo = initRetryInfo();
|
||||
@ -1108,7 +1108,7 @@ export async function processPurchasePay(
|
||||
proposalId: string,
|
||||
forceNow = false,
|
||||
): Promise<void> {
|
||||
const onOpErr = (e: OperationError) =>
|
||||
const onOpErr = (e: OperationError): Promise<void> =>
|
||||
incrementPurchasePayRetry(ws, proposalId, e);
|
||||
await guardOperationException(
|
||||
() => processPurchasePayImpl(ws, proposalId, forceNow),
|
||||
@ -1119,7 +1119,7 @@ export async function processPurchasePay(
|
||||
async function resetPurchasePayRetry(
|
||||
ws: InternalWalletState,
|
||||
proposalId: string,
|
||||
) {
|
||||
): Promise<void> {
|
||||
await ws.db.mutate(Stores.purchases, proposalId, (x) => {
|
||||
if (x.payRetryInfo.active) {
|
||||
x.payRetryInfo = initRetryInfo();
|
||||
@ -1150,7 +1150,7 @@ async function processPurchasePayImpl(
|
||||
export async function refuseProposal(
|
||||
ws: InternalWalletState,
|
||||
proposalId: string,
|
||||
) {
|
||||
): Promise<void> {
|
||||
const success = await ws.db.runWithWriteTransaction(
|
||||
[Stores.proposals],
|
||||
async (tx) => {
|
||||
|
@ -302,7 +302,7 @@ export async function processPurchaseQueryRefund(
|
||||
proposalId: string,
|
||||
forceNow = false,
|
||||
): Promise<void> {
|
||||
const onOpErr = (e: OperationError) =>
|
||||
const onOpErr = (e: OperationError): Promise<void> =>
|
||||
incrementPurchaseQueryRefundRetry(ws, proposalId, e);
|
||||
await guardOperationException(
|
||||
() => processPurchaseQueryRefundImpl(ws, proposalId, forceNow),
|
||||
@ -313,7 +313,7 @@ export async function processPurchaseQueryRefund(
|
||||
async function resetPurchaseQueryRefundRetry(
|
||||
ws: InternalWalletState,
|
||||
proposalId: string,
|
||||
) {
|
||||
): Promise<void> {
|
||||
await ws.db.mutate(Stores.purchases, proposalId, (x) => {
|
||||
if (x.refundStatusRetryInfo.active) {
|
||||
x.refundStatusRetryInfo = initRetryInfo();
|
||||
@ -368,7 +368,7 @@ export async function processPurchaseApplyRefund(
|
||||
proposalId: string,
|
||||
forceNow = false,
|
||||
): Promise<void> {
|
||||
const onOpErr = (e: OperationError) =>
|
||||
const onOpErr = (e: OperationError): Promise<void> =>
|
||||
incrementPurchaseApplyRefundRetry(ws, proposalId, e);
|
||||
await guardOperationException(
|
||||
() => processPurchaseApplyRefundImpl(ws, proposalId, forceNow),
|
||||
@ -379,7 +379,7 @@ export async function processPurchaseApplyRefund(
|
||||
async function resetPurchaseApplyRefundRetry(
|
||||
ws: InternalWalletState,
|
||||
proposalId: string,
|
||||
) {
|
||||
): Promise<void> {
|
||||
await ws.db.mutate(Stores.purchases, proposalId, (x) => {
|
||||
if (x.refundApplyRetryInfo.active) {
|
||||
x.refundApplyRetryInfo = initRetryInfo();
|
||||
@ -435,11 +435,10 @@ async function processPurchaseApplyRefundImpl(
|
||||
// We're too late, refund is expired.
|
||||
newRefundsFailed[pk] = info;
|
||||
break;
|
||||
default:
|
||||
default: {
|
||||
let body: string | null = null;
|
||||
try {
|
||||
// FIXME: error handling!
|
||||
body = await resp.json();
|
||||
} catch {}
|
||||
const m = "refund request (at exchange) failed";
|
||||
throw new OperationFailedError({
|
||||
message: m,
|
||||
@ -450,6 +449,7 @@ async function processPurchaseApplyRefundImpl(
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let allRefundsProcessed = false;
|
||||
await ws.db.runWithWriteTransaction(
|
||||
[Stores.purchases, Stores.coins, Stores.refreshGroups, Stores.refundEvents],
|
||||
|
@ -23,11 +23,9 @@
|
||||
*/
|
||||
import {
|
||||
codecForString,
|
||||
typecheckedCodec,
|
||||
makeCodecForObject,
|
||||
makeCodecForConstString,
|
||||
makeCodecForUnion,
|
||||
makeCodecForList,
|
||||
Codec,
|
||||
} from "../util/codec";
|
||||
import { AmountString } from "./talerTypes";
|
||||
import {
|
||||
@ -52,10 +50,8 @@ export interface ReserveStatus {
|
||||
history: ReserveTransaction[];
|
||||
}
|
||||
|
||||
export const codecForReserveStatus = () =>
|
||||
typecheckedCodec<ReserveStatus>(
|
||||
export const codecForReserveStatus = (): Codec<ReserveStatus> =>
|
||||
makeCodecForObject<ReserveStatus>()
|
||||
.property("balance", codecForString)
|
||||
.property("history", makeCodecForList(codecForReserveTransaction()))
|
||||
.build("ReserveStatus"),
|
||||
);
|
||||
.build("ReserveStatus");
|
||||
|
@ -23,10 +23,10 @@
|
||||
*/
|
||||
import {
|
||||
codecForString,
|
||||
typecheckedCodec,
|
||||
makeCodecForObject,
|
||||
makeCodecForConstString,
|
||||
makeCodecForUnion,
|
||||
Codec,
|
||||
} from "../util/codec";
|
||||
import {
|
||||
AmountString,
|
||||
@ -179,8 +179,7 @@ export type ReserveTransaction =
|
||||
| ReserveClosingTransaction
|
||||
| ReserveRecoupTransaction;
|
||||
|
||||
export const codecForReserveWithdrawTransaction = () =>
|
||||
typecheckedCodec<ReserveWithdrawTransaction>(
|
||||
export const codecForReserveWithdrawTransaction = (): Codec<ReserveWithdrawTransaction> =>
|
||||
makeCodecForObject<ReserveWithdrawTransaction>()
|
||||
.property("amount", codecForString)
|
||||
.property("h_coin_envelope", codecForString)
|
||||
@ -191,22 +190,18 @@ export const codecForReserveWithdrawTransaction = () =>
|
||||
makeCodecForConstString(ReserveTransactionType.Withdraw),
|
||||
)
|
||||
.property("withdraw_fee", codecForString)
|
||||
.build("ReserveWithdrawTransaction"),
|
||||
);
|
||||
.build("ReserveWithdrawTransaction");
|
||||
|
||||
export const codecForReserveCreditTransaction = () =>
|
||||
typecheckedCodec<ReserveCreditTransaction>(
|
||||
export const codecForReserveCreditTransaction = (): Codec<ReserveCreditTransaction> =>
|
||||
makeCodecForObject<ReserveCreditTransaction>()
|
||||
.property("amount", codecForString)
|
||||
.property("sender_account_url", codecForString)
|
||||
.property("timestamp", codecForTimestamp)
|
||||
.property("wire_reference", codecForString)
|
||||
.property("type", makeCodecForConstString(ReserveTransactionType.Credit))
|
||||
.build("ReserveCreditTransaction"),
|
||||
);
|
||||
.build("ReserveCreditTransaction");
|
||||
|
||||
export const codecForReserveClosingTransaction = () =>
|
||||
typecheckedCodec<ReserveClosingTransaction>(
|
||||
export const codecForReserveClosingTransaction = (): Codec<ReserveClosingTransaction> =>
|
||||
makeCodecForObject<ReserveClosingTransaction>()
|
||||
.property("amount", codecForString)
|
||||
.property("closing_fee", codecForString)
|
||||
@ -216,11 +211,9 @@ export const codecForReserveClosingTransaction = () =>
|
||||
.property("timestamp", codecForTimestamp)
|
||||
.property("type", makeCodecForConstString(ReserveTransactionType.Closing))
|
||||
.property("wtid", codecForString)
|
||||
.build("ReserveClosingTransaction"),
|
||||
);
|
||||
.build("ReserveClosingTransaction");
|
||||
|
||||
export const codecForReserveRecoupTransaction = () =>
|
||||
typecheckedCodec<ReserveRecoupTransaction>(
|
||||
export const codecForReserveRecoupTransaction = (): Codec<ReserveRecoupTransaction> =>
|
||||
makeCodecForObject<ReserveRecoupTransaction>()
|
||||
.property("amount", codecForString)
|
||||
.property("coin_pub", codecForString)
|
||||
@ -228,11 +221,9 @@ export const codecForReserveRecoupTransaction = () =>
|
||||
.property("exchange_sig", codecForString)
|
||||
.property("timestamp", codecForTimestamp)
|
||||
.property("type", makeCodecForConstString(ReserveTransactionType.Recoup))
|
||||
.build("ReserveRecoupTransaction"),
|
||||
);
|
||||
.build("ReserveRecoupTransaction");
|
||||
|
||||
export const codecForReserveTransaction = () =>
|
||||
typecheckedCodec<ReserveTransaction>(
|
||||
export const codecForReserveTransaction = (): Codec<ReserveTransaction> =>
|
||||
makeCodecForUnion<ReserveTransaction>()
|
||||
.discriminateOn("type")
|
||||
.alternative(
|
||||
@ -251,5 +242,4 @@ export const codecForReserveTransaction = () =>
|
||||
ReserveTransactionType.Credit,
|
||||
codecForReserveCreditTransaction(),
|
||||
)
|
||||
.build<ReserveTransaction>("ReserveTransaction"),
|
||||
);
|
||||
.build<ReserveTransaction>("ReserveTransaction");
|
||||
|
@ -28,7 +28,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
typecheckedCodec,
|
||||
makeCodecForObject,
|
||||
codecForString,
|
||||
makeCodecForList,
|
||||
@ -37,6 +36,7 @@ import {
|
||||
codecForNumber,
|
||||
codecForBoolean,
|
||||
makeCodecForMap,
|
||||
Codec,
|
||||
} from "../util/codec";
|
||||
import {
|
||||
Timestamp,
|
||||
@ -786,8 +786,7 @@ export type EddsaSignatureString = string;
|
||||
export type EddsaPublicKeyString = string;
|
||||
export type CoinPublicKeyString = string;
|
||||
|
||||
export const codecForDenomination = () =>
|
||||
typecheckedCodec<Denomination>(
|
||||
export const codecForDenomination = (): Codec<Denomination> =>
|
||||
makeCodecForObject<Denomination>()
|
||||
.property("value", codecForString)
|
||||
.property("denom_pub", codecForString)
|
||||
@ -800,48 +799,35 @@ export const codecForDenomination = () =>
|
||||
.property("stamp_expire_legal", codecForTimestamp)
|
||||
.property("stamp_expire_deposit", codecForTimestamp)
|
||||
.property("master_sig", codecForString)
|
||||
.build("Denomination"),
|
||||
);
|
||||
.build("Denomination");
|
||||
|
||||
export const codecForAuditorDenomSig = () =>
|
||||
typecheckedCodec<AuditorDenomSig>(
|
||||
export const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> =>
|
||||
makeCodecForObject<AuditorDenomSig>()
|
||||
.property("denom_pub_h", codecForString)
|
||||
.property("auditor_sig", codecForString)
|
||||
.build("AuditorDenomSig"),
|
||||
);
|
||||
.build("AuditorDenomSig");
|
||||
|
||||
export const codecForAuditor = () =>
|
||||
typecheckedCodec<Auditor>(
|
||||
export const codecForAuditor = (): Codec<Auditor> =>
|
||||
makeCodecForObject<Auditor>()
|
||||
.property("auditor_pub", codecForString)
|
||||
.property("auditor_url", codecForString)
|
||||
.property(
|
||||
"denomination_keys",
|
||||
makeCodecForList(codecForAuditorDenomSig()),
|
||||
)
|
||||
.build("Auditor"),
|
||||
);
|
||||
.property("denomination_keys", makeCodecForList(codecForAuditorDenomSig()))
|
||||
.build("Auditor");
|
||||
|
||||
export const codecForExchangeHandle = () =>
|
||||
typecheckedCodec<ExchangeHandle>(
|
||||
export const codecForExchangeHandle = (): Codec<ExchangeHandle> =>
|
||||
makeCodecForObject<ExchangeHandle>()
|
||||
.property("master_pub", codecForString)
|
||||
.property("url", codecForString)
|
||||
.build("ExchangeHandle"),
|
||||
);
|
||||
.build("ExchangeHandle");
|
||||
|
||||
export const codecForAuditorHandle = () =>
|
||||
typecheckedCodec<AuditorHandle>(
|
||||
export const codecForAuditorHandle = (): Codec<AuditorHandle> =>
|
||||
makeCodecForObject<AuditorHandle>()
|
||||
.property("name", codecForString)
|
||||
.property("master_pub", codecForString)
|
||||
.property("url", codecForString)
|
||||
.build("AuditorHandle"),
|
||||
);
|
||||
.build("AuditorHandle");
|
||||
|
||||
export const codecForContractTerms = () =>
|
||||
typecheckedCodec<ContractTerms>(
|
||||
export const codecForContractTerms = (): Codec<ContractTerms> =>
|
||||
makeCodecForObject<ContractTerms>()
|
||||
.property("order_id", codecForString)
|
||||
.property("fulfillment_url", codecForString)
|
||||
@ -865,22 +851,22 @@ export const codecForContractTerms = () =>
|
||||
.property("exchanges", makeCodecForList(codecForExchangeHandle()))
|
||||
.property("products", makeCodecOptional(makeCodecForList(codecForAny)))
|
||||
.property("extra", codecForAny)
|
||||
.build("ContractTerms"),
|
||||
);
|
||||
.build("ContractTerms");
|
||||
|
||||
export const codecForMerchantRefundPermission = () =>
|
||||
typecheckedCodec<MerchantRefundPermission>(
|
||||
export const codecForMerchantRefundPermission = (): Codec<
|
||||
MerchantRefundPermission
|
||||
> =>
|
||||
makeCodecForObject<MerchantRefundPermission>()
|
||||
.property("refund_amount", codecForString)
|
||||
.property("refund_fee", codecForString)
|
||||
.property("coin_pub", codecForString)
|
||||
.property("rtransaction_id", codecForNumber)
|
||||
.property("merchant_sig", codecForString)
|
||||
.build("MerchantRefundPermission"),
|
||||
);
|
||||
.build("MerchantRefundPermission");
|
||||
|
||||
export const codecForMerchantRefundResponse = () =>
|
||||
typecheckedCodec<MerchantRefundResponse>(
|
||||
export const codecForMerchantRefundResponse = (): Codec<
|
||||
MerchantRefundResponse
|
||||
> =>
|
||||
makeCodecForObject<MerchantRefundResponse>()
|
||||
.property("merchant_pub", codecForString)
|
||||
.property("h_contract_terms", codecForString)
|
||||
@ -888,44 +874,34 @@ export const codecForMerchantRefundResponse = () =>
|
||||
"refund_permissions",
|
||||
makeCodecForList(codecForMerchantRefundPermission()),
|
||||
)
|
||||
.build("MerchantRefundResponse"),
|
||||
);
|
||||
.build("MerchantRefundResponse");
|
||||
|
||||
export const codecForReserveSigSingleton = () =>
|
||||
typecheckedCodec<ReserveSigSingleton>(
|
||||
export const codecForReserveSigSingleton = (): Codec<ReserveSigSingleton> =>
|
||||
makeCodecForObject<ReserveSigSingleton>()
|
||||
.property("reserve_sig", codecForString)
|
||||
.build("ReserveSigSingleton"),
|
||||
);
|
||||
.build("ReserveSigSingleton");
|
||||
|
||||
export const codecForTipResponse = () =>
|
||||
typecheckedCodec<TipResponse>(
|
||||
export const codecForTipResponse = (): Codec<TipResponse> =>
|
||||
makeCodecForObject<TipResponse>()
|
||||
.property("reserve_pub", codecForString)
|
||||
.property("reserve_sigs", makeCodecForList(codecForReserveSigSingleton()))
|
||||
.build("TipResponse"),
|
||||
);
|
||||
.build("TipResponse");
|
||||
|
||||
export const codecForRecoup = () =>
|
||||
typecheckedCodec<Recoup>(
|
||||
export const codecForRecoup = (): Codec<Recoup> =>
|
||||
makeCodecForObject<Recoup>()
|
||||
.property("h_denom_pub", codecForString)
|
||||
.build("Payback"),
|
||||
);
|
||||
.build("Recoup");
|
||||
|
||||
export const codecForExchangeSigningKey = () =>
|
||||
typecheckedCodec<ExchangeSignKeyJson>(
|
||||
export const codecForExchangeSigningKey = (): Codec<ExchangeSignKeyJson> =>
|
||||
makeCodecForObject<ExchangeSignKeyJson>()
|
||||
.property("key", codecForString)
|
||||
.property("master_sig", codecForString)
|
||||
.property("stamp_end", codecForTimestamp)
|
||||
.property("stamp_start", codecForTimestamp)
|
||||
.property("stamp_expire", codecForTimestamp)
|
||||
.build("ExchangeSignKeyJson"),
|
||||
);
|
||||
.build("ExchangeSignKeyJson");
|
||||
|
||||
export const codecForExchangeKeysJson = () =>
|
||||
typecheckedCodec<ExchangeKeysJson>(
|
||||
export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> =>
|
||||
makeCodecForObject<ExchangeKeysJson>()
|
||||
.property("denoms", makeCodecForList(codecForDenomination()))
|
||||
.property("master_public_key", codecForString)
|
||||
@ -934,49 +910,36 @@ export const codecForExchangeKeysJson = () =>
|
||||
.property("recoup", makeCodecOptional(makeCodecForList(codecForRecoup())))
|
||||
.property("signkeys", makeCodecForList(codecForExchangeSigningKey()))
|
||||
.property("version", codecForString)
|
||||
.build("KeysJson"),
|
||||
);
|
||||
.build("KeysJson");
|
||||
|
||||
export const codecForWireFeesJson = () =>
|
||||
typecheckedCodec<WireFeesJson>(
|
||||
export const codecForWireFeesJson = (): Codec<WireFeesJson> =>
|
||||
makeCodecForObject<WireFeesJson>()
|
||||
.property("wire_fee", codecForString)
|
||||
.property("closing_fee", codecForString)
|
||||
.property("sig", codecForString)
|
||||
.property("start_date", codecForTimestamp)
|
||||
.property("end_date", codecForTimestamp)
|
||||
.build("WireFeesJson"),
|
||||
);
|
||||
.build("WireFeesJson");
|
||||
|
||||
export const codecForAccountInfo = () =>
|
||||
typecheckedCodec<AccountInfo>(
|
||||
export const codecForAccountInfo = (): Codec<AccountInfo> =>
|
||||
makeCodecForObject<AccountInfo>()
|
||||
.property("payto_uri", codecForString)
|
||||
.property("master_sig", codecForString)
|
||||
.build("AccountInfo"),
|
||||
);
|
||||
.build("AccountInfo");
|
||||
|
||||
export const codecForExchangeWireJson = () =>
|
||||
typecheckedCodec<ExchangeWireJson>(
|
||||
export const codecForExchangeWireJson = (): Codec<ExchangeWireJson> =>
|
||||
makeCodecForObject<ExchangeWireJson>()
|
||||
.property("accounts", makeCodecForList(codecForAccountInfo()))
|
||||
.property(
|
||||
"fees",
|
||||
makeCodecForMap(makeCodecForList(codecForWireFeesJson())),
|
||||
)
|
||||
.build("ExchangeWireJson"),
|
||||
);
|
||||
.property("fees", makeCodecForMap(makeCodecForList(codecForWireFeesJson())))
|
||||
.build("ExchangeWireJson");
|
||||
|
||||
export const codecForProposal = () =>
|
||||
typecheckedCodec<Proposal>(
|
||||
export const codecForProposal = (): Codec<Proposal> =>
|
||||
makeCodecForObject<Proposal>()
|
||||
.property("contract_terms", codecForAny)
|
||||
.property("sig", codecForString)
|
||||
.build("Proposal"),
|
||||
);
|
||||
.build("Proposal");
|
||||
|
||||
export const codecForCheckPaymentResponse = () =>
|
||||
typecheckedCodec<CheckPaymentResponse>(
|
||||
export const codecForCheckPaymentResponse = (): Codec<CheckPaymentResponse> =>
|
||||
makeCodecForObject<CheckPaymentResponse>()
|
||||
.property("paid", codecForBoolean)
|
||||
.property("refunded", makeCodecOptional(codecForBoolean))
|
||||
@ -984,11 +947,11 @@ export const codecForCheckPaymentResponse = () =>
|
||||
.property("contract_terms", makeCodecOptional(codecForAny))
|
||||
.property("taler_pay_uri", makeCodecOptional(codecForString))
|
||||
.property("contract_url", makeCodecOptional(codecForString))
|
||||
.build("CheckPaymentResponse"),
|
||||
);
|
||||
.build("CheckPaymentResponse");
|
||||
|
||||
export const codecForWithdrawOperationStatusResponse = () =>
|
||||
typecheckedCodec<WithdrawOperationStatusResponse>(
|
||||
export const codecForWithdrawOperationStatusResponse = (): Codec<
|
||||
WithdrawOperationStatusResponse
|
||||
> =>
|
||||
makeCodecForObject<WithdrawOperationStatusResponse>()
|
||||
.property("selection_done", codecForBoolean)
|
||||
.property("transfer_done", codecForBoolean)
|
||||
@ -997,11 +960,9 @@ export const codecForWithdrawOperationStatusResponse = () =>
|
||||
.property("suggested_exchange", makeCodecOptional(codecForString))
|
||||
.property("confirm_transfer_url", makeCodecOptional(codecForString))
|
||||
.property("wire_types", makeCodecForList(codecForString))
|
||||
.build("WithdrawOperationStatusResponse"),
|
||||
);
|
||||
.build("WithdrawOperationStatusResponse");
|
||||
|
||||
export const codecForTipPickupGetResponse = () =>
|
||||
typecheckedCodec<TipPickupGetResponse>(
|
||||
export const codecForTipPickupGetResponse = (): Codec<TipPickupGetResponse> =>
|
||||
makeCodecForObject<TipPickupGetResponse>()
|
||||
.property("extra", codecForAny)
|
||||
.property("amount", codecForString)
|
||||
@ -1009,20 +970,15 @@ export const codecForTipPickupGetResponse = () =>
|
||||
.property("exchange_url", codecForString)
|
||||
.property("stamp_expire", codecForTimestamp)
|
||||
.property("stamp_created", codecForTimestamp)
|
||||
.build("TipPickupGetResponse"),
|
||||
);
|
||||
.build("TipPickupGetResponse");
|
||||
|
||||
export const codecForRecoupConfirmation = () =>
|
||||
typecheckedCodec<RecoupConfirmation>(
|
||||
export const codecForRecoupConfirmation = (): Codec<RecoupConfirmation> =>
|
||||
makeCodecForObject<RecoupConfirmation>()
|
||||
.property("reserve_pub", makeCodecOptional(codecForString))
|
||||
.property("old_coin_pub", makeCodecOptional(codecForString))
|
||||
.build("RecoupConfirmation"),
|
||||
);
|
||||
.build("RecoupConfirmation");
|
||||
|
||||
export const codecForWithdrawResponse = () =>
|
||||
typecheckedCodec<WithdrawResponse>(
|
||||
export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>
|
||||
makeCodecForObject<WithdrawResponse>()
|
||||
.property("ev_sig", codecForString)
|
||||
.build("WithdrawResponse"),
|
||||
);
|
||||
.build("WithdrawResponse");
|
||||
|
@ -30,18 +30,16 @@
|
||||
import { AmountJson, codecForAmountJson } from "../util/amounts";
|
||||
import * as LibtoolVersion from "../util/libtoolVersion";
|
||||
import {
|
||||
CoinRecord,
|
||||
DenominationRecord,
|
||||
ExchangeRecord,
|
||||
ExchangeWireInfo,
|
||||
} from "./dbTypes";
|
||||
import { CoinDepositPermission, ContractTerms } from "./talerTypes";
|
||||
import { Timestamp } from "../util/time";
|
||||
import {
|
||||
typecheckedCodec,
|
||||
makeCodecForObject,
|
||||
codecForString,
|
||||
makeCodecOptional,
|
||||
Codec,
|
||||
} from "../util/codec";
|
||||
|
||||
/**
|
||||
@ -261,16 +259,14 @@ export interface CreateReserveRequest {
|
||||
bankWithdrawStatusUrl?: string;
|
||||
}
|
||||
|
||||
export const codecForCreateReserveRequest = () =>
|
||||
typecheckedCodec<CreateReserveRequest>(
|
||||
export const codecForCreateReserveRequest = (): Codec<CreateReserveRequest> =>
|
||||
makeCodecForObject<CreateReserveRequest>()
|
||||
.property("amount", codecForAmountJson())
|
||||
.property("exchange", codecForString)
|
||||
.property("exchangeWire", codecForString)
|
||||
.property("senderWire", makeCodecOptional(codecForString))
|
||||
.property("bankWithdrawStatusUrl", makeCodecOptional(codecForString))
|
||||
.build("CreateReserveRequest"),
|
||||
);
|
||||
.build("CreateReserveRequest");
|
||||
|
||||
/**
|
||||
* Request to mark a reserve as confirmed.
|
||||
@ -283,12 +279,10 @@ export interface ConfirmReserveRequest {
|
||||
reservePub: string;
|
||||
}
|
||||
|
||||
export const codecForConfirmReserveRequest = () =>
|
||||
typecheckedCodec<ConfirmReserveRequest>(
|
||||
export const codecForConfirmReserveRequest = (): Codec<ConfirmReserveRequest> =>
|
||||
makeCodecForObject<ConfirmReserveRequest>()
|
||||
.property("reservePub", codecForString)
|
||||
.build("ConfirmReserveRequest"),
|
||||
);
|
||||
.build("ConfirmReserveRequest");
|
||||
|
||||
/**
|
||||
* Wire coins to the user's own bank account.
|
||||
|
@ -22,10 +22,10 @@
|
||||
* Imports.
|
||||
*/
|
||||
import {
|
||||
typecheckedCodec,
|
||||
makeCodecForObject,
|
||||
codecForString,
|
||||
codecForNumber,
|
||||
Codec,
|
||||
} from "./codec";
|
||||
|
||||
/**
|
||||
@ -66,14 +66,12 @@ export interface AmountJson {
|
||||
readonly currency: string;
|
||||
}
|
||||
|
||||
export const codecForAmountJson = () =>
|
||||
typecheckedCodec<AmountJson>(
|
||||
export const codecForAmountJson = (): Codec<AmountJson> =>
|
||||
makeCodecForObject<AmountJson>()
|
||||
.property("currency", codecForString)
|
||||
.property("value", codecForNumber)
|
||||
.property("fraction", codecForNumber)
|
||||
.build("AmountJson"),
|
||||
);
|
||||
.build("AmountJson");
|
||||
|
||||
/**
|
||||
* Result of a possibly overflowing operation.
|
||||
@ -100,7 +98,7 @@ export function getZero(currency: string): AmountJson {
|
||||
};
|
||||
}
|
||||
|
||||
export function sum(amounts: AmountJson[]) {
|
||||
export function sum(amounts: AmountJson[]): Result {
|
||||
if (amounts.length <= 0) {
|
||||
throw Error("can't sum zero amounts");
|
||||
}
|
||||
@ -287,7 +285,7 @@ export function parseOrThrow(s: string): AmountJson {
|
||||
* Convert a float to a Taler amount.
|
||||
* Loss of precision possible.
|
||||
*/
|
||||
export function fromFloat(floatVal: number, currency: string) {
|
||||
export function fromFloat(floatVal: number, currency: string): AmountJson {
|
||||
return {
|
||||
currency,
|
||||
fraction: Math.floor((floatVal - Math.floor(floatVal)) * fractionalBase),
|
||||
|
@ -24,7 +24,7 @@ export class AsyncOpMemoMap<T> {
|
||||
private n = 0;
|
||||
private memoMap: { [k: string]: MemoEntry<T> } = {};
|
||||
|
||||
private cleanUp(key: string, n: number) {
|
||||
private cleanUp(key: string, n: number): void {
|
||||
const r = this.memoMap[key];
|
||||
if (r && r.n === n) {
|
||||
delete this.memoMap[key];
|
||||
@ -48,7 +48,7 @@ export class AsyncOpMemoMap<T> {
|
||||
this.cleanUp(key, n);
|
||||
});
|
||||
}
|
||||
clear() {
|
||||
clear(): void {
|
||||
this.memoMap = {};
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ export class AsyncOpMemoSingle<T> {
|
||||
private n = 0;
|
||||
private memoEntry: MemoEntry<T> | undefined;
|
||||
|
||||
private cleanUp(n: number) {
|
||||
private cleanUp(n: number): void {
|
||||
if (this.memoEntry && this.memoEntry.n === n) {
|
||||
this.memoEntry = undefined;
|
||||
}
|
||||
@ -81,7 +81,7 @@ export class AsyncOpMemoSingle<T> {
|
||||
};
|
||||
return p;
|
||||
}
|
||||
clear() {
|
||||
clear(): void {
|
||||
this.memoEntry = undefined;
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +347,3 @@ export function makeCodecOptional<V>(
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function typecheckedCodec<T = undefined>(c: Codec<T>): Codec<T> {
|
||||
return c;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ export class BrowserHttpLib implements HttpRequestLibrary {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const makeJson = async () => {
|
||||
const makeJson = async (): Promise<any> => {
|
||||
let responseJson;
|
||||
try {
|
||||
responseJson = JSON.parse(myRequest.responseText);
|
||||
@ -152,15 +152,15 @@ export class BrowserHttpLib implements HttpRequestLibrary {
|
||||
});
|
||||
}
|
||||
|
||||
get(url: string, opt?: HttpRequestOptions) {
|
||||
get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
|
||||
return this.req("get", url, undefined, opt);
|
||||
}
|
||||
|
||||
postJson(url: string, body: any, opt?: HttpRequestOptions) {
|
||||
postJson(url: string, body: any, opt?: HttpRequestOptions): Promise<HttpResponse> {
|
||||
return this.req("post", url, JSON.stringify(body), opt);
|
||||
}
|
||||
|
||||
stop() {
|
||||
stop(): void {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ function writeNodeLog(
|
||||
tag: string,
|
||||
level: string,
|
||||
args: any[],
|
||||
) {
|
||||
): void {
|
||||
process.stderr.write(`${new Date().toISOString()} ${tag} ${level} `);
|
||||
process.stderr.write(message);
|
||||
if (args.length != 0) {
|
||||
@ -41,7 +41,7 @@ function writeNodeLog(
|
||||
export class Logger {
|
||||
constructor(private tag: string) {}
|
||||
|
||||
info(message: string, ...args: any[]) {
|
||||
info(message: string, ...args: any[]): void {
|
||||
if (isNode()) {
|
||||
writeNodeLog(message, this.tag, "INFO", args);
|
||||
} else {
|
||||
@ -52,7 +52,7 @@ export class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
warn(message: string, ...args: any[]) {
|
||||
warn(message: string, ...args: any[]): void {
|
||||
if (isNode()) {
|
||||
writeNodeLog(message, this.tag, "WARN", args);
|
||||
} else {
|
||||
@ -63,7 +63,7 @@ export class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
error(message: string, ...args: any[]) {
|
||||
error(message: string, ...args: any[]): void {
|
||||
if (isNode()) {
|
||||
writeNodeLog(message, this.tag, "ERROR", args);
|
||||
} else {
|
||||
@ -74,7 +74,7 @@ export class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
trace(message: any, ...args: any[]) {
|
||||
trace(message: any, ...args: any[]): void {
|
||||
if (isNode()) {
|
||||
writeNodeLog(message, this.tag, "TRACE", args);
|
||||
} else {
|
||||
|
@ -25,6 +25,11 @@
|
||||
*/
|
||||
import { openPromise } from "./promiseUtils";
|
||||
|
||||
/**
|
||||
* Exception that should be thrown by client code to abort a transaction.
|
||||
*/
|
||||
export const TransactionAbort = Symbol("transaction_abort");
|
||||
|
||||
/**
|
||||
* Definition of an object store.
|
||||
*/
|
||||
@ -430,11 +435,6 @@ export function openDatabase(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception that should be thrown by client code to abort a transaction.
|
||||
*/
|
||||
export const TransactionAbort = Symbol("transaction_abort");
|
||||
|
||||
export class Database {
|
||||
constructor(private db: IDBDatabase) {}
|
||||
|
||||
|
@ -36,7 +36,7 @@ export interface Duration {
|
||||
|
||||
let timeshift = 0;
|
||||
|
||||
export function setDangerousTimetravel(dt: number) {
|
||||
export function setDangerousTimetravel(dt: number): void {
|
||||
timeshift = dt;
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ export function timestampSubtractDuraction(
|
||||
return { t_ms: Math.max(0, t1.t_ms - d.d_ms) };
|
||||
}
|
||||
|
||||
export function stringifyTimestamp(t: Timestamp) {
|
||||
export function stringifyTimestamp(t: Timestamp): string {
|
||||
if (t.t_ms === "never") {
|
||||
return "never";
|
||||
}
|
||||
@ -142,7 +142,7 @@ export function timestampIsBetween(
|
||||
t: Timestamp,
|
||||
start: Timestamp,
|
||||
end: Timestamp,
|
||||
) {
|
||||
): boolean {
|
||||
if (timestampCmp(t, start) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
import test from "ava";
|
||||
|
||||
import * as dbTypes from "./types/dbTypes";
|
||||
import * as types from "./types/walletTypes";
|
||||
|
||||
import { AmountJson } from "./util/amounts";
|
||||
import * as Amounts from "./util/amounts";
|
||||
import { selectPayCoins, AvailableCoinInfo } from "./operations/pay";
|
||||
|
@ -47,7 +47,6 @@ import {
|
||||
CurrencyRecord,
|
||||
DenominationRecord,
|
||||
ExchangeRecord,
|
||||
ProposalRecord,
|
||||
PurchaseRecord,
|
||||
ReserveRecord,
|
||||
Stores,
|
||||
@ -155,7 +154,7 @@ export class Wallet {
|
||||
this.ws = new InternalWalletState(db, http, cryptoWorkerFactory);
|
||||
}
|
||||
|
||||
getExchangePaytoUri(exchangeBaseUrl: string, supportedTargetTypes: string[]) {
|
||||
getExchangePaytoUri(exchangeBaseUrl: string, supportedTargetTypes: string[]): Promise<string> {
|
||||
return getExchangePaytoUri(this.ws, exchangeBaseUrl, supportedTargetTypes);
|
||||
}
|
||||
|
||||
@ -371,7 +370,7 @@ export class Wallet {
|
||||
* auditors into the database, unless these defaults have
|
||||
* already been applied.
|
||||
*/
|
||||
async fillDefaults() {
|
||||
async fillDefaults(): Promise<void> {
|
||||
await this.db.runWithWriteTransaction(
|
||||
[Stores.config, Stores.currencies],
|
||||
async (tx) => {
|
||||
@ -549,7 +548,7 @@ export class Wallet {
|
||||
async acceptExchangeTermsOfService(
|
||||
exchangeBaseUrl: string,
|
||||
etag: string | undefined,
|
||||
) {
|
||||
): Promise<void> {
|
||||
return acceptExchangeTermsOfService(this.ws, exchangeBaseUrl, etag);
|
||||
}
|
||||
|
||||
@ -596,7 +595,7 @@ export class Wallet {
|
||||
/**
|
||||
* Stop ongoing processing.
|
||||
*/
|
||||
stop() {
|
||||
stop(): void {
|
||||
this.stopped = true;
|
||||
this.timerGroup.stopCurrentAndFutureTimers();
|
||||
this.ws.cryptoApi.stop();
|
||||
@ -685,7 +684,7 @@ export class Wallet {
|
||||
* Inform the wallet that the status of a reserve has changed (e.g. due to a
|
||||
* confirmation from the bank.).
|
||||
*/
|
||||
public async handleNotifyReserve() {
|
||||
public async handleNotifyReserve(): Promise<void> {
|
||||
const reserves = await this.db.iter(Stores.reserves).toArray();
|
||||
for (const r of reserves) {
|
||||
if (r.reserveStatus === ReserveRecordStatus.WAIT_CONFIRM_BANK) {
|
||||
@ -702,7 +701,7 @@ export class Wallet {
|
||||
* Remove unreferenced / expired data from the wallet's database
|
||||
* based on the current system time.
|
||||
*/
|
||||
async collectGarbage() {
|
||||
async collectGarbage(): Promise<void> {
|
||||
// FIXME(#5845)
|
||||
// We currently do not garbage-collect the wallet database. This might change
|
||||
// after the feature has been properly re-designed, and we have come up with a
|
||||
|
@ -20,7 +20,7 @@ import { isFirefox } from "./compat";
|
||||
* Polyfill for requestAnimationFrame, which
|
||||
* doesn't work from a background page.
|
||||
*/
|
||||
function rAF(cb: (ts: number) => void) {
|
||||
function rAF(cb: (ts: number) => void): void {
|
||||
window.setTimeout(() => {
|
||||
cb(performance.now());
|
||||
}, 100 /* 100 ms delay between frames */);
|
||||
@ -99,14 +99,18 @@ export class ChromeBadge {
|
||||
// size in draw() as well!
|
||||
this.canvas.width = 32;
|
||||
this.canvas.height = 32;
|
||||
this.ctx = this.canvas.getContext("2d")!;
|
||||
const ctx = this.canvas.getContext("2d");
|
||||
if (!ctx) {
|
||||
throw Error("unable to get canvas context");
|
||||
}
|
||||
this.ctx = ctx;
|
||||
this.draw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the badge based on the current state.
|
||||
*/
|
||||
private draw() {
|
||||
private draw(): void {
|
||||
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
@ -202,7 +206,7 @@ export class ChromeBadge {
|
||||
}
|
||||
}
|
||||
|
||||
private animate() {
|
||||
private animate(): void {
|
||||
if (this.animationRunning) {
|
||||
return;
|
||||
}
|
||||
@ -212,7 +216,7 @@ export class ChromeBadge {
|
||||
}
|
||||
this.animationRunning = true;
|
||||
let start: number | undefined;
|
||||
const step = (timestamp: number) => {
|
||||
const step = (timestamp: number): void => {
|
||||
if (!this.animationRunning) {
|
||||
return;
|
||||
}
|
||||
@ -257,7 +261,7 @@ export class ChromeBadge {
|
||||
* Draw the badge such that it shows the
|
||||
* user that something happened (balance changed).
|
||||
*/
|
||||
showNotification() {
|
||||
showNotification(): void {
|
||||
this.hasNotification = true;
|
||||
this.draw();
|
||||
}
|
||||
@ -265,12 +269,12 @@ export class ChromeBadge {
|
||||
/**
|
||||
* Draw the badge without the notification mark.
|
||||
*/
|
||||
clearNotification() {
|
||||
clearNotification(): void {
|
||||
this.hasNotification = false;
|
||||
this.draw();
|
||||
}
|
||||
|
||||
startBusy() {
|
||||
startBusy(): void {
|
||||
if (this.isBusy) {
|
||||
return;
|
||||
}
|
||||
@ -278,7 +282,7 @@ export class ChromeBadge {
|
||||
this.animate();
|
||||
}
|
||||
|
||||
stopBusy() {
|
||||
stopBusy(): void {
|
||||
this.isBusy = false;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ const handlers: Handler[] = [];
|
||||
|
||||
let sheet: CSSStyleSheet | null;
|
||||
|
||||
function initStyle() {
|
||||
function initStyle(): void {
|
||||
logVerbose && console.log("taking over styles");
|
||||
const name = "taler-presence-stylesheet";
|
||||
const content = "/* Taler stylesheet controlled by JS */";
|
||||
@ -78,7 +78,7 @@ function initStyle() {
|
||||
}
|
||||
}
|
||||
|
||||
function setStyles(installed: boolean) {
|
||||
function setStyles(installed: boolean): void {
|
||||
if (!sheet || !sheet.cssRules) {
|
||||
return;
|
||||
}
|
||||
@ -93,7 +93,7 @@ function setStyles(installed: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function onceOnComplete(cb: () => void) {
|
||||
function onceOnComplete(cb: () => void): void {
|
||||
if (document.readyState === "complete") {
|
||||
cb();
|
||||
} else {
|
||||
@ -105,7 +105,7 @@ function onceOnComplete(cb: () => void) {
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
function init(): void {
|
||||
onceOnComplete(() => {
|
||||
if (document.documentElement.getAttribute("data-taler-nojs")) {
|
||||
initStyle();
|
||||
@ -129,13 +129,13 @@ function init() {
|
||||
|
||||
type HandlerFn = (detail: any, sendResponse: (msg: any) => void) => void;
|
||||
|
||||
function registerHandlers() {
|
||||
function registerHandlers(): void {
|
||||
/**
|
||||
* Add a handler for a DOM event, which automatically
|
||||
* handles adding sequence numbers to responses.
|
||||
*/
|
||||
function addHandler(type: string, handler: HandlerFn) {
|
||||
const handlerWrap = (e: Event) => {
|
||||
function addHandler(type: string, handler: HandlerFn): void {
|
||||
const handlerWrap = (e: Event): void => {
|
||||
if (!(e instanceof Event)) {
|
||||
console.log("unexpected event", e);
|
||||
throw Error(`invariant violated`);
|
||||
@ -154,7 +154,7 @@ function registerHandlers() {
|
||||
callId = e.detail.callId;
|
||||
detail = e.detail;
|
||||
}
|
||||
const responder = (msg?: any) => {
|
||||
const responder = (msg?: any): void => {
|
||||
const fullMsg = Object.assign({}, msg, { callId });
|
||||
let opts = { detail: fullMsg };
|
||||
if ("function" === typeof cloneInto) {
|
||||
|
@ -31,10 +31,10 @@ interface ConfirmAuditorProps {
|
||||
expirationStamp: number;
|
||||
}
|
||||
|
||||
function ConfirmAuditor(props: ConfirmAuditorProps) {
|
||||
function ConfirmAuditor(props: ConfirmAuditorProps): JSX.Element {
|
||||
const [addDone, setAddDone] = useState(false);
|
||||
|
||||
const add = async () => {
|
||||
const add = async (): Promise<void> => {
|
||||
const currencies = await getCurrencies();
|
||||
let currency: CurrencyRecord | undefined;
|
||||
|
||||
|
@ -34,7 +34,7 @@ interface BenchmarkRunnerState {
|
||||
running: boolean;
|
||||
}
|
||||
|
||||
function BenchmarkDisplay(props: BenchmarkRunnerState) {
|
||||
function BenchmarkDisplay(props: BenchmarkRunnerState): JSX.Element {
|
||||
const result = props.result;
|
||||
if (!result) {
|
||||
if (props.running) {
|
||||
@ -55,7 +55,7 @@ function BenchmarkDisplay(props: BenchmarkRunnerState) {
|
||||
{Object.keys(result.time)
|
||||
.sort()
|
||||
.map((k) => (
|
||||
<tr>
|
||||
<tr key={k}>
|
||||
<td>{k}</td>
|
||||
<td>{result.time[k] / result.repetitions}</td>
|
||||
</tr>
|
||||
@ -75,13 +75,13 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {
|
||||
};
|
||||
}
|
||||
|
||||
async run() {
|
||||
async run(): Promise<void> {
|
||||
this.setState({ result: undefined, running: true });
|
||||
const result = await wxApi.benchmarkCrypto(this.state.repetitions);
|
||||
this.setState({ result, running: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<label>Repetitions:</label>
|
||||
@ -99,6 +99,6 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {
|
||||
}
|
||||
}
|
||||
|
||||
export function makeBenchmarkPage() {
|
||||
export function makeBenchmarkPage(): JSX.Element {
|
||||
return <BenchmarkRunner />;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import React, { useState, useEffect } from "react";
|
||||
import * as Amounts from "../../util/amounts";
|
||||
import { codecForContractTerms, ContractTerms } from "../../types/talerTypes";
|
||||
|
||||
function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
||||
function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
|
||||
const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>();
|
||||
const [payErrMsg, setPayErrMsg] = useState<string | undefined>("");
|
||||
const [numTries, setNumTries] = useState(0);
|
||||
@ -42,7 +42,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
||||
let totalFees: Amounts.AmountJson | undefined = undefined;
|
||||
|
||||
useEffect(() => {
|
||||
const doFetch = async () => {
|
||||
const doFetch = async (): Promise<void> => {
|
||||
const p = await wxApi.preparePay(talerPayUri);
|
||||
setPayStatus(p);
|
||||
};
|
||||
@ -108,7 +108,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
||||
<strong>{renderAmount(Amounts.parseOrThrow(contractTerms.amount))}</strong>
|
||||
);
|
||||
|
||||
const doPayment = async () => {
|
||||
const doPayment = async (): Promise<void> => {
|
||||
if (payStatus.status !== "payment-possible") {
|
||||
throw Error(`invalid state: ${payStatus.status}`);
|
||||
}
|
||||
@ -178,7 +178,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function makePayPage() {
|
||||
export function makePayPage(): JSX.Element {
|
||||
const url = new URL(document.location.href);
|
||||
const talerPayUri = url.searchParams.get("talerPayUri");
|
||||
if (!talerPayUri) {
|
||||
|
@ -46,7 +46,7 @@ import { Timestamp } from "../../util/time";
|
||||
|
||||
function onUpdateNotification(f: () => void): () => void {
|
||||
const port = chrome.runtime.connect({ name: "notifications" });
|
||||
const listener = () => {
|
||||
const listener = (): void => {
|
||||
f();
|
||||
};
|
||||
port.onMessage.addListener(listener);
|
||||
@ -75,7 +75,7 @@ class Router extends React.Component<any, any> {
|
||||
|
||||
private static routeHandlers: any[] = [];
|
||||
|
||||
componentWillMount() {
|
||||
componentWillMount(): void {
|
||||
console.log("router mounted");
|
||||
window.onhashchange = () => {
|
||||
this.setState({});
|
||||
@ -85,10 +85,6 @@ class Router extends React.Component<any, any> {
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
console.log("router unmounted");
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
const route = window.location.hash.substring(1);
|
||||
console.log("rendering route", route);
|
||||
@ -120,12 +116,12 @@ interface TabProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
function Tab(props: TabProps) {
|
||||
function Tab(props: TabProps): JSX.Element {
|
||||
let cssClass = "";
|
||||
if (props.target === Router.getRoute()) {
|
||||
cssClass = "active";
|
||||
}
|
||||
const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
const onClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {
|
||||
Router.setRoute(props.target);
|
||||
e.preventDefault();
|
||||
};
|
||||
@ -139,19 +135,19 @@ function Tab(props: TabProps) {
|
||||
class WalletNavBar extends React.Component<any, any> {
|
||||
private cancelSubscription: any;
|
||||
|
||||
componentWillMount() {
|
||||
componentWillMount(): void {
|
||||
this.cancelSubscription = Router.onRoute(() => {
|
||||
this.setState({});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
if (this.cancelSubscription) {
|
||||
this.cancelSubscription();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
console.log("rendering nav bar");
|
||||
return (
|
||||
<div className="nav" id="header">
|
||||
@ -163,20 +159,6 @@ class WalletNavBar extends React.Component<any, any> {
|
||||
}
|
||||
}
|
||||
|
||||
function ExtensionLink(props: any) {
|
||||
const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
chrome.tabs.create({
|
||||
url: chrome.extension.getURL(props.target),
|
||||
});
|
||||
e.preventDefault();
|
||||
};
|
||||
return (
|
||||
<a onClick={onClick} href={props.target}>
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an amount as a large number with a small currency symbol.
|
||||
*/
|
||||
@ -190,7 +172,7 @@ function bigAmount(amount: AmountJson): JSX.Element {
|
||||
);
|
||||
}
|
||||
|
||||
function EmptyBalanceView() {
|
||||
function EmptyBalanceView(): JSX.Element {
|
||||
return (
|
||||
<i18n.Translate wrap="p">
|
||||
You have no balance to show. Need some{" "}
|
||||
@ -205,12 +187,12 @@ class WalletBalanceView extends React.Component<any, any> {
|
||||
private canceler: (() => void) | undefined = undefined;
|
||||
private unmount = false;
|
||||
|
||||
componentWillMount() {
|
||||
componentWillMount(): void {
|
||||
this.canceler = onUpdateNotification(() => this.updateBalance());
|
||||
this.updateBalance();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
console.log("component WalletBalanceView will unmount");
|
||||
if (this.canceler) {
|
||||
this.canceler();
|
||||
@ -218,7 +200,7 @@ class WalletBalanceView extends React.Component<any, any> {
|
||||
this.unmount = true;
|
||||
}
|
||||
|
||||
async updateBalance() {
|
||||
async updateBalance(): Promise<void> {
|
||||
let balance: WalletBalance;
|
||||
try {
|
||||
balance = await wxApi.getBalance();
|
||||
@ -325,11 +307,11 @@ class WalletBalanceView extends React.Component<any, any> {
|
||||
}
|
||||
}
|
||||
|
||||
function Icon({ l }: { l: string }) {
|
||||
function Icon({ l }: { l: string }): JSX.Element {
|
||||
return <div className={"icon"}>{l}</div>;
|
||||
}
|
||||
|
||||
function formatAndCapitalize(text: string) {
|
||||
function formatAndCapitalize(text: string): string {
|
||||
text = text.replace("-", " ");
|
||||
text = text.replace(/^./, text[0].toUpperCase());
|
||||
return text;
|
||||
@ -357,8 +339,8 @@ function HistoryItem({
|
||||
timestamp,
|
||||
icon,
|
||||
negative = false,
|
||||
}: HistoryItemProps) {
|
||||
function formatDate(timestamp: number | "never") {
|
||||
}: HistoryItemProps): JSX.Element {
|
||||
function formatDate(timestamp: number | "never"): string | null {
|
||||
if (timestamp !== "never") {
|
||||
const itemDate = moment(timestamp);
|
||||
if (itemDate.isBetween(moment().subtract(2, "days"), moment())) {
|
||||
@ -444,7 +426,7 @@ function parseSummary(summary: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function formatHistoryItem(historyItem: HistoryEvent) {
|
||||
function formatHistoryItem(historyItem: HistoryEvent): JSX.Element {
|
||||
switch (historyItem.type) {
|
||||
case "refreshed": {
|
||||
return (
|
||||
@ -637,7 +619,7 @@ function formatHistoryItem(historyItem: HistoryEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
const HistoryComponent = (props: any) => {
|
||||
const HistoryComponent = (props: any): JSX.Element => {
|
||||
const record = props.record;
|
||||
return formatHistoryItem(record);
|
||||
};
|
||||
@ -655,18 +637,18 @@ class WalletHistory extends React.Component<any, any> {
|
||||
"exchange-added",
|
||||
];
|
||||
|
||||
componentWillMount() {
|
||||
componentWillMount(): void {
|
||||
this.update();
|
||||
this.setState({ filter: true });
|
||||
onUpdateNotification(() => this.update());
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
console.log("history component unmounted");
|
||||
this.unmounted = true;
|
||||
}
|
||||
|
||||
update() {
|
||||
update(): void {
|
||||
chrome.runtime.sendMessage({ type: "get-history" }, (resp) => {
|
||||
if (this.unmounted) {
|
||||
return;
|
||||
@ -727,7 +709,7 @@ class WalletHistory extends React.Component<any, any> {
|
||||
}
|
||||
}
|
||||
|
||||
function reload() {
|
||||
function reload(): void {
|
||||
try {
|
||||
chrome.runtime.reload();
|
||||
window.close();
|
||||
@ -736,7 +718,7 @@ function reload() {
|
||||
}
|
||||
}
|
||||
|
||||
function confirmReset() {
|
||||
function confirmReset(): void {
|
||||
if (
|
||||
confirm(
|
||||
"Do you want to IRREVOCABLY DESTROY everything inside your" +
|
||||
@ -748,7 +730,7 @@ function confirmReset() {
|
||||
}
|
||||
}
|
||||
|
||||
function WalletDebug(props: any) {
|
||||
function WalletDebug(props: any): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<p>Debug tools:</p>
|
||||
@ -791,7 +773,7 @@ function openTab(page: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function WalletPopup() {
|
||||
function WalletPopup(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<WalletNavBar />
|
||||
@ -806,7 +788,7 @@ function WalletPopup() {
|
||||
);
|
||||
}
|
||||
|
||||
export function createPopup() {
|
||||
export function createPopup(): JSX.Element {
|
||||
chrome.runtime.connect({ name: "popup" });
|
||||
return <WalletPopup />;
|
||||
}
|
@ -21,13 +21,12 @@
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import * as wxApi from "../wxApi";
|
||||
import { PurchaseDetails } from "../../types/walletTypes";
|
||||
import { AmountView } from "../renderHtml";
|
||||
|
||||
function RefundStatusView(props: { talerRefundUri: string }) {
|
||||
function RefundStatusView(props: { talerRefundUri: string }): JSX.Element {
|
||||
const [applied, setApplied] = useState(false);
|
||||
const [purchaseDetails, setPurchaseDetails] = useState<
|
||||
PurchaseDetails | undefined
|
||||
@ -35,7 +34,7 @@ function RefundStatusView(props: { talerRefundUri: string }) {
|
||||
const [errMsg, setErrMsg] = useState<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
const doFetch = async () => {
|
||||
const doFetch = async (): Promise<void> => {
|
||||
try {
|
||||
const hc = await wxApi.applyRefund(props.talerRefundUri);
|
||||
setApplied(true);
|
||||
@ -73,19 +72,17 @@ function RefundStatusView(props: { talerRefundUri: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function createRefundPage() {
|
||||
export function createRefundPage(): JSX.Element {
|
||||
const url = new URL(document.location.href);
|
||||
|
||||
const container = document.getElementById("container");
|
||||
if (!container) {
|
||||
console.error("fatal: can't mount component, container missing");
|
||||
return;
|
||||
throw Error("fatal: can't mount component, container missing")
|
||||
}
|
||||
|
||||
const talerRefundUri = url.searchParams.get("talerRefundUri");
|
||||
if (!talerRefundUri) {
|
||||
console.error("taler refund URI requred");
|
||||
return;
|
||||
throw Error("taler refund URI requred");
|
||||
}
|
||||
|
||||
return <RefundStatusView talerRefundUri={talerRefundUri} />;
|
||||
|
@ -38,7 +38,6 @@ import { getBalance, getSenderWireInfos, returnCoins } from "../wxApi";
|
||||
import { renderAmount } from "../renderHtml";
|
||||
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
|
||||
interface ReturnSelectionItemProps extends ReturnSelectionListProps {
|
||||
exchangeUrl: string;
|
||||
@ -129,7 +128,7 @@ class ReturnSelectionItem extends React.Component<
|
||||
);
|
||||
}
|
||||
|
||||
select() {
|
||||
select(): void {
|
||||
let val: number;
|
||||
let selectedWire: number;
|
||||
try {
|
||||
@ -188,7 +187,7 @@ interface ReturnConfirmationProps {
|
||||
}
|
||||
|
||||
class ReturnConfirmation extends React.Component<ReturnConfirmationProps, {}> {
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
@ -238,7 +237,7 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {
|
||||
this.state = {} as any;
|
||||
}
|
||||
|
||||
async update() {
|
||||
async update(): Promise<void> {
|
||||
const balance = await getBalance();
|
||||
const senderWireInfos = await getSenderWireInfos();
|
||||
console.log("got swi", senderWireInfos);
|
||||
@ -246,11 +245,11 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {
|
||||
this.setState({ balance, senderWireInfos });
|
||||
}
|
||||
|
||||
selectDetail(d: SelectedDetail) {
|
||||
selectDetail(d: SelectedDetail): void {
|
||||
this.setState({ selectedReturn: d });
|
||||
}
|
||||
|
||||
async confirm() {
|
||||
async confirm(): Promise<void> {
|
||||
const selectedReturn = this.state.selectedReturn;
|
||||
if (!selectedReturn) {
|
||||
return;
|
||||
@ -263,14 +262,14 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {
|
||||
});
|
||||
}
|
||||
|
||||
async cancel() {
|
||||
async cancel(): Promise<void> {
|
||||
this.setState({
|
||||
selectedReturn: undefined,
|
||||
lastConfirmedDetail: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const balance = this.state.balance;
|
||||
const senderWireInfos = this.state.senderWireInfos;
|
||||
if (!balance || !senderWireInfos) {
|
||||
@ -310,6 +309,6 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {
|
||||
}
|
||||
}
|
||||
|
||||
export function createReturnCoinsPage() {
|
||||
export function createReturnCoinsPage(): JSX.Element {
|
||||
return <ReturnCoins />;
|
||||
}
|
||||
|
@ -22,30 +22,25 @@
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
|
||||
import * as i18n from "../i18n";
|
||||
|
||||
import { acceptTip, getReserveCreationInfo, getTipStatus } from "../wxApi";
|
||||
import { acceptTip, getTipStatus } from "../wxApi";
|
||||
|
||||
import {
|
||||
WithdrawDetailView,
|
||||
renderAmount,
|
||||
ProgressButton,
|
||||
} from "../renderHtml";
|
||||
|
||||
import * as Amounts from "../../util/amounts";
|
||||
import { useState, useEffect } from "react";
|
||||
import { TipStatus } from "../../types/walletTypes";
|
||||
|
||||
function TipDisplay(props: { talerTipUri: string }) {
|
||||
function TipDisplay(props: { talerTipUri: string }): JSX.Element {
|
||||
const [tipStatus, setTipStatus] = useState<TipStatus | undefined>(undefined);
|
||||
const [discarded, setDiscarded] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [finished, setFinished] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const doFetch = async () => {
|
||||
const doFetch = async (): Promise<void> => {
|
||||
const ts = await getTipStatus(props.talerTipUri);
|
||||
setTipStatus(ts);
|
||||
};
|
||||
@ -53,7 +48,7 @@ function TipDisplay(props: { talerTipUri: string }) {
|
||||
}, []);
|
||||
|
||||
if (discarded) {
|
||||
return <span>You've discarded the tip.</span>;
|
||||
return <span>You've discarded the tip.</span>;
|
||||
}
|
||||
|
||||
if (finished) {
|
||||
@ -64,11 +59,11 @@ function TipDisplay(props: { talerTipUri: string }) {
|
||||
return <span>Loading ...</span>;
|
||||
}
|
||||
|
||||
const discard = () => {
|
||||
const discard = (): void => {
|
||||
setDiscarded(true);
|
||||
};
|
||||
|
||||
const accept = async () => {
|
||||
const accept = async (): Promise<void> => {
|
||||
setLoading(true);
|
||||
await acceptTip(tipStatus.tipId);
|
||||
setFinished(true);
|
||||
@ -100,7 +95,7 @@ function TipDisplay(props: { talerTipUri: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function createTipPage() {
|
||||
export function createTipPage(): JSX.Element {
|
||||
const url = new URL(document.location.href);
|
||||
const talerTipUri = url.searchParams.get("talerTipUri");
|
||||
if (typeof talerTipUri !== "string") {
|
||||
|
@ -25,7 +25,7 @@ import { getDiagnostics } from "../wxApi";
|
||||
import { PageLink } from "../renderHtml";
|
||||
import { WalletDiagnostics } from "../../types/walletTypes";
|
||||
|
||||
function Diagnostics() {
|
||||
function Diagnostics(): JSX.Element {
|
||||
const [timedOut, setTimedOut] = useState(false);
|
||||
const [diagnostics, setDiagnostics] = useState<WalletDiagnostics | undefined>(
|
||||
undefined,
|
||||
@ -39,7 +39,7 @@ function Diagnostics() {
|
||||
setTimedOut(true);
|
||||
}
|
||||
}, 1000);
|
||||
const doFetch = async () => {
|
||||
const doFetch = async (): Promise<void> => {
|
||||
const d = await getDiagnostics();
|
||||
console.log("got diagnostics", d);
|
||||
gotDiagnostics = true;
|
||||
@ -95,7 +95,7 @@ function Diagnostics() {
|
||||
return <p>Running diagnostics ...</p>;
|
||||
}
|
||||
|
||||
function Welcome() {
|
||||
function Welcome(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<p>Thank you for installing the wallet.</p>
|
||||
@ -110,6 +110,6 @@ function Welcome() {
|
||||
);
|
||||
}
|
||||
|
||||
export function createWelcomePage() {
|
||||
export function createWelcomePage(): JSX.Element {
|
||||
return <Welcome />;
|
||||
}
|
@ -28,10 +28,9 @@ import { WithdrawDetails } from "../../types/walletTypes";
|
||||
import { WithdrawDetailView, renderAmount } from "../renderHtml";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { getWithdrawDetails, acceptWithdrawal } from "../wxApi";
|
||||
|
||||
function NewExchangeSelection(props: { talerWithdrawUri: string }) {
|
||||
function NewExchangeSelection(props: { talerWithdrawUri: string }): JSX.Element {
|
||||
const [details, setDetails] = useState<WithdrawDetails | undefined>();
|
||||
const [selectedExchange, setSelectedExchange] = useState<
|
||||
string | undefined
|
||||
@ -43,7 +42,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {
|
||||
const [errMsg, setErrMsg] = useState<string | undefined>("");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const fetchData = async (): Promise<void> => {
|
||||
console.log("getting from", talerWithdrawUri);
|
||||
let d: WithdrawDetails | undefined = undefined;
|
||||
try {
|
||||
@ -145,7 +144,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
const accept = async () => {
|
||||
const accept = async (): Promise<void> => {
|
||||
console.log("accepting exchange", selectedExchange);
|
||||
const res = await acceptWithdrawal(talerWithdrawUri, selectedExchange!);
|
||||
console.log("accept withdrawal response", res);
|
||||
@ -197,27 +196,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const url = new URL(document.location.href);
|
||||
const talerWithdrawUri = url.searchParams.get("talerWithdrawUri");
|
||||
if (!talerWithdrawUri) {
|
||||
throw Error("withdraw URI required");
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<NewExchangeSelection talerWithdrawUri={talerWithdrawUri} />,
|
||||
document.getElementById("exchange-selection")!,
|
||||
);
|
||||
} catch (e) {
|
||||
// TODO: provide more context information, maybe factor it out into a
|
||||
// TODO:generic error reporting function or component.
|
||||
document.body.innerText = i18n.str`Fatal error: "${e.message}".`;
|
||||
console.error("got error", e);
|
||||
}
|
||||
}
|
||||
|
||||
export function createWithdrawPage() {
|
||||
export function createWithdrawPage(): JSX.Element {
|
||||
const url = new URL(document.location.href);
|
||||
const talerWithdrawUri = url.searchParams.get("talerWithdrawUri");
|
||||
if (!talerWithdrawUri) {
|
||||
|
@ -29,14 +29,13 @@ import { DenominationRecord } from "../types/dbTypes";
|
||||
import { ExchangeWithdrawDetails } from "../types/walletTypes";
|
||||
import * as i18n from "./i18n";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { stringifyTimestamp } from "../util/time";
|
||||
|
||||
/**
|
||||
* Render amount as HTML, which non-breaking space between
|
||||
* decimal value and currency.
|
||||
*/
|
||||
export function renderAmount(amount: AmountJson | string) {
|
||||
export function renderAmount(amount: AmountJson | string): JSX.Element {
|
||||
let a;
|
||||
if (typeof amount === "string") {
|
||||
a = Amounts.parse(amount);
|
||||
@ -54,14 +53,17 @@ export function renderAmount(amount: AmountJson | string) {
|
||||
);
|
||||
}
|
||||
|
||||
export const AmountView = ({ amount }: { amount: AmountJson | string }) =>
|
||||
renderAmount(amount);
|
||||
export const AmountView = ({
|
||||
amount,
|
||||
}: {
|
||||
amount: AmountJson | string;
|
||||
}): JSX.Element => renderAmount(amount);
|
||||
|
||||
/**
|
||||
* Abbreviate a string to a given length, and show the full
|
||||
* string on hover as a tooltip.
|
||||
*/
|
||||
export function abbrev(s: string, n = 5) {
|
||||
export function abbrev(s: string, n = 5): JSX.Element {
|
||||
let sAbbrev = s;
|
||||
if (s.length > n) {
|
||||
sAbbrev = s.slice(0, n) + "..";
|
||||
@ -94,12 +96,12 @@ export class Collapsible extends React.Component<
|
||||
super(props);
|
||||
this.state = { collapsed: props.initiallyCollapsed };
|
||||
}
|
||||
render() {
|
||||
const doOpen = (e: any) => {
|
||||
render(): JSX.Element {
|
||||
const doOpen = (e: any): void => {
|
||||
this.setState({ collapsed: false });
|
||||
e.preventDefault();
|
||||
};
|
||||
const doClose = (e: any) => {
|
||||
const doClose = (e: any): void => {
|
||||
this.setState({ collapsed: true });
|
||||
e.preventDefault();
|
||||
};
|
||||
@ -188,7 +190,7 @@ function FeeDetailsView(props: {
|
||||
countByPub[x.denomPub] = c;
|
||||
});
|
||||
|
||||
function row(denom: DenominationRecord) {
|
||||
function row(denom: DenominationRecord): JSX.Element {
|
||||
return (
|
||||
<tr>
|
||||
<td>{countByPub[denom.denomPub] + "x"}</td>
|
||||
@ -296,7 +298,7 @@ interface ExpanderTextProps {
|
||||
/**
|
||||
* Show a heading with a toggle to show/hide the expandable content.
|
||||
*/
|
||||
export function ExpanderText({ text }: ExpanderTextProps) {
|
||||
export function ExpanderText({ text }: ExpanderTextProps): JSX.Element {
|
||||
return <span>{text}</span>;
|
||||
}
|
||||
|
||||
@ -310,7 +312,7 @@ export function ProgressButton(
|
||||
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
HTMLButtonElement
|
||||
>,
|
||||
) {
|
||||
): JSX.Element {
|
||||
return (
|
||||
<button
|
||||
className="pure-button pure-button-primary"
|
||||
@ -330,7 +332,9 @@ export function ProgressButton(
|
||||
);
|
||||
}
|
||||
|
||||
export function PageLink(props: React.PropsWithChildren<{ pageName: string }>) {
|
||||
export function PageLink(
|
||||
props: React.PropsWithChildren<{ pageName: string }>,
|
||||
): JSX.Element {
|
||||
const url = chrome.extension.getURL(`/src/webex/pages/${props.pageName}`);
|
||||
return (
|
||||
<a className="actionLink" href={url} target="_blank">
|
||||
|
@ -38,6 +38,9 @@ import {
|
||||
WalletBalance,
|
||||
PurchaseDetails,
|
||||
WalletDiagnostics,
|
||||
WithdrawDetails,
|
||||
PreparePayResult,
|
||||
AcceptWithdrawalResponse,
|
||||
} from "../types/walletTypes";
|
||||
|
||||
import { MessageMap, MessageType } from "./messages";
|
||||
@ -271,7 +274,7 @@ export function applyRefund(refundUrl: string): Promise<string> {
|
||||
/**
|
||||
* Abort a failed payment and try to get a refund.
|
||||
*/
|
||||
export function abortFailedPayment(contractTermsHash: string) {
|
||||
export function abortFailedPayment(contractTermsHash: string): Promise<void> {
|
||||
return callBackend("abort-failed-payment", { contractTermsHash });
|
||||
}
|
||||
|
||||
@ -288,7 +291,7 @@ export function benchmarkCrypto(repetitions: number): Promise<BenchmarkResult> {
|
||||
export function getWithdrawDetails(
|
||||
talerWithdrawUri: string,
|
||||
maybeSelectedExchange: string | undefined,
|
||||
) {
|
||||
): Promise<WithdrawDetails> {
|
||||
return callBackend("get-withdraw-details", {
|
||||
talerWithdrawUri,
|
||||
maybeSelectedExchange,
|
||||
@ -298,7 +301,7 @@ export function getWithdrawDetails(
|
||||
/**
|
||||
* Get details about a pay operation.
|
||||
*/
|
||||
export function preparePay(talerPayUri: string) {
|
||||
export function preparePay(talerPayUri: string): Promise<PreparePayResult> {
|
||||
return callBackend("prepare-pay", { talerPayUri });
|
||||
}
|
||||
|
||||
@ -308,7 +311,7 @@ export function preparePay(talerPayUri: string) {
|
||||
export function acceptWithdrawal(
|
||||
talerWithdrawUri: string,
|
||||
selectedExchange: string,
|
||||
) {
|
||||
): Promise<AcceptWithdrawalResponse> {
|
||||
return callBackend("accept-withdrawal", {
|
||||
talerWithdrawUri,
|
||||
selectedExchange,
|
||||
|
@ -40,7 +40,6 @@ import { BrowserHttpLib } from "../util/http";
|
||||
import { OpenedPromise, openPromise } from "../util/promiseUtils";
|
||||
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
|
||||
import { Wallet } from "../wallet";
|
||||
import { ChromeBadge } from "./chromeBadge";
|
||||
import { isFirefox } from "./compat";
|
||||
import { MessageType } from "./messages";
|
||||
import * as wxApi from "./wxApi";
|
||||
@ -49,6 +48,21 @@ import { Database } from "../util/query";
|
||||
|
||||
const NeedsWallet = Symbol("NeedsWallet");
|
||||
|
||||
/**
|
||||
* Currently active wallet instance. Might be unloaded and
|
||||
* re-instantiated when the database is reset.
|
||||
*/
|
||||
let currentWallet: Wallet | undefined;
|
||||
|
||||
let currentDatabase: IDBDatabase | undefined;
|
||||
|
||||
/**
|
||||
* Last version if an outdated DB, if applicable.
|
||||
*/
|
||||
let outdatedDbVersion: number | undefined;
|
||||
|
||||
const walletInit: OpenedPromise<void> = openPromise<void>();
|
||||
|
||||
async function handleMessage(
|
||||
sender: MessageSender,
|
||||
type: MessageType,
|
||||
@ -57,14 +71,12 @@ async function handleMessage(
|
||||
function assertNotFound(t: never): never {
|
||||
console.error(`Request type ${t as string} unknown`);
|
||||
console.error(`Request detail was ${detail}`);
|
||||
return (
|
||||
{
|
||||
return {
|
||||
error: {
|
||||
message: `request type ${t as string} unknown`,
|
||||
requestType: type,
|
||||
},
|
||||
} as never
|
||||
);
|
||||
} as never;
|
||||
}
|
||||
function needsWallet(): Wallet {
|
||||
if (!currentWallet) {
|
||||
@ -320,7 +332,7 @@ function getTab(tabId: number): Promise<chrome.tabs.Tab> {
|
||||
});
|
||||
}
|
||||
|
||||
function setBadgeText(options: chrome.browserAction.BadgeTextDetails) {
|
||||
function setBadgeText(options: chrome.browserAction.BadgeTextDetails): void {
|
||||
// not supported by all browsers ...
|
||||
if (chrome && chrome.browserAction && chrome.browserAction.setBadgeText) {
|
||||
chrome.browserAction.setBadgeText(options);
|
||||
@ -331,9 +343,12 @@ function setBadgeText(options: chrome.browserAction.BadgeTextDetails) {
|
||||
|
||||
function waitMs(timeoutMs: number): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.extension
|
||||
.getBackgroundPage()!
|
||||
.setTimeout(() => resolve(), timeoutMs);
|
||||
const bgPage = chrome.extension.getBackgroundPage();
|
||||
if (!bgPage) {
|
||||
reject("fatal: no background page");
|
||||
return;
|
||||
}
|
||||
bgPage.setTimeout(() => resolve(), timeoutMs);
|
||||
});
|
||||
}
|
||||
|
||||
@ -359,7 +374,7 @@ function makeSyncWalletRedirect(
|
||||
if (isFirefox()) {
|
||||
// Some platforms don't support the sync redirect (yet), so fall back to
|
||||
// async redirect after a timeout.
|
||||
const doit = async () => {
|
||||
const doit = async (): Promise<void> => {
|
||||
await waitMs(150);
|
||||
const tab = await getTab(tabId);
|
||||
if (tab.url === oldUrl) {
|
||||
@ -371,29 +386,13 @@ function makeSyncWalletRedirect(
|
||||
return { redirectUrl: outerUrl.href };
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently active wallet instance. Might be unloaded and
|
||||
* re-instantiated when the database is reset.
|
||||
*/
|
||||
let currentWallet: Wallet | undefined;
|
||||
|
||||
let currentDatabase: IDBDatabase | undefined;
|
||||
|
||||
/**
|
||||
* Last version if an outdated DB, if applicable.
|
||||
*/
|
||||
let outdatedDbVersion: number | undefined;
|
||||
|
||||
const walletInit: OpenedPromise<void> = openPromise<void>();
|
||||
|
||||
async function reinitWallet() {
|
||||
async function reinitWallet(): Promise<void> {
|
||||
if (currentWallet) {
|
||||
currentWallet.stop();
|
||||
currentWallet = undefined;
|
||||
}
|
||||
currentDatabase = undefined;
|
||||
setBadgeText({ text: "" });
|
||||
const badge = new ChromeBadge();
|
||||
try {
|
||||
currentDatabase = await openTalerDatabase(indexedDB, reinitWallet);
|
||||
} catch (e) {
|
||||
@ -461,7 +460,7 @@ try {
|
||||
*
|
||||
* Sets up all event handlers and other machinery.
|
||||
*/
|
||||
export async function wxMain() {
|
||||
export async function wxMain(): Promise<void> {
|
||||
// Explicitly unload the extension page as soon as an update is available,
|
||||
// so the update gets installed as soon as possible.
|
||||
chrome.runtime.onUpdateAvailable.addListener((details) => {
|
||||
@ -505,8 +504,13 @@ export async function wxMain() {
|
||||
|
||||
chrome.tabs.onRemoved.addListener((tabId, changeInfo) => {
|
||||
const tt = tabTimers[tabId] || [];
|
||||
const bgPage = chrome.extension.getBackgroundPage();
|
||||
if (!bgPage) {
|
||||
console.error("background page unavailable");
|
||||
return;
|
||||
}
|
||||
for (const t of tt) {
|
||||
chrome.extension.getBackgroundPage()!.clearTimeout(t);
|
||||
bgPage.clearTimeout(t);
|
||||
}
|
||||
});
|
||||
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
|
||||
@ -515,12 +519,7 @@ export async function wxMain() {
|
||||
}
|
||||
const timers: number[] = [];
|
||||
|
||||
const addRun = (dt: number) => {
|
||||
const id = chrome.extension.getBackgroundPage()!.setTimeout(run, dt);
|
||||
timers.push(id);
|
||||
};
|
||||
|
||||
const run = () => {
|
||||
const run = (): void => {
|
||||
timers.shift();
|
||||
chrome.tabs.get(tabId, (tab) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
@ -538,10 +537,20 @@ export async function wxMain() {
|
||||
document.dispatchEvent(new Event("taler-probe-result"));
|
||||
}
|
||||
`;
|
||||
injectScript(tab.id!, { code, runAt: "document_start" }, uri.href);
|
||||
injectScript(tab.id, { code, runAt: "document_start" }, uri.href);
|
||||
});
|
||||
};
|
||||
|
||||
const addRun = (dt: number): void => {
|
||||
const bgPage = chrome.extension.getBackgroundPage();
|
||||
if (!bgPage) {
|
||||
console.error("no background page");
|
||||
return;
|
||||
}
|
||||
const id = bgPage.setTimeout(run, dt);
|
||||
timers.push(id);
|
||||
};
|
||||
|
||||
addRun(0);
|
||||
addRun(50);
|
||||
addRun(300);
|
||||
|
Loading…
Reference in New Issue
Block a user