aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/exchanges.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-08-29 13:44:50 +0200
committerFlorian Dold <florian@dold.me>2023-08-29 13:44:50 +0200
commitebb1c58e7a2be01e42f35dfe6d890a08cf992c79 (patch)
tree7ecb9a2d082d499854502114924351329c7c1bf9 /packages/taler-wallet-core/src/operations/exchanges.ts
parent9402aeef5b111c3a9bf51a7b204044ba19de8607 (diff)
downloadwallet-core-ebb1c58e7a2be01e42f35dfe6d890a08cf992c79.tar.xz
wallet-core: remove usage of /wire
Diffstat (limited to 'packages/taler-wallet-core/src/operations/exchanges.ts')
-rw-r--r--packages/taler-wallet-core/src/operations/exchanges.ts170
1 files changed, 76 insertions, 94 deletions
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts
index 8bf70fa27..c6b46e360 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -19,12 +19,14 @@
*/
import {
AbsoluteTime,
+ AccountInfo,
Amounts,
CancellationToken,
canonicalizeBaseUrl,
codecForExchangeKeysJson,
- codecForExchangeWireJson,
+ DenomGroup,
DenominationPubKey,
+ DenomKeyType,
Duration,
durationFromSpec,
encodeCrock,
@@ -51,6 +53,7 @@ import {
URL,
WireFee,
WireFeeMap,
+ WireFeesJson,
WireInfo,
} from "@gnu-taler/taler-util";
import {
@@ -84,43 +87,6 @@ import {
const logger = new Logger("exchanges.ts");
-function denominationRecordFromKeys(
- exchangeBaseUrl: string,
- exchangeMasterPub: string,
- listIssueDate: TalerProtocolTimestamp,
- denomIn: ExchangeDenomination,
-): DenominationRecord {
- let denomPub: DenominationPubKey;
- denomPub = denomIn.denom_pub;
- const denomPubHash = encodeCrock(hashDenomPub(denomPub));
- const value = Amounts.parseOrThrow(denomIn.value);
- const d: DenominationRecord = {
- denomPub,
- denomPubHash,
- exchangeBaseUrl,
- exchangeMasterPub,
- fees: {
- feeDeposit: Amounts.stringify(denomIn.fee_deposit),
- feeRefresh: Amounts.stringify(denomIn.fee_refresh),
- feeRefund: Amounts.stringify(denomIn.fee_refund),
- feeWithdraw: Amounts.stringify(denomIn.fee_withdraw),
- },
- isOffered: true,
- isRevoked: false,
- masterSig: denomIn.master_sig,
- stampExpireDeposit: denomIn.stamp_expire_deposit,
- stampExpireLegal: denomIn.stamp_expire_legal,
- stampExpireWithdraw: denomIn.stamp_expire_withdraw,
- stampStart: denomIn.stamp_start,
- verificationStatus: DenominationVerificationStatus.Unverified,
- amountFrac: value.fraction,
- amountVal: value.value,
- currency: value.currency,
- listIssueDate,
- };
- return d;
-}
-
export function getExchangeRequestTimeout(): Duration {
return Duration.fromSpec({
seconds: 5,
@@ -145,7 +111,7 @@ export async function downloadExchangeWithTermsOfService(
Accept: contentType,
};
- const resp = await http.get(reqUrl.href, {
+ const resp = await http.fetch(reqUrl.href, {
headers,
timeout,
});
@@ -241,7 +207,7 @@ export async function acceptExchangeTermsOfService(
async function validateWireInfo(
ws: InternalWalletState,
versionCurrent: number,
- wireInfo: ExchangeWireJson,
+ wireInfo: ExchangeKeysDownloadResult,
masterPublicKey: string,
): Promise<WireInfo> {
for (const a of wireInfo.accounts) {
@@ -267,9 +233,9 @@ async function validateWireInfo(
}
logger.trace("account validation done");
const feesForType: WireFeeMap = {};
- for (const wireMethod of Object.keys(wireInfo.fees)) {
+ for (const wireMethod of Object.keys(wireInfo.wireFees)) {
const feeList: WireFee[] = [];
- for (const x of wireInfo.fees[wireMethod]) {
+ for (const x of wireInfo.wireFees[wireMethod]) {
const startStamp = x.start_date;
const endStamp = x.end_date;
const fee: WireFee = {
@@ -343,7 +309,6 @@ async function validateGlobalFees(
}
export interface ExchangeInfo {
- wire: ExchangeWireJson;
keys: ExchangeKeysDownloadResult;
}
@@ -351,11 +316,6 @@ export async function downloadExchangeInfo(
exchangeBaseUrl: string,
http: HttpRequestLibrary,
): Promise<ExchangeInfo> {
- const wireInfo = await downloadExchangeWireInfo(
- exchangeBaseUrl,
- http,
- Duration.getForever(),
- );
const keysInfo = await downloadExchangeKeysInfo(
exchangeBaseUrl,
http,
@@ -363,33 +323,9 @@ export async function downloadExchangeInfo(
);
return {
keys: keysInfo,
- wire: wireInfo,
};
}
-/**
- * Fetch wire information for an exchange.
- *
- * @param exchangeBaseUrl Exchange base URL, assumed to be already normalized.
- */
-async function downloadExchangeWireInfo(
- exchangeBaseUrl: string,
- http: HttpRequestLibrary,
- timeout: Duration,
-): Promise<ExchangeWireJson> {
- const reqUrl = new URL("wire", exchangeBaseUrl);
-
- const resp = await http.get(reqUrl.href, {
- timeout,
- });
- const wireInfo = await readSuccessResponseJsonOrThrow(
- resp,
- codecForExchangeWireJson(),
- );
-
- return wireInfo;
-}
-
export async function provideExchangeRecordInTx(
ws: InternalWalletState,
tx: GetReadWriteAccess<{
@@ -434,6 +370,8 @@ interface ExchangeKeysDownloadResult {
recoup: Recoup[];
listIssueDate: TalerProtocolTimestamp;
globalFees: GlobalFees[];
+ accounts: AccountInfo[];
+ wireFees: { [methodName: string]: WireFeesJson[] };
}
/**
@@ -446,7 +384,7 @@ async function downloadExchangeKeysInfo(
): Promise<ExchangeKeysDownloadResult> {
const keysUrl = new URL("keys", baseUrl);
- const resp = await http.get(keysUrl.href, {
+ const resp = await http.fetch(keysUrl.href, {
timeout,
});
const exchangeKeysJsonUnchecked = await readSuccessResponseJsonOrThrow(
@@ -454,7 +392,7 @@ async function downloadExchangeKeysInfo(
codecForExchangeKeysJson(),
);
- if (exchangeKeysJsonUnchecked.denoms.length === 0) {
+ if (exchangeKeysJsonUnchecked.denominations.length === 0) {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT,
{
@@ -481,23 +419,72 @@ async function downloadExchangeKeysInfo(
);
}
- const currency = Amounts.parseOrThrow(
- exchangeKeysJsonUnchecked.denoms[0].value,
- ).currency.toUpperCase();
+ const currency = exchangeKeysJsonUnchecked.currency;
+
+ const currentDenominations: DenominationRecord[] = [];
+
+ for (const denomGroup of exchangeKeysJsonUnchecked.denominations) {
+ switch (denomGroup.cipher) {
+ case "RSA":
+ case "RSA+age_restricted": {
+ let ageMask = 0;
+ if (denomGroup.cipher === "RSA+age_restricted") {
+ ageMask = denomGroup.age_mask;
+ }
+ for (const denomIn of denomGroup.denoms) {
+ const denomPub: DenominationPubKey = {
+ age_mask: ageMask,
+ cipher: DenomKeyType.Rsa,
+ rsa_public_key: denomIn.rsa_pub,
+ };
+ const denomPubHash = encodeCrock(hashDenomPub(denomPub));
+ const value = Amounts.parseOrThrow(denomGroup.value);
+ const rec: DenominationRecord = {
+ denomPub,
+ denomPubHash,
+ exchangeBaseUrl: baseUrl,
+ exchangeMasterPub: exchangeKeysJsonUnchecked.master_public_key,
+ isOffered: true,
+ isRevoked: false,
+ amountFrac: value.fraction,
+ amountVal: value.value,
+ currency: value.currency,
+ stampExpireDeposit: denomIn.stamp_expire_deposit,
+ stampExpireLegal: denomIn.stamp_expire_legal,
+ stampExpireWithdraw: denomIn.stamp_expire_withdraw,
+ stampStart: denomIn.stamp_start,
+ verificationStatus: DenominationVerificationStatus.Unverified,
+ masterSig: denomIn.master_sig,
+ listIssueDate: exchangeKeysJsonUnchecked.list_issue_date,
+ fees: {
+ feeDeposit: Amounts.stringify(denomGroup.fee_deposit),
+ feeRefresh: Amounts.stringify(denomGroup.fee_refresh),
+ feeRefund: Amounts.stringify(denomGroup.fee_refund),
+ feeWithdraw: Amounts.stringify(denomGroup.fee_withdraw),
+ },
+ };
+ currentDenominations.push(rec);
+ }
+ break;
+ }
+ case "CS+age_restricted":
+ case "CS":
+ logger.warn("Clause-Schnorr denominations not supported");
+ continue;
+ default:
+ logger.warn(
+ `denomination type ${(denomGroup as any).cipher} not supported`,
+ );
+ continue;
+ }
+ }
return {
masterPublicKey: exchangeKeysJsonUnchecked.master_public_key,
currency,
baseUrl: exchangeKeysJsonUnchecked.base_url,
auditors: exchangeKeysJsonUnchecked.auditors,
- currentDenominations: exchangeKeysJsonUnchecked.denoms.map((d) =>
- denominationRecordFromKeys(
- baseUrl,
- exchangeKeysJsonUnchecked.master_public_key,
- exchangeKeysJsonUnchecked.list_issue_date,
- d,
- ),
- ),
+ currentDenominations,
protocolVersion: exchangeKeysJsonUnchecked.version,
signingKeys: exchangeKeysJsonUnchecked.signkeys,
reserveClosingDelay: exchangeKeysJsonUnchecked.reserve_closing_delay,
@@ -509,6 +496,8 @@ async function downloadExchangeKeysInfo(
recoup: exchangeKeysJsonUnchecked.recoup ?? [],
listIssueDate: exchangeKeysJsonUnchecked.list_issue_date,
globalFees: exchangeKeysJsonUnchecked.global_fees,
+ accounts: exchangeKeysJsonUnchecked.accounts,
+ wireFees: exchangeKeysJsonUnchecked.wire_fees,
};
}
@@ -654,14 +643,7 @@ export async function updateExchangeFromUrlHandler(
}
}
- logger.trace("updating exchange /wire info");
- const wireInfoDownload = await downloadExchangeWireInfo(
- exchangeBaseUrl,
- ws.http,
- timeout,
- );
-
- logger.trace("validating exchange /wire info");
+ logger.trace("validating exchange wire info");
const version = LibtoolVersion.parseVersion(keysInfo.protocolVersion);
if (!version) {
@@ -672,7 +654,7 @@ export async function updateExchangeFromUrlHandler(
const wireInfo = await validateWireInfo(
ws,
version.current,
- wireInfoDownload,
+ keysInfo,
keysInfo.masterPublicKey,
);