From 6415564b9259a4a6a2f6ec9cb934eab3d56a1677 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 9 Dec 2019 19:59:08 +0100 Subject: tos --- src/android/index.ts | 54 ++++++++++++++++++++++++------- src/dbTypes.ts | 23 +++++++++++++- src/headless/helpers.ts | 7 +++- src/headless/taler-wallet-cli.ts | 4 +-- src/util/http.ts | 31 ++++++++++++++++-- src/wallet-impl/exchanges.ts | 69 ++++++++++++++++++++++++++++++++++++---- src/wallet-impl/tip.ts | 4 +-- src/wallet-impl/withdraw.ts | 37 +++++++++++++-------- src/wallet.ts | 51 +++++++++++++++++------------ src/walletTypes.ts | 13 +++++--- src/webex/messages.ts | 2 +- src/webex/pages/withdraw.tsx | 12 +++---- src/webex/renderHtml.tsx | 8 ++--- src/webex/wxApi.ts | 4 +-- 14 files changed, 241 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/android/index.ts b/src/android/index.ts index ec5853543..6d7f92cdb 100644 --- a/src/android/index.ts +++ b/src/android/index.ts @@ -26,12 +26,20 @@ import { } from "../headless/helpers"; import { openPromise, OpenedPromise } from "../util/promiseUtils"; import fs = require("fs"); -import { HttpRequestLibrary, HttpResponse, HttpRequestOptions } from "../util/http"; +import { + HttpRequestLibrary, + HttpResponse, + HttpRequestOptions, + Headers, +} from "../util/http"; // @ts-ignore: special built-in module //import akono = require("akono"); -export { handleWorkerError, handleWorkerMessage } from "../crypto/workers/nodeThreadWorker"; +export { + handleWorkerError, + handleWorkerMessage, +} from "../crypto/workers/nodeThreadWorker"; export class AndroidHttpLib implements HttpRequestLibrary { useNfcTunnel: boolean = false; @@ -66,7 +74,11 @@ export class AndroidHttpLib implements HttpRequestLibrary { } } - postJson(url: string, body: any, opt?: HttpRequestOptions): Promise { + postJson( + url: string, + body: any, + opt?: HttpRequestOptions, + ): Promise { if (this.useNfcTunnel) { const myId = this.requestId++; const p = openPromise(); @@ -89,11 +101,14 @@ export class AndroidHttpLib implements HttpRequestLibrary { const myId = msg.id; const p = this.requestMap[myId]; if (!p) { - console.error(`no matching request for tunneled HTTP response, id=${myId}`); + console.error( + `no matching request for tunneled HTTP response, id=${myId}`, + ); } + const headers = new Headers(); if (msg.status != 0) { const resp: HttpResponse = { - headers: {}, + headers, status: msg.status, json: async () => JSON.parse(msg.responseText), text: async () => msg.responseText, @@ -146,7 +161,7 @@ export function installAndroidWalletListener() { }; const w = await getDefaultNodeWallet(walletArgs); maybeWallet = w; - w.runRetryLoop().catch((e) => { + w.runRetryLoop().catch(e => { console.error("Error during wallet retry loop", e); }); wp.resolve(w); @@ -191,7 +206,10 @@ export function installAndroidWalletListener() { } case "confirmPay": { const wallet = await wp.promise; - result = await wallet.confirmPay(msg.args.proposalId, msg.args.sessionId); + result = await wallet.confirmPay( + msg.args.proposalId, + msg.args.sessionId, + ); break; } case "startTunnel": { @@ -206,14 +224,28 @@ export function installAndroidWalletListener() { httpLib.handleTunnelResponse(msg.args); break; } - case "getWithdrawalInfo": { + case "getWithdrawDetailsForUri": { + const wallet = await wp.promise; + result = await wallet.getWithdrawDetailsForUri( + msg.args.talerWithdrawUri, + msg.args.selectedExchange, + ); + break; + } + case "acceptExchangeTermsOfService": { const wallet = await wp.promise; - result = await wallet.getWithdrawalInfo(msg.args.talerWithdrawUri); + result = await wallet.acceptExchangeTermsOfService( + msg.args.exchangeBaseUrl, + msg.args.etag, + ); break; } case "acceptWithdrawal": { const wallet = await wp.promise; - result = await wallet.acceptWithdrawal(msg.args.talerWithdrawUri, msg.args.selectedExchange); + result = await wallet.acceptWithdrawal( + msg.args.talerWithdrawUri, + msg.args.selectedExchange, + ); break; } case "reset": { @@ -234,7 +266,7 @@ export function installAndroidWalletListener() { maybeWallet = undefined; const w = await getDefaultNodeWallet(walletArgs); maybeWallet = w; - w.runRetryLoop().catch((e) => { + w.runRetryLoop().catch(e => { console.error("Error during wallet retry loop", e); }); wp.resolve(w); diff --git a/src/dbTypes.ts b/src/dbTypes.ts index 3ffade4e3..e0abf1362 100644 --- a/src/dbTypes.ts +++ b/src/dbTypes.ts @@ -455,9 +455,10 @@ export interface ExchangeDetails { lastUpdateTime: Timestamp; } -export enum ExchangeUpdateStatus { +export const enum ExchangeUpdateStatus { FETCH_KEYS = "fetch_keys", FETCH_WIRE = "fetch_wire", + FETCH_TERMS = "fetch_terms", FINISHED = "finished", } @@ -494,6 +495,26 @@ export interface ExchangeRecord { */ timestampAdded: Timestamp; + /** + * Terms of service text or undefined if not downloaded yet. + */ + termsOfServiceText: string | undefined; + + /** + * ETag for last terms of service download. + */ + termsOfServiceLastEtag: string | undefined; + + /** + * ETag for last terms of service download. + */ + termsOfServiceAcceptedEtag: string | undefined; + + /** + * ETag for last terms of service download. + */ + termsOfServiceAcceptedTimestamp: Timestamp | undefined; + /** * Time when the update to the exchange has been started or * undefined if no update is in progress. diff --git a/src/headless/helpers.ts b/src/headless/helpers.ts index 7a9cd2ca7..791bd6ab5 100644 --- a/src/headless/helpers.ts +++ b/src/headless/helpers.ts @@ -28,6 +28,7 @@ import Axios, { AxiosPromise, AxiosResponse } from "axios"; import { HttpRequestLibrary, HttpRequestOptions, + Headers, } from "../util/http"; import * as amounts from "../util/amounts"; import { Bank } from "./bank"; @@ -83,8 +84,12 @@ export class NodeHttpLib implements HttpRequestLibrary { } return responseJson; }; + const headers = new Headers(); + for (const hn of Object.keys(resp.headers)) { + headers.set(hn, resp.headers[hn]); + } return { - headers: resp.headers, + headers, status: resp.status, text: async () => resp.data, json: makeJson, diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts index 4cec984d5..d2ace124d 100644 --- a/src/headless/taler-wallet-cli.ts +++ b/src/headless/taler-wallet-cli.ts @@ -230,8 +230,8 @@ walletCli break; case TalerUriType.TalerWithdraw: { - const withdrawInfo = await wallet.getWithdrawalInfo(uri); - const selectedExchange = withdrawInfo.suggestedExchange; + const withdrawInfo = await wallet.getWithdrawDetailsForUri(uri); + const selectedExchange = withdrawInfo.bankWithdrawDetails.suggestedExchange; if (!selectedExchange) { console.error("no suggested exchange!"); process.exit(1); diff --git a/src/util/http.ts b/src/util/http.ts index ab253b232..79039f516 100644 --- a/src/util/http.ts +++ b/src/util/http.ts @@ -24,7 +24,7 @@ */ export interface HttpResponse { status: number; - headers: { [name: string]: string }; + headers: Headers; json(): Promise; text(): Promise; } @@ -33,6 +33,31 @@ export interface HttpRequestOptions { headers?: { [name: string]: string }; } +/** + * Headers, roughly modeled after the fetch API's headers object. + */ +export class Headers { + private headerMap = new Map(); + + get(name: string): string | null { + const r = this.headerMap.get(name.toLowerCase()); + if (r) { + return r; + } + return null; + } + + set(name: string, value: string): void { + const normalizedName = name.toLowerCase(); + const existing = this.headerMap.get(normalizedName); + if (existing !== undefined) { + this.headerMap.set(normalizedName, existing + "," + value); + } else { + this.headerMap.set(normalizedName, value); + } + } +} + /** * The request library is bundled into an interface to m responseJson: object & any;ake mocking easy. */ @@ -103,12 +128,12 @@ export class BrowserHttpLib implements HttpRequestLibrary { const arr = headers.trim().split(/[\r\n]+/); // Create a map of header names to values - const headerMap: { [name: string]: string } = {}; + const headerMap = new Headers(); arr.forEach(function(line) { const parts = line.split(": "); const header = parts.shift(); const value = parts.join(": "); - headerMap[header!] = value; + headerMap.set(header!, value); }); const resp: HttpResponse = { status: myRequest.status, diff --git a/src/wallet-impl/exchanges.ts b/src/wallet-impl/exchanges.ts index 9810b9b91..1e5f86b4f 100644 --- a/src/wallet-impl/exchanges.ts +++ b/src/wallet-impl/exchanges.ts @@ -16,11 +16,7 @@ import { InternalWalletState } from "./state"; import { WALLET_CACHE_BREAKER_CLIENT_VERSION } from "../wallet"; -import { - KeysJson, - Denomination, - ExchangeWireJson, -} from "../talerTypes"; +import { KeysJson, Denomination, ExchangeWireJson } from "../talerTypes"; import { getTimestampNow, OperationError } from "../walletTypes"; import { ExchangeRecord, @@ -222,6 +218,62 @@ async function updateExchangeWithKeys( ); } +async function updateExchangeWithTermsOfService( + ws: InternalWalletState, + exchangeBaseUrl: string, +) { + const exchange = await oneShotGet(ws.db, Stores.exchanges, exchangeBaseUrl); + if (!exchange) { + return; + } + if (exchange.updateStatus != ExchangeUpdateStatus.FETCH_TERMS) { + return; + } + const reqUrl = new URL("terms", exchangeBaseUrl); + reqUrl.searchParams.set("cacheBreaker", WALLET_CACHE_BREAKER_CLIENT_VERSION); + const headers = { + Accept: "text/plain", + }; + + const resp = await ws.http.get(reqUrl.href, { headers }); + if (resp.status !== 200) { + throw Error(`/terms response has unexpected status code (${resp.status})`); + } + + const tosText = await resp.text(); + const tosEtag = resp.headers.get("etag") || undefined; + + await runWithWriteTransaction(ws.db, [Stores.exchanges], async tx => { + const r = await tx.get(Stores.exchanges, exchangeBaseUrl); + if (!r) { + return; + } + if (r.updateStatus != ExchangeUpdateStatus.FETCH_TERMS) { + return; + } + r.termsOfServiceText = tosText; + r.termsOfServiceLastEtag = tosEtag; + r.updateStatus = ExchangeUpdateStatus.FINISHED; + await tx.put(Stores.exchanges, r); + }); +} + +export async function acceptExchangeTermsOfService( + ws: InternalWalletState, + exchangeBaseUrl: string, + etag: string | undefined, +) { + await runWithWriteTransaction(ws.db, [Stores.exchanges], async tx => { + const r = await tx.get(Stores.exchanges, exchangeBaseUrl); + if (!r) { + return; + } + r.termsOfServiceAcceptedEtag = etag; + r.termsOfServiceAcceptedTimestamp = getTimestampNow(); + await tx.put(Stores.exchanges, r); + }); +} + /** * Fetch wire information for an exchange and store it in the database. * @@ -309,7 +361,7 @@ async function updateExchangeWithWireInfo( accounts: wireInfo.accounts, feesForType: feesForType, }; - r.updateStatus = ExchangeUpdateStatus.FINISHED; + r.updateStatus = ExchangeUpdateStatus.FETCH_TERMS; r.lastError = undefined; await tx.put(Stores.exchanges, r); }); @@ -350,6 +402,10 @@ async function updateExchangeFromUrlImpl( updateStarted: now, updateReason: "initial", timestampAdded: getTimestampNow(), + termsOfServiceAcceptedEtag: undefined, + termsOfServiceAcceptedTimestamp: undefined, + termsOfServiceLastEtag: undefined, + termsOfServiceText: undefined, }; await oneShotPut(ws.db, Stores.exchanges, newExchangeRecord); } else { @@ -373,6 +429,7 @@ async function updateExchangeFromUrlImpl( await updateExchangeWithKeys(ws, baseUrl); await updateExchangeWithWireInfo(ws, baseUrl); + await updateExchangeWithTermsOfService(ws, baseUrl); const updatedExchange = await oneShotGet(ws.db, Stores.exchanges, baseUrl); diff --git a/src/wallet-impl/tip.ts b/src/wallet-impl/tip.ts index 41463ab18..22ec37793 100644 --- a/src/wallet-impl/tip.ts +++ b/src/wallet-impl/tip.ts @@ -22,7 +22,7 @@ import { TipStatus, getTimestampNow, OperationError, NotificationType } from ".. import { TipPickupGetResponse, TipPlanchetDetail, TipResponse } from "../talerTypes"; import * as Amounts from "../util/amounts"; import { Stores, PlanchetRecord, WithdrawalSessionRecord, initRetryInfo, updateRetryInfoTimeout } from "../dbTypes"; -import { getWithdrawDetailsForAmount, getVerifiedWithdrawDenomList, processWithdrawSession } from "./withdraw"; +import { getExchangeWithdrawalInfo, getVerifiedWithdrawDenomList, processWithdrawSession } from "./withdraw"; import { getTalerStampSec, extractTalerStampOrThrow } from "../util/helpers"; import { updateExchangeFromUrl } from "./exchanges"; import { getRandomBytes, encodeCrock } from "../crypto/talerCrypto"; @@ -58,7 +58,7 @@ export async function getTipStatus( ]); if (!tipRecord) { - const withdrawDetails = await getWithdrawDetailsForAmount( + const withdrawDetails = await getExchangeWithdrawalInfo( ws, tipPickupStatus.exchange_url, amount, diff --git a/src/wallet-impl/withdraw.ts b/src/wallet-impl/withdraw.ts index cd3989972..d8b2b599c 100644 --- a/src/wallet-impl/withdraw.ts +++ b/src/wallet-impl/withdraw.ts @@ -29,8 +29,8 @@ import * as Amounts from "../util/amounts"; import { getTimestampNow, AcceptWithdrawalResponse, - DownloadedWithdrawInfo, - ReserveCreationInfo, + BankWithdrawDetails, + ExchangeWithdrawDetails, WithdrawDetails, OperationError, NotificationType, @@ -106,12 +106,12 @@ export function getWithdrawDenomList( /** * Get information about a withdrawal from - * a taler://withdraw URI. + * a taler://withdraw URI by asking the bank. */ -export async function getWithdrawalInfo( +async function getBankWithdrawalInfo( ws: InternalWalletState, talerWithdrawUri: string, -): Promise { +): Promise { const uriResult = parseWithdrawUri(talerWithdrawUri); if (!uriResult) { throw Error("can't parse URL"); @@ -140,7 +140,7 @@ export async function acceptWithdrawal( talerWithdrawUri: string, selectedExchange: string, ): Promise { - const withdrawInfo = await getWithdrawalInfo(ws, talerWithdrawUri); + const withdrawInfo = await getBankWithdrawalInfo(ws, talerWithdrawUri); const exchangeWire = await getExchangePaytoUri( ws, selectedExchange, @@ -572,11 +572,11 @@ async function processWithdrawSessionImpl( return; } -export async function getWithdrawDetailsForAmount( +export async function getExchangeWithdrawalInfo( ws: InternalWalletState, baseUrl: string, amount: AmountJson, -): Promise { +): Promise { const exchangeInfo = await updateExchangeFromUrl(ws, baseUrl); const exchangeDetails = exchangeInfo.details; if (!exchangeDetails) { @@ -650,7 +650,15 @@ export async function getWithdrawDetailsForAmount( } } - const ret: ReserveCreationInfo = { + let tosAccepted = false; + + if (exchangeInfo.termsOfServiceAcceptedTimestamp) { + if (exchangeInfo.termsOfServiceAcceptedEtag == exchangeInfo.termsOfServiceLastEtag) { + tosAccepted = true; + } + } + + const ret: ExchangeWithdrawDetails = { earliestDepositExpiration, exchangeInfo, exchangeWireAccounts, @@ -665,6 +673,7 @@ export async function getWithdrawDetailsForAmount( walletVersion: WALLET_PROTOCOL_VERSION, wireFees: exchangeWireInfo, withdrawFee: acc, + termsOfServiceAccepted: tosAccepted, }; return ret; } @@ -674,17 +683,17 @@ export async function getWithdrawDetailsForUri( talerWithdrawUri: string, maybeSelectedExchange?: string, ): Promise { - const info = await getWithdrawalInfo(ws, talerWithdrawUri); - let rci: ReserveCreationInfo | undefined = undefined; + const info = await getBankWithdrawalInfo(ws, talerWithdrawUri); + let rci: ExchangeWithdrawDetails | undefined = undefined; if (maybeSelectedExchange) { - rci = await getWithdrawDetailsForAmount( + rci = await getExchangeWithdrawalInfo( ws, maybeSelectedExchange, info.amount, ); } return { - withdrawInfo: info, - reserveCreationInfo: rci, + bankWithdrawDetails: info, + exchangeWithdrawDetails: rci, }; } diff --git a/src/wallet.ts b/src/wallet.ts index bf1b11fbd..edfc0b09d 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -37,9 +37,8 @@ import * as Amounts from "./util/amounts"; import { acceptWithdrawal, - getWithdrawalInfo, getWithdrawDetailsForUri, - getWithdrawDetailsForAmount, + getExchangeWithdrawalInfo, } from "./wallet-impl/withdraw"; import { @@ -79,7 +78,7 @@ import { TipStatus, WalletBalance, PreparePayResult, - DownloadedWithdrawInfo, + BankWithdrawDetails, WithdrawDetails, AcceptWithdrawalResponse, PurchaseDetails, @@ -88,6 +87,7 @@ import { HistoryQuery, WalletNotification, NotificationType, + ExchangeWithdrawDetails, } from "./walletTypes"; import { Logger } from "./util/logging"; @@ -97,6 +97,7 @@ import { updateExchangeFromUrl, getExchangeTrust, getExchangePaytoUri, + acceptExchangeTermsOfService, } from "./wallet-impl/exchanges"; import { processReserve } from "./wallet-impl/reserves"; @@ -167,8 +168,11 @@ export class Wallet { return getExchangePaytoUri(this.ws, exchangeBaseUrl, supportedTargetTypes); } - getWithdrawDetailsForAmount(baseUrl: any, amount: AmountJson): any { - return getWithdrawDetailsForAmount(this.ws, baseUrl, amount); + getWithdrawDetailsForAmount( + exchangeBaseUrl: string, + amount: AmountJson, + ): Promise { + return getExchangeWithdrawalInfo(this.ws, exchangeBaseUrl, amount); } addNotificationListener(f: (n: WalletNotification) => void): void { @@ -194,13 +198,21 @@ export class Wallet { await updateExchangeFromUrl(this.ws, pending.exchangeBaseUrl, forceNow); break; case "refresh": - await processRefreshSession(this.ws, pending.refreshSessionId, forceNow); + await processRefreshSession( + this.ws, + pending.refreshSessionId, + forceNow, + ); break; case "reserve": await processReserve(this.ws, pending.reservePub, forceNow); break; case "withdraw": - await processWithdrawSession(this.ws, pending.withdrawSessionId, forceNow); + await processWithdrawSession( + this.ws, + pending.withdrawSessionId, + forceNow, + ); break; case "proposal-choice": // Nothing to do, user needs to accept/reject @@ -524,6 +536,13 @@ export class Wallet { ); } + async acceptExchangeTermsOfService( + exchangeBaseUrl: string, + etag: string | undefined, + ) { + return acceptExchangeTermsOfService(this.ws, exchangeBaseUrl, etag); + } + async getDenoms(exchangeUrl: string): Promise { const denoms = await oneShotIterIndex( this.db, @@ -663,6 +682,10 @@ 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() { const reserves = await oneShotIter(this.db, Stores.reserves).toArray(); for (const r of reserves) { @@ -687,20 +710,6 @@ export class Wallet { // strategy to test it. } - /** - * Get information about a withdrawal from - * a taler://withdraw URI. - */ - async getWithdrawalInfo( - talerWithdrawUri: string, - ): Promise { - try { - return getWithdrawalInfo(this.ws, talerWithdrawUri); - } finally { - this.latch.trigger(); - } - } - async acceptWithdrawal( talerWithdrawUri: string, selectedExchange: string, diff --git a/src/walletTypes.ts b/src/walletTypes.ts index 32a5b0192..e136b4e01 100644 --- a/src/walletTypes.ts +++ b/src/walletTypes.ts @@ -70,7 +70,7 @@ export class CreateReserveResponse { * * Sent to the wallet frontend to be rendered and shown to the user. */ -export interface ReserveCreationInfo { +export interface ExchangeWithdrawDetails { /** * Exchange that the reserve will be created at. */ @@ -107,6 +107,11 @@ export interface ReserveCreationInfo { */ isAudited: boolean; + /** + * Did the user already accept the current terms of service for the exchange? + */ + termsOfServiceAccepted: boolean; + /** * The exchange is trusted directly. */ @@ -148,8 +153,8 @@ export interface ReserveCreationInfo { } export interface WithdrawDetails { - withdrawInfo: DownloadedWithdrawInfo; - reserveCreationInfo: ReserveCreationInfo | undefined; + bankWithdrawDetails: BankWithdrawDetails; + exchangeWithdrawDetails: ExchangeWithdrawDetails | undefined; } /** @@ -449,7 +454,7 @@ export interface PreparePayResultPaid { nextUrl: string; } -export interface DownloadedWithdrawInfo { +export interface BankWithdrawDetails { selectionDone: boolean; transferDone: boolean; amount: AmountJson; diff --git a/src/webex/messages.ts b/src/webex/messages.ts index 6c57385c3..4aaf75b2b 100644 --- a/src/webex/messages.ts +++ b/src/webex/messages.ts @@ -75,7 +75,7 @@ export interface MessageMap { }; "reserve-creation-info": { request: { baseUrl: string; amount: AmountJson }; - response: walletTypes.ReserveCreationInfo; + response: walletTypes.ExchangeWithdrawDetails; }; "get-history": { request: {}; diff --git a/src/webex/pages/withdraw.tsx b/src/webex/pages/withdraw.tsx index 6b7152dc2..3ee0f768a 100644 --- a/src/webex/pages/withdraw.tsx +++ b/src/webex/pages/withdraw.tsx @@ -57,9 +57,9 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) { return; } console.log("got withdrawDetails", d); - if (!selectedExchange && d.withdrawInfo.suggestedExchange) { + if (!selectedExchange && d.bankWithdrawDetails.suggestedExchange) { console.log("setting selected exchange"); - setSelectedExchange(d.withdrawInfo.suggestedExchange); + setSelectedExchange(d.bankWithdrawDetails.suggestedExchange); } setDetails(d); }; @@ -101,7 +101,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) { } if (selecting) { - const bankSuggestion = details && details.withdrawInfo.suggestedExchange; + const bankSuggestion = details && details.bankWithdrawDetails.suggestedExchange; return (
{i18n.str`Please select an exchange. You can review the details before after your selection.`} @@ -157,7 +157,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {
You are about to withdraw{" "} - {renderAmount(details.withdrawInfo.amount)} from your + {renderAmount(details.bankWithdrawDetails.amount)} from your bank account into your wallet.
@@ -188,8 +188,8 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {

- {details.reserveCreationInfo ? ( - + {details.exchangeWithdrawDetails ? ( + ) : null}
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx index 945719b65..bf9cdc76f 100644 --- a/src/webex/renderHtml.tsx +++ b/src/webex/renderHtml.tsx @@ -26,7 +26,7 @@ import { AmountJson } from "../util/amounts"; import * as Amounts from "../util/amounts"; import { DenominationRecord } from "../dbTypes"; -import { ReserveCreationInfo } from "../walletTypes"; +import { ExchangeWithdrawDetails } from "../walletTypes"; import * as moment from "moment"; import * as i18n from "../i18n"; import React from "react"; @@ -126,7 +126,7 @@ export class Collapsible extends React.Component< } function AuditorDetailsView(props: { - rci: ReserveCreationInfo | null; + rci: ExchangeWithdrawDetails | null; }): JSX.Element { const rci = props.rci; console.log("rci", rci); @@ -163,7 +163,7 @@ function AuditorDetailsView(props: { } function FeeDetailsView(props: { - rci: ReserveCreationInfo | null; + rci: ExchangeWithdrawDetails | null; }): JSX.Element { const rci = props.rci; if (!rci) { @@ -271,7 +271,7 @@ function FeeDetailsView(props: { * Shows details about a withdraw request. */ export function WithdrawDetailView(props: { - rci: ReserveCreationInfo | null; + rci: ExchangeWithdrawDetails | null; }): JSX.Element { const rci = props.rci; return ( diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts index c4fa65186..b0af7ac29 100644 --- a/src/webex/wxApi.ts +++ b/src/webex/wxApi.ts @@ -34,7 +34,7 @@ import { import { BenchmarkResult, ConfirmPayResult, - ReserveCreationInfo, + ExchangeWithdrawDetails, SenderWireInfos, TipStatus, WalletBalance, @@ -102,7 +102,7 @@ async function callBackend( * from a given reserve. */ export function getReserveCreationInfo(baseUrl: string, - amount: AmountJson): Promise { + amount: AmountJson): Promise { return callBackend("reserve-creation-info", { baseUrl, amount }); } -- cgit v1.2.3