wallet-core: remove usage of /wire

This commit is contained in:
Florian Dold 2023-08-29 13:44:50 +02:00
parent 9402aeef5b
commit ebb1c58e7a
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
17 changed files with 317 additions and 188 deletions

View File

@ -19,10 +19,16 @@
*/ */
import { import {
AbsoluteTime, AbsoluteTime,
Amounts,
codecForExchangeKeysJson, codecForExchangeKeysJson,
DenominationPubKey, DenominationPubKey,
DenomKeyType,
Duration, Duration,
durationFromSpec, durationFromSpec,
encodeCrock,
ExchangeKeysJson,
hashDenomPub,
Logger,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
createPlatformHttpLib, createPlatformHttpLib,
@ -40,6 +46,52 @@ import {
} from "../harness/harness.js"; } from "../harness/harness.js";
import { withdrawViaBank } from "../harness/helpers.js"; import { withdrawViaBank } from "../harness/helpers.js";
const logger = new Logger("test-exchange-timetravel.ts");
interface DenomInfo {
denomPub: DenominationPubKey;
expireDeposit: string;
}
function getDenomInfoFromKeys(ek: ExchangeKeysJson): DenomInfo[] {
const denomInfos: DenomInfo[] = [];
for (const denomGroup of ek.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,
};
denomInfos.push({
denomPub,
expireDeposit: AbsoluteTime.stringify(
AbsoluteTime.fromProtocolTimestamp(denomIn.stamp_expire_deposit),
),
});
}
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 denomInfos;
}
async function applyTimeTravel( async function applyTimeTravel(
timetravelDuration: Duration, timetravelDuration: Duration,
s: { s: {
@ -144,7 +196,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" });
const keysResp1 = await http.get(exchange.baseUrl + "keys"); const keysResp1 = await http.fetch(exchange.baseUrl + "keys");
const keys1 = await readSuccessResponseJsonOrThrow( const keys1 = await readSuccessResponseJsonOrThrow(
keysResp1, keysResp1,
codecForExchangeKeysJson(), codecForExchangeKeysJson(),
@ -163,7 +215,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
merchant, merchant,
}); });
const keysResp2 = await http.get(exchange.baseUrl + "keys"); const keysResp2 = await http.fetch(exchange.baseUrl + "keys");
const keys2 = await readSuccessResponseJsonOrThrow( const keys2 = await readSuccessResponseJsonOrThrow(
keysResp2, keysResp2,
codecForExchangeKeysJson(), codecForExchangeKeysJson(),
@ -173,41 +225,31 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
JSON.stringify(keys2, undefined, 2), JSON.stringify(keys2, undefined, 2),
); );
const denomPubs1 = keys1.denoms.map((x) => { const denomPubs1 = getDenomInfoFromKeys(keys1);
return { const denomPubs2 = getDenomInfoFromKeys(keys2);
denomPub: x.denom_pub,
expireDeposit: AbsoluteTime.stringify(
AbsoluteTime.fromProtocolTimestamp(x.stamp_expire_deposit),
),
};
});
const denomPubs2 = keys2.denoms.map((x) => {
return {
denomPub: x.denom_pub,
expireDeposit: AbsoluteTime.stringify(
AbsoluteTime.fromProtocolTimestamp(x.stamp_expire_deposit),
),
};
});
const dps2 = new Set(denomPubs2.map((x) => x.denomPub)); const dps2 = new Set(denomPubs2.map((x) => x.denomPub));
console.log("=== KEYS RESPONSE 1 ==="); console.log("=== KEYS RESPONSE 1 ===");
console.log( console.log(
"list issue date", "list issue date",
AbsoluteTime.stringify(AbsoluteTime.fromProtocolTimestamp(keys1.list_issue_date)), AbsoluteTime.stringify(
AbsoluteTime.fromProtocolTimestamp(keys1.list_issue_date),
),
); );
console.log("num denoms", keys1.denoms.length); console.log("num denoms", denomPubs1.length);
console.log("denoms", JSON.stringify(denomPubs1, undefined, 2)); console.log("denoms", JSON.stringify(denomPubs1, undefined, 2));
console.log("=== KEYS RESPONSE 2 ==="); console.log("=== KEYS RESPONSE 2 ===");
console.log( console.log(
"list issue date", "list issue date",
AbsoluteTime.stringify(AbsoluteTime.fromProtocolTimestamp(keys2.list_issue_date)), AbsoluteTime.stringify(
AbsoluteTime.fromProtocolTimestamp(keys2.list_issue_date),
),
); );
console.log("num denoms", keys2.denoms.length); console.log("num denoms", denomPubs2.length);
console.log("denoms", JSON.stringify(denomPubs2, undefined, 2)); console.log("denoms", JSON.stringify(denomPubs2, undefined, 2));
for (const da of denomPubs1) { for (const da of denomPubs1) {

View File

@ -72,7 +72,7 @@ async function testWithClaimToken(
let talerPayUri: string; let talerPayUri: string;
{ {
const httpResp = await httpLib.get( const httpResp = await httpLib.fetch(
new URL(`orders/${orderId}`, merchantBaseUrl).href, new URL(`orders/${orderId}`, merchantBaseUrl).href,
); );
const r = await httpResp.json(); const r = await httpResp.json();
@ -83,7 +83,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("token", claimToken); url.searchParams.set("token", claimToken);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
console.log(r); console.log(r);
@ -94,7 +94,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("token", claimToken); url.searchParams.set("token", claimToken);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { headers: {
Accept: "text/html", Accept: "text/html",
}, },
@ -120,7 +120,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const hcWrong = encodeCrock(getRandomBytes(64)); const hcWrong = encodeCrock(getRandomBytes(64));
url.searchParams.set("h_contract", hcWrong); url.searchParams.set("h_contract", hcWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -131,7 +131,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const ctWrong = encodeCrock(getRandomBytes(16)); const ctWrong = encodeCrock(getRandomBytes(16));
url.searchParams.set("token", ctWrong); url.searchParams.set("token", ctWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -141,7 +141,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("token", claimToken); url.searchParams.set("token", claimToken);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -151,7 +151,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("h_contract", contractTermsHash); url.searchParams.set("h_contract", contractTermsHash);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -160,7 +160,7 @@ async function testWithClaimToken(
// claimed, unpaid, access without credentials // claimed, unpaid, access without credentials
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 202); t.assertDeepEqual(httpResp.status, 202);
@ -178,7 +178,7 @@ async function testWithClaimToken(
// paid, access without credentials // paid, access without credentials
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 202); t.assertDeepEqual(httpResp.status, 202);
@ -189,7 +189,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const hcWrong = encodeCrock(getRandomBytes(64)); const hcWrong = encodeCrock(getRandomBytes(64));
url.searchParams.set("h_contract", hcWrong); url.searchParams.set("h_contract", hcWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -200,7 +200,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const ctWrong = encodeCrock(getRandomBytes(16)); const ctWrong = encodeCrock(getRandomBytes(16));
url.searchParams.set("token", ctWrong); url.searchParams.set("token", ctWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -210,7 +210,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("h_contract", contractTermsHash); url.searchParams.set("h_contract", contractTermsHash);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -220,7 +220,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("token", claimToken); url.searchParams.set("token", claimToken);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -232,7 +232,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("token", claimToken); url.searchParams.set("token", claimToken);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { Accept: "text/html" }, headers: { Accept: "text/html" },
}); });
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -269,7 +269,7 @@ async function testWithClaimToken(
{ {
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -280,7 +280,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
url.searchParams.set("session_id", sessionId); url.searchParams.set("session_id", sessionId);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -293,7 +293,7 @@ async function testWithClaimToken(
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
url.searchParams.set("session_id", sessionId); url.searchParams.set("session_id", sessionId);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { Accept: "text/html" }, headers: { Accept: "text/html" },
}); });
t.assertDeepEqual(httpResp.status, 302); t.assertDeepEqual(httpResp.status, 302);
@ -326,7 +326,7 @@ async function testWithoutClaimToken(
let talerPayUri: string; let talerPayUri: string;
{ {
const httpResp = await httpLib.get( const httpResp = await httpLib.fetch(
new URL(`orders/${orderId}`, merchantBaseUrl).href, new URL(`orders/${orderId}`, merchantBaseUrl).href,
); );
const r = await httpResp.json(); const r = await httpResp.json();
@ -336,7 +336,7 @@ async function testWithoutClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
console.log(r); console.log(r);
@ -346,7 +346,7 @@ async function testWithoutClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { headers: {
Accept: "text/html", Accept: "text/html",
}, },
@ -374,7 +374,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const hcWrong = encodeCrock(getRandomBytes(64)); const hcWrong = encodeCrock(getRandomBytes(64));
url.searchParams.set("h_contract", hcWrong); url.searchParams.set("h_contract", hcWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -385,7 +385,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const ctWrong = encodeCrock(getRandomBytes(16)); const ctWrong = encodeCrock(getRandomBytes(16));
url.searchParams.set("token", ctWrong); url.searchParams.set("token", ctWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -394,7 +394,7 @@ async function testWithoutClaimToken(
// claimed, unpaid, no claim token // claimed, unpaid, no claim token
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -404,7 +404,7 @@ async function testWithoutClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("h_contract", contractTermsHash); url.searchParams.set("h_contract", contractTermsHash);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -413,7 +413,7 @@ async function testWithoutClaimToken(
// claimed, unpaid, access without credentials // claimed, unpaid, access without credentials
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
// No credentials, but the order doesn't require a claim token. // No credentials, but the order doesn't require a claim token.
@ -434,7 +434,7 @@ async function testWithoutClaimToken(
// paid, access without credentials // paid, access without credentials
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -445,7 +445,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const hcWrong = encodeCrock(getRandomBytes(64)); const hcWrong = encodeCrock(getRandomBytes(64));
url.searchParams.set("h_contract", hcWrong); url.searchParams.set("h_contract", hcWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -456,7 +456,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const ctWrong = encodeCrock(getRandomBytes(16)); const ctWrong = encodeCrock(getRandomBytes(16));
url.searchParams.set("token", ctWrong); url.searchParams.set("token", ctWrong);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 403); t.assertDeepEqual(httpResp.status, 403);
@ -466,7 +466,7 @@ async function testWithoutClaimToken(
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
url.searchParams.set("h_contract", contractTermsHash); url.searchParams.set("h_contract", contractTermsHash);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -475,7 +475,7 @@ async function testWithoutClaimToken(
// paid, JSON // paid, JSON
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -486,7 +486,7 @@ async function testWithoutClaimToken(
// paid, HTML // paid, HTML
{ {
const url = new URL(`orders/${orderId}`, merchantBaseUrl); const url = new URL(`orders/${orderId}`, merchantBaseUrl);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { Accept: "text/html" }, headers: { Accept: "text/html" },
}); });
t.assertDeepEqual(httpResp.status, 200); t.assertDeepEqual(httpResp.status, 200);
@ -523,7 +523,7 @@ async function testWithoutClaimToken(
{ {
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -534,7 +534,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
url.searchParams.set("session_id", sessionId); url.searchParams.set("session_id", sessionId);
const httpResp = await httpLib.get(url.href); const httpResp = await httpLib.fetch(url.href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(httpResp.status, 402); t.assertDeepEqual(httpResp.status, 402);
@ -547,7 +547,7 @@ async function testWithoutClaimToken(
const url = new URL(`orders/${apOrderId}`, merchantBaseUrl); const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
url.searchParams.set("token", apToken); url.searchParams.set("token", apToken);
url.searchParams.set("session_id", sessionId); url.searchParams.set("session_id", sessionId);
const httpResp = await httpLib.get(url.href, { const httpResp = await httpLib.fetch(url.href, {
headers: { Accept: "text/html" }, headers: { Accept: "text/html" },
}); });
t.assertDeepEqual(httpResp.status, 302); t.assertDeepEqual(httpResp.status, 302);
@ -572,14 +572,14 @@ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) {
const merchantBaseUrl = merchant.makeInstanceBaseUrl(); const merchantBaseUrl = merchant.makeInstanceBaseUrl();
{ {
const httpResp = await httpLib.get(new URL("config", merchantBaseUrl).href); const httpResp = await httpLib.fetch(new URL("config", merchantBaseUrl).href);
const r = await httpResp.json(); const r = await httpResp.json();
console.log(r); console.log(r);
t.assertDeepEqual(r.currency, "TESTKUDOS"); t.assertDeepEqual(r.currency, "TESTKUDOS");
} }
{ {
const httpResp = await httpLib.get( const httpResp = await httpLib.fetch(
new URL("orders/foo", merchantBaseUrl).href, new URL("orders/foo", merchantBaseUrl).href,
); );
const r = await httpResp.json(); const r = await httpResp.json();
@ -589,7 +589,7 @@ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) {
} }
{ {
const httpResp = await httpLib.get( const httpResp = await httpLib.fetch(
new URL("orders/foo", merchantBaseUrl).href, new URL("orders/foo", merchantBaseUrl).href,
{ {
headers: { headers: {

View File

@ -407,7 +407,7 @@ export async function checkExchangeHttpd(
{ {
const mgmtUrl = new URL("management/keys", baseUrl); const mgmtUrl = new URL("management/keys", baseUrl);
const resp = await httpLib.get(mgmtUrl.href); const resp = await httpLib.fetch(mgmtUrl.href);
const futureKeys = await readSuccessResponseJsonOrThrow( const futureKeys = await readSuccessResponseJsonOrThrow(
resp, resp,
@ -431,7 +431,7 @@ export async function checkExchangeHttpd(
{ {
const keysUrl = new URL("keys", baseUrl); const keysUrl = new URL("keys", baseUrl);
const resp = await Promise.race([httpLib.get(keysUrl.href), delayMs(2000)]); const resp = await Promise.race([httpLib.fetch(keysUrl.href), delayMs(2000)]);
if (!resp) { if (!resp) {
context.numErr++; context.numErr++;
@ -467,7 +467,7 @@ export async function checkExchangeHttpd(
{ {
const keysUrl = new URL("wire", baseUrl); const keysUrl = new URL("wire", baseUrl);
const resp = await Promise.race([httpLib.get(keysUrl.href), delayMs(2000)]); const resp = await Promise.race([httpLib.fetch(keysUrl.href), delayMs(2000)]);
if (!resp) { if (!resp) {
context.numErr++; context.numErr++;

View File

@ -25,7 +25,7 @@
* Imports. * Imports.
*/ */
import { codecForAmountString } from "./amounts.js"; import { Amounts, codecForAmountString } from "./amounts.js";
import { import {
buildCodecForObject, buildCodecForObject,
buildCodecForUnion, buildCodecForUnion,
@ -719,16 +719,12 @@ export class ExchangeSignKeyJson {
* Structure that the exchange gives us in /keys. * Structure that the exchange gives us in /keys.
*/ */
export class ExchangeKeysJson { export class ExchangeKeysJson {
/** /**
* Canonical, public base URL of the exchange. * Canonical, public base URL of the exchange.
*/ */
base_url: string; base_url: string;
/** currency: string;
* List of offered denominations.
*/
denoms: ExchangeDenomination[];
/** /**
* The exchange's master public key. * The exchange's master public key.
@ -764,6 +760,111 @@ export class ExchangeKeysJson {
reserve_closing_delay: TalerProtocolDuration; reserve_closing_delay: TalerProtocolDuration;
global_fees: GlobalFees[]; global_fees: GlobalFees[];
accounts: AccountInfo[];
wire_fees: { [methodName: string]: WireFeesJson[] };
denominations: DenomGroup[];
}
export type DenomGroup =
| DenomGroupRsa
| DenomGroupCs
| DenomGroupRsaAgeRestricted
| DenomGroupCsAgeRestricted;
export interface DenomGroupCommon {
// How much are coins of this denomination worth?
value: AmountString;
// Fee charged by the exchange for withdrawing a coin of this denomination.
fee_withdraw: AmountString;
// Fee charged by the exchange for depositing a coin of this denomination.
fee_deposit: AmountString;
// Fee charged by the exchange for refreshing a coin of this denomination.
fee_refresh: AmountString;
// Fee charged by the exchange for refunding a coin of this denomination.
fee_refund: AmountString;
// XOR of all the SHA-512 hash values of the denominations' public keys
// in this group. Note that for hashing, the binary format of the
// public keys is used, and not their base32 encoding.
hash: HashCodeString;
}
export interface DenomCommon {
// Signature of TALER_DenominationKeyValidityPS.
master_sig: EddsaSignatureString;
// When does the denomination key become valid?
stamp_start: TalerProtocolTimestamp;
// When is it no longer possible to deposit coins
// of this denomination?
stamp_expire_withdraw: TalerProtocolTimestamp;
// Timestamp indicating by when legal disputes relating to these coins must
// be settled, as the exchange will afterwards destroy its evidence relating to
// transactions involving this coin.
stamp_expire_legal: TalerProtocolTimestamp;
stamp_expire_deposit: TalerProtocolTimestamp;
// Set to 'true' if the exchange somehow "lost"
// the private key. The denomination was not
// necessarily revoked, but still cannot be used
// to withdraw coins at this time (theoretically,
// the private key could be recovered in the
// future; coins signed with the private key
// remain valid).
lost?: boolean;
}
export type RsaPublicKeySring = string;
export type AgeMask = number;
/**
* 32-byte value representing a point on Curve25519.
*/
export type Cs25519Point = string;
export interface DenomGroupRsa extends DenomGroupCommon {
cipher: "RSA";
denoms: ({
rsa_pub: RsaPublicKeySring;
} & DenomCommon)[];
}
export interface DenomGroupRsaAgeRestricted extends DenomGroupCommon {
cipher: "RSA+age_restricted";
age_mask: AgeMask;
denoms: ({
rsa_pub: RsaPublicKeySring;
} & DenomCommon)[];
}
export interface DenomGroupCs extends DenomGroupCommon {
cipher: "CS";
age_mask: AgeMask;
denoms: ({
cs_pub: Cs25519Point;
} & DenomCommon)[];
}
export interface DenomGroupCsAgeRestricted extends DenomGroupCommon {
cipher: "CS+age_restricted";
age_mask: AgeMask;
denoms: ({
cs_pub: Cs25519Point;
} & DenomCommon)[];
} }
export interface GlobalFees { export interface GlobalFees {
@ -847,10 +948,10 @@ export interface AccountInfo {
debit_restrictions?: any; debit_restrictions?: any;
} }
export interface ExchangeWireJson { /**
accounts: AccountInfo[]; * @deprecated
fees: { [methodName: string]: WireFeesJson[] }; */
} export interface ExchangeWireJson {}
/** /**
* Proposal returned from the contract URL. * Proposal returned from the contract URL.
@ -1404,10 +1505,13 @@ export const codecForGlobalFees = (): Codec<GlobalFees> =>
.property("master_sig", codecForString()) .property("master_sig", codecForString())
.build("GlobalFees"); .build("GlobalFees");
// FIXME: Validate properly!
export const codecForNgDenominations: Codec<DenomGroup> = codecForAny();
export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> => export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> =>
buildCodecForObject<ExchangeKeysJson>() buildCodecForObject<ExchangeKeysJson>()
.property("denoms", codecForList(codecForDenomination()))
.property("base_url", codecForString()) .property("base_url", codecForString())
.property("currency", codecForString())
.property("master_public_key", codecForString()) .property("master_public_key", codecForString())
.property("auditors", codecForList(codecForAuditor())) .property("auditors", codecForList(codecForAuditor()))
.property("list_issue_date", codecForTimestamp) .property("list_issue_date", codecForTimestamp)
@ -1416,6 +1520,9 @@ export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> =>
.property("version", codecForString()) .property("version", codecForString())
.property("reserve_closing_delay", codecForDuration) .property("reserve_closing_delay", codecForDuration)
.property("global_fees", codecForList(codecForGlobalFees())) .property("global_fees", codecForList(codecForGlobalFees()))
.property("accounts", codecForList(codecForAccountInfo()))
.property("wire_fees", codecForMap(codecForList(codecForWireFeesJson())))
.property("denominations", codecForList(codecForNgDenominations))
.build("ExchangeKeysJson"); .build("ExchangeKeysJson");
export const codecForWireFeesJson = (): Codec<WireFeesJson> => export const codecForWireFeesJson = (): Codec<WireFeesJson> =>
@ -1436,12 +1543,6 @@ export const codecForAccountInfo = (): Codec<AccountInfo> =>
.property("debit_restrictions", codecForAny()) .property("debit_restrictions", codecForAny())
.build("AccountInfo"); .build("AccountInfo");
export const codecForExchangeWireJson = (): Codec<ExchangeWireJson> =>
buildCodecForObject<ExchangeWireJson>()
.property("accounts", codecForList(codecForAccountInfo()))
.property("fees", codecForMap(codecForList(codecForWireFeesJson())))
.build("ExchangeWireJson");
export const codecForProposal = (): Codec<Proposal> => export const codecForProposal = (): Codec<Proposal> =>
buildCodecForObject<Proposal>() buildCodecForObject<Proposal>()
.property("contract_terms", codecForAny()) .property("contract_terms", codecForAny())

View File

@ -224,7 +224,7 @@ export namespace BankAccessApi {
`accounts/${bankUser.username}`, `accounts/${bankUser.username}`,
bank.bankAccessApiBaseUrl, bank.bankAccessApiBaseUrl,
); );
const resp = await bank.http.get(url.href, { const resp = await bank.http.fetch(url.href, {
headers: { headers: {
Authorization: makeBasicAuthHeader( Authorization: makeBasicAuthHeader(
bankUser.username, bankUser.username,

View File

@ -352,6 +352,7 @@ export interface DenomFees {
export interface DenominationRecord { export interface DenominationRecord {
currency: string; currency: string;
// FIXME: Use binary encoding of amount instead?
amountVal: number; amountVal: number;
amountFrac: number; amountFrac: number;

View File

@ -137,7 +137,7 @@ export async function topupReserveWithDemobank(
throw Error("no suggested exchange"); throw Error("no suggested exchange");
} }
const plainPaytoUris = const plainPaytoUris =
exchangeInfo.wire.accounts.map((x) => x.payto_uri) ?? []; exchangeInfo.keys.accounts.map((x) => x.payto_uri) ?? [];
if (plainPaytoUris.length <= 0) { if (plainPaytoUris.length <= 0) {
throw new Error(); throw new Error();
} }
@ -338,7 +338,10 @@ export async function refreshCoin(req: {
logger.info("requesting melt done"); logger.info("requesting melt done");
const meltHttpResp = await http.postJson(meltReqUrl.href, meltReqBody); const meltHttpResp = await http.fetch(meltReqUrl.href, {
method: "POST",
body: meltReqBody,
});
const meltResponse = await readSuccessResponseJsonOrThrow( const meltResponse = await readSuccessResponseJsonOrThrow(
meltHttpResp, meltHttpResp,
@ -386,7 +389,7 @@ export async function createFakebankReserve(args: {
exchangeInfo: ExchangeInfo; exchangeInfo: ExchangeInfo;
}): Promise<void> { }): Promise<void> {
const { http, fakebankBaseUrl, amount, reservePub } = args; const { http, fakebankBaseUrl, amount, reservePub } = args;
const paytoUri = args.exchangeInfo.wire.accounts[0].payto_uri; const paytoUri = args.exchangeInfo.keys.accounts[0].payto_uri;
const pt = parsePaytoUri(paytoUri); const pt = parsePaytoUri(paytoUri);
if (!pt) { if (!pt) {
throw Error("failed to parse payto URI"); throw Error("failed to parse payto URI");

View File

@ -70,7 +70,7 @@ export class DevExperimentHttpLib implements HttpRequestLibrary {
opt?: HttpRequestOptions | undefined, opt?: HttpRequestOptions | undefined,
): Promise<HttpResponse> { ): Promise<HttpResponse> {
logger.trace(`devexperiment httplib ${url}`); logger.trace(`devexperiment httplib ${url}`);
return this.underlyingLib.get(url, opt); return this.underlyingLib.fetch(url, opt);
} }
postJson( postJson(

View File

@ -661,7 +661,7 @@ export async function addBackupProvider(
} }
}); });
const termsUrl = new URL("config", canonUrl); const termsUrl = new URL("config", canonUrl);
const resp = await ws.http.get(termsUrl.href); const resp = await ws.http.fetch(termsUrl.href);
const terms = await readSuccessResponseJsonOrThrow( const terms = await readSuccessResponseJsonOrThrow(
resp, resp,
codecForSyncTermsOfServiceResponse(), codecForSyncTermsOfServiceResponse(),

View File

@ -19,12 +19,14 @@
*/ */
import { import {
AbsoluteTime, AbsoluteTime,
AccountInfo,
Amounts, Amounts,
CancellationToken, CancellationToken,
canonicalizeBaseUrl, canonicalizeBaseUrl,
codecForExchangeKeysJson, codecForExchangeKeysJson,
codecForExchangeWireJson, DenomGroup,
DenominationPubKey, DenominationPubKey,
DenomKeyType,
Duration, Duration,
durationFromSpec, durationFromSpec,
encodeCrock, encodeCrock,
@ -51,6 +53,7 @@ import {
URL, URL,
WireFee, WireFee,
WireFeeMap, WireFeeMap,
WireFeesJson,
WireInfo, WireInfo,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
@ -84,43 +87,6 @@ import {
const logger = new Logger("exchanges.ts"); 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 { export function getExchangeRequestTimeout(): Duration {
return Duration.fromSpec({ return Duration.fromSpec({
seconds: 5, seconds: 5,
@ -145,7 +111,7 @@ export async function downloadExchangeWithTermsOfService(
Accept: contentType, Accept: contentType,
}; };
const resp = await http.get(reqUrl.href, { const resp = await http.fetch(reqUrl.href, {
headers, headers,
timeout, timeout,
}); });
@ -241,7 +207,7 @@ export async function acceptExchangeTermsOfService(
async function validateWireInfo( async function validateWireInfo(
ws: InternalWalletState, ws: InternalWalletState,
versionCurrent: number, versionCurrent: number,
wireInfo: ExchangeWireJson, wireInfo: ExchangeKeysDownloadResult,
masterPublicKey: string, masterPublicKey: string,
): Promise<WireInfo> { ): Promise<WireInfo> {
for (const a of wireInfo.accounts) { for (const a of wireInfo.accounts) {
@ -267,9 +233,9 @@ async function validateWireInfo(
} }
logger.trace("account validation done"); logger.trace("account validation done");
const feesForType: WireFeeMap = {}; const feesForType: WireFeeMap = {};
for (const wireMethod of Object.keys(wireInfo.fees)) { for (const wireMethod of Object.keys(wireInfo.wireFees)) {
const feeList: WireFee[] = []; const feeList: WireFee[] = [];
for (const x of wireInfo.fees[wireMethod]) { for (const x of wireInfo.wireFees[wireMethod]) {
const startStamp = x.start_date; const startStamp = x.start_date;
const endStamp = x.end_date; const endStamp = x.end_date;
const fee: WireFee = { const fee: WireFee = {
@ -343,7 +309,6 @@ async function validateGlobalFees(
} }
export interface ExchangeInfo { export interface ExchangeInfo {
wire: ExchangeWireJson;
keys: ExchangeKeysDownloadResult; keys: ExchangeKeysDownloadResult;
} }
@ -351,11 +316,6 @@ export async function downloadExchangeInfo(
exchangeBaseUrl: string, exchangeBaseUrl: string,
http: HttpRequestLibrary, http: HttpRequestLibrary,
): Promise<ExchangeInfo> { ): Promise<ExchangeInfo> {
const wireInfo = await downloadExchangeWireInfo(
exchangeBaseUrl,
http,
Duration.getForever(),
);
const keysInfo = await downloadExchangeKeysInfo( const keysInfo = await downloadExchangeKeysInfo(
exchangeBaseUrl, exchangeBaseUrl,
http, http,
@ -363,33 +323,9 @@ export async function downloadExchangeInfo(
); );
return { return {
keys: keysInfo, 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( export async function provideExchangeRecordInTx(
ws: InternalWalletState, ws: InternalWalletState,
tx: GetReadWriteAccess<{ tx: GetReadWriteAccess<{
@ -434,6 +370,8 @@ interface ExchangeKeysDownloadResult {
recoup: Recoup[]; recoup: Recoup[];
listIssueDate: TalerProtocolTimestamp; listIssueDate: TalerProtocolTimestamp;
globalFees: GlobalFees[]; globalFees: GlobalFees[];
accounts: AccountInfo[];
wireFees: { [methodName: string]: WireFeesJson[] };
} }
/** /**
@ -446,7 +384,7 @@ async function downloadExchangeKeysInfo(
): Promise<ExchangeKeysDownloadResult> { ): Promise<ExchangeKeysDownloadResult> {
const keysUrl = new URL("keys", baseUrl); const keysUrl = new URL("keys", baseUrl);
const resp = await http.get(keysUrl.href, { const resp = await http.fetch(keysUrl.href, {
timeout, timeout,
}); });
const exchangeKeysJsonUnchecked = await readSuccessResponseJsonOrThrow( const exchangeKeysJsonUnchecked = await readSuccessResponseJsonOrThrow(
@ -454,7 +392,7 @@ async function downloadExchangeKeysInfo(
codecForExchangeKeysJson(), codecForExchangeKeysJson(),
); );
if (exchangeKeysJsonUnchecked.denoms.length === 0) { if (exchangeKeysJsonUnchecked.denominations.length === 0) {
throw TalerError.fromDetail( throw TalerError.fromDetail(
TalerErrorCode.WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT, TalerErrorCode.WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT,
{ {
@ -481,23 +419,72 @@ async function downloadExchangeKeysInfo(
); );
} }
const currency = Amounts.parseOrThrow( const currency = exchangeKeysJsonUnchecked.currency;
exchangeKeysJsonUnchecked.denoms[0].value,
).currency.toUpperCase(); 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 { return {
masterPublicKey: exchangeKeysJsonUnchecked.master_public_key, masterPublicKey: exchangeKeysJsonUnchecked.master_public_key,
currency, currency,
baseUrl: exchangeKeysJsonUnchecked.base_url, baseUrl: exchangeKeysJsonUnchecked.base_url,
auditors: exchangeKeysJsonUnchecked.auditors, auditors: exchangeKeysJsonUnchecked.auditors,
currentDenominations: exchangeKeysJsonUnchecked.denoms.map((d) => currentDenominations,
denominationRecordFromKeys(
baseUrl,
exchangeKeysJsonUnchecked.master_public_key,
exchangeKeysJsonUnchecked.list_issue_date,
d,
),
),
protocolVersion: exchangeKeysJsonUnchecked.version, protocolVersion: exchangeKeysJsonUnchecked.version,
signingKeys: exchangeKeysJsonUnchecked.signkeys, signingKeys: exchangeKeysJsonUnchecked.signkeys,
reserveClosingDelay: exchangeKeysJsonUnchecked.reserve_closing_delay, reserveClosingDelay: exchangeKeysJsonUnchecked.reserve_closing_delay,
@ -509,6 +496,8 @@ async function downloadExchangeKeysInfo(
recoup: exchangeKeysJsonUnchecked.recoup ?? [], recoup: exchangeKeysJsonUnchecked.recoup ?? [],
listIssueDate: exchangeKeysJsonUnchecked.list_issue_date, listIssueDate: exchangeKeysJsonUnchecked.list_issue_date,
globalFees: exchangeKeysJsonUnchecked.global_fees, 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"); logger.trace("validating exchange wire info");
const wireInfoDownload = await downloadExchangeWireInfo(
exchangeBaseUrl,
ws.http,
timeout,
);
logger.trace("validating exchange /wire info");
const version = LibtoolVersion.parseVersion(keysInfo.protocolVersion); const version = LibtoolVersion.parseVersion(keysInfo.protocolVersion);
if (!version) { if (!version) {
@ -672,7 +654,7 @@ export async function updateExchangeFromUrlHandler(
const wireInfo = await validateWireInfo( const wireInfo = await validateWireInfo(
ws, ws,
version.current, version.current,
wireInfoDownload, keysInfo,
keysInfo.masterPublicKey, keysInfo.masterPublicKey,
); );

View File

@ -41,7 +41,7 @@ export async function getMerchantInfo(
} }
const configUrl = new URL("config", canonBaseUrl); const configUrl = new URL("config", canonBaseUrl);
const resp = await ws.http.get(configUrl.href); const resp = await ws.http.fetch(configUrl.href);
const configResp = await readSuccessResponseJsonOrThrow( const configResp = await readSuccessResponseJsonOrThrow(
resp, resp,

View File

@ -530,7 +530,7 @@ export async function preparePeerPullDebit(
const getContractUrl = new URL(`contracts/${contractPub}`, exchangeBaseUrl); const getContractUrl = new URL(`contracts/${contractPub}`, exchangeBaseUrl);
const contractHttpResp = await ws.http.get(getContractUrl.href); const contractHttpResp = await ws.http.fetch(getContractUrl.href);
const contractResp = await readSuccessResponseJsonOrThrow( const contractResp = await readSuccessResponseJsonOrThrow(
contractHttpResp, contractHttpResp,

View File

@ -165,7 +165,7 @@ export async function preparePeerPushCredit(
const getPurseUrl = new URL(`purses/${pursePub}/deposit`, exchangeBaseUrl); const getPurseUrl = new URL(`purses/${pursePub}/deposit`, exchangeBaseUrl);
const purseHttpResp = await ws.http.get(getPurseUrl.href); const purseHttpResp = await ws.http.fetch(getPurseUrl.href);
const purseStatus = await readSuccessResponseJsonOrThrow( const purseStatus = await readSuccessResponseJsonOrThrow(
purseHttpResp, purseHttpResp,

View File

@ -358,7 +358,7 @@ export async function processRecoupGroup(
); );
logger.info(`querying reserve status for recoup via ${reserveUrl}`); logger.info(`querying reserve status for recoup via ${reserveUrl}`);
const resp = await ws.http.get(reserveUrl.href); const resp = await ws.http.fetch(reserveUrl.href);
const result = await readSuccessResponseJsonOrThrow( const result = await readSuccessResponseJsonOrThrow(
resp, resp,

View File

@ -161,7 +161,7 @@ export async function prepareTip(
res.merchantBaseUrl, res.merchantBaseUrl,
); );
logger.trace("checking tip status from", tipStatusUrl.href); logger.trace("checking tip status from", tipStatusUrl.href);
const merchantResp = await ws.http.get(tipStatusUrl.href); const merchantResp = await ws.http.fetch(tipStatusUrl.href);
const tipPickupStatus = await readSuccessResponseJsonOrThrow( const tipPickupStatus = await readSuccessResponseJsonOrThrow(
merchantResp, merchantResp,
codecForTipPickupGetResponse(), codecForTipPickupGetResponse(),

View File

@ -293,7 +293,7 @@ async function checkPayment(
): Promise<CheckPaymentResponse> { ): Promise<CheckPaymentResponse> {
const reqUrl = new URL(`private/orders/${orderId}`, merchantBackend.baseUrl); const reqUrl = new URL(`private/orders/${orderId}`, merchantBackend.baseUrl);
reqUrl.searchParams.set("order_id", orderId); reqUrl.searchParams.set("order_id", orderId);
const resp = await http.get(reqUrl.href, { const resp = await http.fetch(reqUrl.href, {
headers: getMerchantAuthHeader(merchantBackend), headers: getMerchantAuthHeader(merchantBackend),
}); });
return readSuccessResponseJsonOrThrow(resp, codecForCheckPaymentResponse()); return readSuccessResponseJsonOrThrow(resp, codecForCheckPaymentResponse());

View File

@ -554,7 +554,7 @@ export async function getBankWithdrawalInfo(
const configReqUrl = new URL("config", uriResult.bankIntegrationApiBaseUrl); const configReqUrl = new URL("config", uriResult.bankIntegrationApiBaseUrl);
const configResp = await http.get(configReqUrl.href); const configResp = await http.fetch(configReqUrl.href);
const config = await readSuccessResponseJsonOrThrow( const config = await readSuccessResponseJsonOrThrow(
configResp, configResp,
codecForTalerConfigResponse(), codecForTalerConfigResponse(),
@ -582,7 +582,7 @@ export async function getBankWithdrawalInfo(
logger.info(`bank withdrawal status URL: ${reqUrl.href}}`); logger.info(`bank withdrawal status URL: ${reqUrl.href}}`);
const resp = await http.get(reqUrl.href); const resp = await http.fetch(reqUrl.href);
const status = await readSuccessResponseJsonOrThrow( const status = await readSuccessResponseJsonOrThrow(
resp, resp,
codecForWithdrawOperationStatusResponse(), codecForWithdrawOperationStatusResponse(),
@ -2098,7 +2098,7 @@ async function processReserveBankStatus(
const bankStatusUrl = getBankStatusUrl(bankInfo.talerWithdrawUri); const bankStatusUrl = getBankStatusUrl(bankInfo.talerWithdrawUri);
const statusResp = await ws.http.get(bankStatusUrl, { const statusResp = await ws.http.fetch(bankStatusUrl, {
timeout: getReserveRequestTimeout(withdrawalGroup), timeout: getReserveRequestTimeout(withdrawalGroup),
}); });
const status = await readSuccessResponseJsonOrThrow( const status = await readSuccessResponseJsonOrThrow(