From 2339438e4892dd3afc11538f45442a714ab5732f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 10 May 2024 18:23:37 +0200 Subject: wallet-core: testing request for reserve history --- .../src/crypto/cryptoImplementation.ts | 35 ++++++++++++++++++++++ packages/taler-wallet-core/src/deposits.ts | 2 +- packages/taler-wallet-core/src/wallet-api-types.ts | 8 +++++ packages/taler-wallet-core/src/wallet.ts | 35 +++++++++++++++++++++- 4 files changed, 78 insertions(+), 2 deletions(-) (limited to 'packages/taler-wallet-core') diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index 0745d70c4..2a2958a71 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -214,6 +214,10 @@ export interface TalerCryptoInterface { signPurseCreation(req: SignPurseCreationRequest): Promise; + signReserveHistoryReq( + req: SignReserveHistoryReqRequest, + ): Promise; + signPurseDeposits( req: SignPurseDepositsRequest, ): Promise; @@ -438,6 +442,11 @@ export const nullCrypto: TalerCryptoInterface = { ): Promise { throw new Error("Function not implemented."); }, + signReserveHistoryReq: function ( + req: SignReserveHistoryReqRequest, + ): Promise { + throw new Error("Function not implemented."); + }, }; export type WithArg = X extends (req: infer T) => infer R @@ -475,6 +484,15 @@ export interface SignPurseCreationRequest { minAge: number; } +export interface SignReserveHistoryReqRequest { + reservePriv: string; + startOffset: number; +} + +export interface SignReserveHistoryReqResponse { + sig: string; +} + export interface SpendCoinDetails { coinPub: string; coinPriv: string; @@ -1730,6 +1748,23 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { sig: sigResp.sig, }; }, + async signReserveHistoryReq( + tci: TalerCryptoInterfaceR, + req: SignReserveHistoryReqRequest, + ): Promise { + const reserveHistoryBlob = buildSigPS( + TalerSignaturePurpose.WALLET_RESERVE_HISTORY, + ) + .put(bufferForUint64(req.startOffset)) + .build(); + const sigResp = await tci.eddsaSign(tci, { + msg: encodeCrock(reserveHistoryBlob), + priv: req.reservePriv, + }); + return { + sig: sigResp.sig, + }; + }, }; export interface EddsaSignRequest { diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts index dbba55247..c4cd98d73 100644 --- a/packages/taler-wallet-core/src/deposits.ts +++ b/packages/taler-wallet-core/src/deposits.ts @@ -776,7 +776,7 @@ async function processDepositGroupPendingTrack( { storeNames: ["coins"] }, async (tx) => { const coinRecord = await tx.coins.get(coinPub); - checkDbInvariant(!!coinRecord); + checkDbInvariant(!!coinRecord, `coin ${coinPub} not found in DB`); return coinRecord.exchangeBaseUrl; }, ); diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index ed882708c..9a8ea8470 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -270,6 +270,7 @@ export enum WalletApiOperation { TestingListTaskForTransaction = "testingListTasksForTransaction", TestingGetDenomStats = "testingGetDenomStats", TestingPing = "testingPing", + TestingGetReserveHistory = "testingGetReserveHistory", } // group: Initialization @@ -1187,6 +1188,12 @@ export type TestingPingOp = { response: EmptyObject; }; +export type TestingGetReserveHistoryOp = { + op: WalletApiOperation.TestingGetReserveHistory; + request: EmptyObject; + response: any; +}; + /** * Get stats about an exchange denomination. */ @@ -1329,6 +1336,7 @@ export type WalletOperations = { [WalletApiOperation.PrepareBankIntegratedWithdrawal]: PrepareBankIntegratedWithdrawalOp; [WalletApiOperation.ConfirmWithdrawal]: ConfirmWithdrawalOp; [WalletApiOperation.CanonicalizeBaseUrl]: CanonicalizeBaseUrlOp; + [WalletApiOperation.TestingGetReserveHistory]: TestingGetReserveHistoryOp; }; export type WalletCoreRequestType< diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index ea47ffad7..fe03dbf62 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -134,6 +134,7 @@ import { codecForSuspendTransaction, codecForTestPayArgs, codecForTestingGetDenomStatsRequest, + codecForTestingGetReserveHistoryRequest, codecForTestingListTasksForTransactionRequest, codecForTestingSetTimetravelRequest, codecForTransactionByIdRequest, @@ -154,7 +155,10 @@ import { setDangerousTimetravel, validateIban, } from "@gnu-taler/taler-util"; -import type { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; +import { + readSuccessResponseJsonOrThrow, + type HttpRequestLibrary, +} from "@gnu-taler/taler-util/http"; import { getUserAttentions, getUserAttentionsUnreadCount, @@ -909,6 +913,35 @@ async function dispatchRequestInternal( restrictAge: req.restrictAge, }); } + case WalletApiOperation.TestingGetReserveHistory: { + const req = codecForTestingGetReserveHistoryRequest().decode(payload); + const reserve = await wex.db.runReadOnlyTx( + { storeNames: ["reserves"] }, + async (tx) => { + return tx.reserves.indexes.byReservePub.get(req.reservePub); + }, + ); + if (!reserve) { + throw Error("no reserve pub found"); + } + const sigResp = await wex.cryptoApi.signReserveHistoryReq({ + reservePriv: reserve.reservePriv, + startOffset: 0, + }); + const exchangeBaseUrl = req.exchangeBaseUrl; + const url = new URL( + `reserves/${req.reservePub}/history`, + exchangeBaseUrl, + ); + const resp = await wex.http.fetch(url.href, { + headers: { ["Taler-Reserve-History-Signature"]: sigResp.sig }, + }); + const historyJson = await readSuccessResponseJsonOrThrow( + resp, + codecForAny(), + ); + return historyJson; + } case WalletApiOperation.AcceptManualWithdrawal: { const req = codecForAcceptManualWithdrawalRequest().decode(payload); const res = await createManualWithdrawal(wex, { -- cgit v1.2.3