diff options
Diffstat (limited to 'src/wallet-impl')
-rw-r--r-- | src/wallet-impl/exchanges.ts | 69 | ||||
-rw-r--r-- | src/wallet-impl/tip.ts | 4 | ||||
-rw-r--r-- | src/wallet-impl/withdraw.ts | 37 |
3 files changed, 88 insertions, 22 deletions
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<DownloadedWithdrawInfo> { +): Promise<BankWithdrawDetails> { 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<AcceptWithdrawalResponse> { - 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<ReserveCreationInfo> { +): Promise<ExchangeWithdrawDetails> { 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<WithdrawDetails> { - 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, }; } |