From 64e78d03a117fffeb18e18154d9028a2532285a5 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 1 Sep 2023 10:52:15 +0200 Subject: wallet-core: implement and test stored backups --- packages/taler-wallet-core/src/db.ts | 53 +++++++++++------- packages/taler-wallet-core/src/host-impl.node.ts | 6 ++- packages/taler-wallet-core/src/wallet.ts | 68 ++++++++++++++++++++++-- 3 files changed, 103 insertions(+), 24 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index a642c0203..b9d86eb25 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -22,6 +22,7 @@ import { IDBDatabase, IDBFactory, IDBObjectStore, + IDBRequest, IDBTransaction, structuredEncapsulate, } from "@gnu-taler/idb-bridge"; @@ -59,6 +60,7 @@ import { Logger, CoinPublicKeyString, TalerPreciseTimestamp, + j2s, } from "@gnu-taler/taler-util"; import { DbAccess, @@ -117,7 +119,8 @@ export const TALER_WALLET_META_DB_NAME = "taler-wallet-meta"; /** * Stored backups, mainly created when manually importing a backup. */ -export const TALER_WALLET_STORED_BACKUPS_DB_NAME = "taler-wallet-stored-backups"; +export const TALER_WALLET_STORED_BACKUPS_DB_NAME = + "taler-wallet-stored-backups"; export const CURRENT_DB_CONFIG_KEY = "currentMainDbName"; @@ -2833,11 +2836,10 @@ export async function exportSingleDb( dbName, undefined, () => { - // May not happen, since we're not requesting a specific version - throw Error("unexpected version change"); + logger.info(`unexpected onversionchange in exportSingleDb of ${dbName}`); }, () => { - logger.info("unexpected onupgradeneeded"); + logger.info(`unexpected onupgradeneeded in exportSingleDb of ${dbName}`); }, ); @@ -2849,7 +2851,7 @@ export async function exportSingleDb( return new Promise((resolve, reject) => { const tx = myDb.transaction(Array.from(myDb.objectStoreNames)); tx.addEventListener("complete", () => { - myDb.close(); + //myDb.close(); resolve(singleDbDump); }); // tslint:disable-next-line:prefer-for-of @@ -2885,6 +2887,7 @@ export async function exportSingleDb( if (store.keyPath == null) { rec.key = structuredEncapsulate(cursor.key); } + storeDump.records.push(rec); cursor.continue(); } }); @@ -2913,21 +2916,22 @@ async function recoverFromDump( db: IDBDatabase, dbDump: DbDumpDatabase, ): Promise { - return new Promise((resolve, reject) => { - const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite"); - tx.addEventListener("complete", () => { - resolve(); - }); - for (let i = 0; i < db.objectStoreNames.length; i++) { - const name = db.objectStoreNames[i]; - const storeDump = dbDump.stores[name]; - if (!storeDump) continue; - for (let rec of storeDump.records) { - tx.objectStore(name).put(rec.value, rec.key); - } + const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite"); + const txProm = promiseFromTransaction(tx); + const storeNames = db.objectStoreNames; + for (let i = 0; i < storeNames.length; i++) { + const name = db.objectStoreNames[i]; + const storeDump = dbDump.stores[name]; + if (!storeDump) continue; + await promiseFromRequest(tx.objectStore(name).clear()); + logger.info(`importing ${storeDump.records.length} records into ${name}`); + for (let rec of storeDump.records) { + await promiseFromRequest(tx.objectStore(name).put(rec.value, rec.key)); + logger.info("importing record done"); } - tx.commit(); - }); + } + tx.commit(); + return await txProm; } function checkDbDump(x: any): x is DbDump { @@ -3184,6 +3188,17 @@ function promiseFromTransaction(transaction: IDBTransaction): Promise { }); } +export function promiseFromRequest(request: IDBRequest): Promise { + return new Promise((resolve, reject) => { + request.onsuccess = () => { + resolve(request.result); + }; + request.onerror = () => { + reject(request.error); + }; + }); +} + /** * Purge all data in the given database. */ diff --git a/packages/taler-wallet-core/src/host-impl.node.ts b/packages/taler-wallet-core/src/host-impl.node.ts index 0b6539306..0626b9254 100644 --- a/packages/taler-wallet-core/src/host-impl.node.ts +++ b/packages/taler-wallet-core/src/host-impl.node.ts @@ -52,7 +52,6 @@ interface MakeDbResult { async function makeFileDb( args: DefaultNodeWalletArgs = {}, ): Promise { - BridgeIDBFactory.enableTracing = false; const myBackend = new MemoryBackend(); myBackend.enableTracing = false; const storagePath = args.persistentStoragePath; @@ -141,7 +140,10 @@ export async function createNativeWalletHost2( let dbResp: MakeDbResult; - if (args.persistentStoragePath &&args.persistentStoragePath.endsWith(".json")) { + if ( + args.persistentStoragePath && + args.persistentStoragePath.endsWith(".json") + ) { logger.info("using legacy file-based DB backend"); dbResp = await makeFileDb(args); } else { diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 626409dd6..5666d67e0 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -121,6 +121,11 @@ import { GetCurrencyInfoResponse, codecForGetCurrencyInfoRequest, CreateStoredBackupResponse, + StoredBackupList, + codecForDeleteStoredBackupRequest, + DeleteStoredBackupRequest, + RecoverStoredBackupRequest, + codecForRecoverStoredBackupRequest, } from "@gnu-taler/taler-util"; import { HttpRequestLibrary, @@ -1041,6 +1046,57 @@ async function createStoredBackup( }; } +async function listStoredBackups( + ws: InternalWalletState, +): Promise { + const storedBackups: StoredBackupList = { + storedBackups: [], + }; + const backupsDb = await openStoredBackupsDatabase(ws.idb); + await backupsDb.mktxAll().runReadWrite(async (tx) => { + await tx.backupMeta.iter().forEach((x) => { + storedBackups.storedBackups.push({ + name: x.name, + }); + }); + }); + return storedBackups; +} + +async function deleteStoredBackup( + ws: InternalWalletState, + req: DeleteStoredBackupRequest, +): Promise { + const backupsDb = await openStoredBackupsDatabase(ws.idb); + await backupsDb.mktxAll().runReadWrite(async (tx) => { + await tx.backupData.delete(req.name); + await tx.backupMeta.delete(req.name); + }); +} + +async function recoverStoredBackup( + ws: InternalWalletState, + req: RecoverStoredBackupRequest, +): Promise { + logger.info(`Recovering stored backup ${req.name}`); + const { name } = req; + const backupsDb = await openStoredBackupsDatabase(ws.idb); + const bd = await backupsDb.mktxAll().runReadWrite(async (tx) => { + const backupMeta = tx.backupMeta.get(name); + if (!backupMeta) { + throw Error("backup not found"); + } + const backupData = await tx.backupData.get(name); + if (!backupData) { + throw Error("no backup data (DB corrupt)"); + } + return backupData; + }); + logger.info(`backup found, now importing`); + await importDb(ws.db.idbHandle(), bd); + logger.info(`import done`); +} + /** * Implementation of the "wallet-core" API. */ @@ -1059,12 +1115,18 @@ async function dispatchRequestInternal( switch (operation) { case WalletApiOperation.CreateStoredBackup: return createStoredBackup(ws); - case WalletApiOperation.DeleteStoredBackup: + case WalletApiOperation.DeleteStoredBackup: { + const req = codecForDeleteStoredBackupRequest().decode(payload); + await deleteStoredBackup(ws, req); return {}; + } case WalletApiOperation.ListStoredBackups: + return listStoredBackups(ws); + case WalletApiOperation.RecoverStoredBackup: { + const req = codecForRecoverStoredBackupRequest().decode(payload); + await recoverStoredBackup(ws, req); return {}; - case WalletApiOperation.RecoverStoredBackup: - return {}; + } case WalletApiOperation.InitWallet: { logger.trace("initializing wallet"); ws.initCalled = true; -- cgit v1.2.3 From a60a1d867cfe6a12f1e6fadfa037f022e9385107 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 5 Sep 2023 10:46:06 +0200 Subject: harness: remove deprecated testing APIs --- packages/taler-harness/src/env-full.ts | 4 +- packages/taler-harness/src/harness/harness.ts | 103 +++++-- packages/taler-harness/src/harness/helpers.ts | 326 +++------------------ .../test-age-restrictions-merchant.ts | 127 +++++--- .../src/integrationtests/test-bank-api.ts | 4 +- .../src/integrationtests/test-clause-schnorr.ts | 32 +- .../integrationtests/test-exchange-management.ts | 4 +- .../integrationtests/test-exchange-timetravel.ts | 63 ++-- .../src/integrationtests/test-fee-regression.ts | 2 +- .../taler-harness/src/integrationtests/test-kyc.ts | 4 +- .../src/integrationtests/test-libeufin-basic.ts | 32 +- .../test-merchant-exchange-confusion.ts | 24 +- .../test-merchant-instances-delete.ts | 4 +- .../integrationtests/test-merchant-instances.ts | 4 +- .../integrationtests/test-merchant-refund-api.ts | 49 ++-- .../test-merchant-spec-public-orders.ts | 61 ++-- .../src/integrationtests/test-pay-paid.ts | 22 +- .../src/integrationtests/test-payment-abort.ts | 29 +- .../src/integrationtests/test-payment-fault.ts | 2 +- .../src/integrationtests/test-payment-multiple.ts | 27 +- .../src/integrationtests/test-payment-transient.ts | 15 +- .../src/integrationtests/test-refund-gone.ts | 34 ++- .../src/integrationtests/test-revocation.ts | 80 +++-- .../test-timetravel-autorefresh.ts | 66 ++--- .../integrationtests/test-timetravel-withdraw.ts | 40 ++- .../integrationtests/test-wallet-backup-basic.ts | 29 +- .../test-wallet-backup-doublespend.ts | 47 +-- .../integrationtests/test-wallet-notifications.ts | 2 +- .../src/integrationtests/test-wallettesting.ts | 2 +- .../integrationtests/test-withdrawal-abort-bank.ts | 20 +- .../src/integrationtests/test-withdrawal-fees.ts | 24 +- .../src/integrationtests/testrunner.ts | 2 + packages/taler-util/src/merchant-api-types.ts | 35 +++ packages/taler-util/src/time.ts | 14 + packages/taler-util/src/wallet-types.ts | 10 + packages/taler-wallet-core/src/wallet-api-types.ts | 12 + packages/taler-wallet-core/src/wallet.ts | 7 + 37 files changed, 673 insertions(+), 689 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-harness/src/env-full.ts b/packages/taler-harness/src/env-full.ts index 3a684db0b..210d38e32 100644 --- a/packages/taler-harness/src/env-full.ts +++ b/packages/taler-harness/src/env-full.ts @@ -79,7 +79,7 @@ export async function runEnvFull(t: GlobalTestState): Promise { await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -88,7 +88,7 @@ export async function runEnvFull(t: GlobalTestState): Promise { ), }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 337f3ca44..b5197afd7 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -56,6 +56,7 @@ import { TippingReserveStatus, WalletNotification, codecForAny, + AccountAddDetails, } from "@gnu-taler/taler-util"; import { createPlatformHttpLib, @@ -760,19 +761,19 @@ export class ExchangeService implements ExchangeServiceInterface { return new ExchangeService(gc, ec, cfgFilename, keyPair); } - private currentTimetravel: Duration | undefined; + private currentTimetravelOffsetMs: number | undefined; - setTimetravel(t: Duration | undefined): void { + setTimetravel(t: number | undefined): void { if (this.isRunning()) { throw Error("can't set time travel while the exchange is running"); } - this.currentTimetravel = t; + this.currentTimetravelOffsetMs = t; } private get timetravelArg(): string | undefined { - if (this.currentTimetravel && this.currentTimetravel.d_ms !== "forever") { + if (this.currentTimetravelOffsetMs != null) { // Convert to microseconds - return `--timetravel=+${this.currentTimetravel.d_ms * 1000}`; + return `--timetravel=+${this.currentTimetravelOffsetMs * 1000}`; } return undefined; } @@ -1360,12 +1361,26 @@ export const harnessHttpLib = createPlatformHttpLib({ }); export class MerchantApiClient { - constructor( - private baseUrl: string, - public readonly auth: MerchantAuthConfiguration, - ) {} + /** + * Base URL for the particular instance that this merchant API client + * is for. + */ + private baseUrl: string; - httpClient = createPlatformHttpLib({ allowHttp: true, enableThrottling: false }); + readonly auth: MerchantAuthConfiguration; + + constructor(baseUrl: string, auth?: MerchantAuthConfiguration) { + this.baseUrl = baseUrl; + + this.auth = auth ?? { + method: "external", + }; + } + + httpClient = createPlatformHttpLib({ + allowHttp: true, + enableThrottling: false, + }); async changeAuth(auth: MerchantAuthConfiguration): Promise { const url = new URL("private/auth", this.baseUrl); @@ -1463,7 +1478,38 @@ export class MerchantApiClient { } } - makeAuthHeader(): Record { + async createOrder( + req: MerchantPostOrderRequest, + ): Promise { + let url = new URL("private/orders", this.baseUrl); + const resp = await harnessHttpLib.fetch(url.href, { + method: "POST", + body: req, + headers: this.makeAuthHeader(), + }); + return readSuccessResponseJsonOrThrow( + resp, + codecForMerchantPostOrderResponse(), + ); + } + + async queryPrivateOrderStatus( + query: PrivateOrderStatusQuery, + ): Promise { + const reqUrl = new URL(`private/orders/${query.orderId}`, this.baseUrl); + if (query.sessionId) { + reqUrl.searchParams.set("session_id", query.sessionId); + } + const resp = await harnessHttpLib.fetch(reqUrl.href, { + headers: this.makeAuthHeader(), + }); + return readSuccessResponseJsonOrThrow( + resp, + codecForMerchantOrderPrivateStatusResponse(), + ); + } + + private makeAuthHeader(): Record { switch (this.auth.method) { case "external": return {}; @@ -1633,23 +1679,23 @@ export class MerchantService implements MerchantServiceInterface { private configFilename: string, ) {} - private currentTimetravel: Duration | undefined; + private currentTimetravelOffsetMs: number | undefined; private isRunning(): boolean { return !!this.proc; } - setTimetravel(t: Duration | undefined): void { + setTimetravel(t: number | undefined): void { if (this.isRunning()) { throw Error("can't set time travel while the exchange is running"); } - this.currentTimetravel = t; + this.currentTimetravelOffsetMs = t; } private get timetravelArg(): string | undefined { - if (this.currentTimetravel && this.currentTimetravel.d_ms !== "forever") { + if (this.currentTimetravelOffsetMs != null) { // Convert to microseconds - return `--timetravel=+${this.currentTimetravel.d_ms * 1000}`; + return `--timetravel=+${this.currentTimetravelOffsetMs * 1000}`; } return undefined; } @@ -1756,7 +1802,7 @@ export class MerchantService implements MerchantServiceInterface { } async addDefaultInstance(): Promise { - return await this.addInstance({ + return await this.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -1766,7 +1812,10 @@ export class MerchantService implements MerchantServiceInterface { }); } - async addInstance( + /** + * Add an instance together with a wire account. + */ + async addInstanceWithWireAccount( instanceConfig: PartialMerchantInstanceConfig, ): Promise { if (!this.proc) { @@ -1798,12 +1847,20 @@ export class MerchantService implements MerchantServiceInterface { instanceConfig.defaultPayDelay ?? Duration.toTalerProtocolDuration(Duration.getForever()), }; - const httpLib = createPlatformHttpLib({ - allowHttp: true, - enableThrottling: false, - }); - const resp = await httpLib.fetch(url, { method: "POST", body }); + const resp = await harnessHttpLib.fetch(url, { method: "POST", body }); await expectSuccessResponseOrThrow(resp); + + const accountCreateUrl = `http://localhost:${this.merchantConfig.httpPort}/instances/${instanceConfig.id}/private/accounts`; + for (const paytoUri of instanceConfig.paytoUris) { + const accountReq: AccountAddDetails = { + payto_uri: paytoUri, + }; + const acctResp = await harnessHttpLib.fetch(accountCreateUrl, { + method: "POST", + body: accountReq, + }); + await expectSuccessResponseOrThrow(acctResp); + } } makeInstanceBaseUrl(instanceName?: string): string { diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index d1d0ea104..39d411a46 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -53,6 +53,7 @@ import { FakebankService, getPayto, GlobalTestState, + MerchantApiClient, MerchantPrivateApi, MerchantService, MerchantServiceInterface, @@ -107,114 +108,6 @@ export interface EnvOptions { additionalBankConfig?(b: BankService): void; } -/** - * Run a test case with a simple TESTKUDOS Taler environment, consisting - * of one exchange, one bank and one merchant. - * - * @deprecated use {@link createSimpleTestkudosEnvironmentV2} instead - */ -export async function createSimpleTestkudosEnvironment( - t: GlobalTestState, - coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")), - opts: EnvOptions = {}, -): Promise { - const db = await setupDb(t); - - const bank = await BankService.create(t, { - allowRegistrations: true, - currency: "TESTKUDOS", - database: db.connStr, - httpPort: 8082, - }); - - const exchange = ExchangeService.create(t, { - name: "testexchange-1", - currency: "TESTKUDOS", - httpPort: 8081, - database: db.connStr, - }); - - const merchant = await MerchantService.create(t, { - name: "testmerchant-1", - currency: "TESTKUDOS", - httpPort: 8083, - database: db.connStr, - }); - - const exchangeBankAccount = await bank.createExchangeAccount( - "myexchange", - "x", - ); - await exchange.addBankAccount("1", exchangeBankAccount); - - bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri); - - await bank.start(); - - await bank.pingUntilAvailable(); - - const ageMaskSpec = opts.ageMaskSpec; - - if (ageMaskSpec) { - exchange.enableAgeRestrictions(ageMaskSpec); - // Enable age restriction for all coins. - exchange.addCoinConfigList( - coinConfig.map((x) => ({ - ...x, - name: `${x.name}-age`, - ageRestricted: true, - })), - ); - // For mixed age restrictions, we also offer coins without age restrictions - if (opts.mixedAgeRestriction) { - exchange.addCoinConfigList( - coinConfig.map((x) => ({ ...x, ageRestricted: false })), - ); - } - } else { - exchange.addCoinConfigList(coinConfig); - } - - await exchange.start(); - await exchange.pingUntilAvailable(); - - merchant.addExchange(exchange); - - await merchant.start(); - await merchant.pingUntilAvailable(); - - await merchant.addInstance({ - id: "default", - name: "Default Instance", - paytoUris: [getPayto("merchant-default")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); - - await merchant.addInstance({ - id: "minst1", - name: "minst1", - paytoUris: [getPayto("minst1")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); - - console.log("setup done!"); - - const wallet = new WalletCli(t); - - return { - commonDb: db, - exchange, - merchant, - wallet, - bank, - exchangeBankAccount, - }; -} - export function getSharedTestDir(): string { return `/tmp/taler-harness@${process.env.USER}`; } @@ -344,7 +237,7 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { await merchant.pingUntilAvailable(); if (!prevSetupDone) { - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -353,7 +246,7 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { ), }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -476,7 +369,7 @@ export async function createSimpleTestkudosEnvironmentV2( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -485,7 +378,7 @@ export async function createSimpleTestkudosEnvironmentV2( ), }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -554,7 +447,7 @@ export interface FaultyMerchantTestEnvironment { exchangeBankAccount: HarnessExchangeBankAccount; merchant: MerchantService; faultyMerchant: FaultInjectedMerchantService; - wallet: WalletCli; + walletClient: WalletClient; } /** @@ -620,13 +513,13 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -634,13 +527,15 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( console.log("setup done!"); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "default", + }); return { commonDb: db, exchange, merchant, - wallet, + walletClient, bank, exchangeBankAccount, faultyMerchant, @@ -648,51 +543,6 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( }; } -/** - * Start withdrawing into the wallet. - * - * Only starts the operation, does not wait for it to finish. - */ -export async function startWithdrawViaBank( - t: GlobalTestState, - p: { - wallet: WalletCli; - bank: BankService; - exchange: ExchangeServiceInterface; - amount: AmountString; - restrictAge?: number; - }, -): Promise { - const { wallet, bank, exchange, amount } = p; - - const user = await BankApi.createRandomBankUser(bank); - const wop = await BankAccessApi.createWithdrawalOperation(bank, user, amount); - - // Hand it to the wallet - - await wallet.client.call(WalletApiOperation.GetWithdrawalDetailsForUri, { - talerWithdrawUri: wop.taler_withdraw_uri, - restrictAge: p.restrictAge, - }); - - await wallet.runPending(); - - // Withdraw (AKA select) - - await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { - exchangeBaseUrl: exchange.baseUrl, - talerWithdrawUri: wop.taler_withdraw_uri, - restrictAge: p.restrictAge, - }); - - // Confirm it - - await BankApi.confirmWithdrawalOperation(bank, user, wop); - - // We do *not* call runPending / runUntilDone on the wallet here. - // Some tests rely on the final withdraw failing. -} - export interface WithdrawViaBankResult { withdrawalFinishedCond: Promise; } @@ -751,131 +601,35 @@ export async function withdrawViaBankV2( }; } -/** - * Withdraw balance. - * - * @deprecated use {@link withdrawViaBankV2 instead} - */ -export async function withdrawViaBank( - t: GlobalTestState, - p: { - wallet: WalletCli; - bank: BankService; - exchange: ExchangeServiceInterface; - amount: AmountString; - restrictAge?: number; - }, -): Promise { - const { wallet } = p; - - await startWithdrawViaBank(t, p); - - await wallet.runUntilDone(); - - // Check balance - - await wallet.client.call(WalletApiOperation.GetBalances, {}); -} - -export async function applyTimeTravel( - timetravelDuration: Duration, +export async function applyTimeTravelV2( + timetravelOffsetMs: number, s: { exchange?: ExchangeService; merchant?: MerchantService; - wallet?: WalletCli; + walletClient?: WalletClient; }, ): Promise { if (s.exchange) { await s.exchange.stop(); - s.exchange.setTimetravel(timetravelDuration); + s.exchange.setTimetravel(timetravelOffsetMs); await s.exchange.start(); await s.exchange.pingUntilAvailable(); } if (s.merchant) { await s.merchant.stop(); - s.merchant.setTimetravel(timetravelDuration); + s.merchant.setTimetravel(timetravelOffsetMs); await s.merchant.start(); await s.merchant.pingUntilAvailable(); } - if (s.wallet) { - s.wallet.setTimetravel(timetravelDuration); + if (s.walletClient) { + s.walletClient.call(WalletApiOperation.TestingSetTimetravel, { + offsetMs: timetravelOffsetMs, + }); } } -/** - * Make a simple payment and check that it succeeded. - * - * @deprecated - */ -export async function makeTestPayment( - t: GlobalTestState, - args: { - merchant: MerchantServiceInterface; - wallet: WalletCli; - order: Partial; - instance?: string; - }, - auth: WithAuthorization = {}, -): Promise { - // Set up order. - - const { wallet, merchant } = args; - const instance = args.instance ?? "default"; - - const orderResp = await MerchantPrivateApi.createOrder( - merchant, - instance, - { - order: args.order, - }, - auth, - ); - - let orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus( - merchant, - { - orderId: orderResp.order_id, - }, - auth, - ); - - t.assertTrue(orderStatus.order_status === "unpaid"); - - // Make wallet pay for the order - - const preparePayResult = await wallet.client.call( - WalletApiOperation.PreparePayForUri, - { - talerPayUri: orderStatus.taler_pay_uri, - }, - ); - - t.assertTrue( - preparePayResult.status === PreparePayResultType.PaymentPossible, - ); - - const r2 = await wallet.client.call(WalletApiOperation.ConfirmPay, { - proposalId: preparePayResult.proposalId, - }); - - t.assertTrue(r2.type === ConfirmPayResultType.Done); - - // Check if payment was successful. - - orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus( - merchant, - { - orderId: orderResp.order_id, - instance, - }, - auth, - ); - - t.assertTrue(orderStatus.order_status === "paid"); -} - /** * Make a simple payment and check that it succeeded. */ @@ -891,25 +645,19 @@ export async function makeTestPaymentV2( ): Promise { // Set up order. - const { walletClient, merchant } = args; - const instance = args.instance ?? "default"; + const { walletClient, merchant, instance } = args; - const orderResp = await MerchantPrivateApi.createOrder( - merchant, - instance, - { - order: args.order, - }, - auth, + const merchantClient = new MerchantApiClient( + merchant.makeInstanceBaseUrl(instance), ); - let orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus( - merchant, - { - orderId: orderResp.order_id, - }, - auth, - ); + const orderResp = await merchantClient.createOrder({ + order: args.order, + }); + + let orderStatus = await merchantClient.queryPrivateOrderStatus({ + orderId: orderResp.order_id, + }); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -934,14 +682,10 @@ export async function makeTestPaymentV2( // Check if payment was successful. - orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus( - merchant, - { - orderId: orderResp.order_id, - instance, - }, - auth, - ); + orderStatus = await merchantClient.queryPrivateOrderStatus({ + orderId: orderResp.order_id, + instance, + }); t.assertTrue(orderStatus.order_status === "paid"); } diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts index 919097deb..5ee35a377 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -31,9 +31,10 @@ import { WalletCli, } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - withdrawViaBank, - makeTestPayment, + createSimpleTestkudosEnvironmentV2, + createWalletDaemonWithClient, + makeTestPaymentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; /** @@ -43,12 +44,12 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { // Set up test environment const { - wallet: walletOne, + walletClient: walletClientOne, bank, exchange, merchant, exchangeBankAccount, - } = await createSimpleTestkudosEnvironment( + } = await createSimpleTestkudosEnvironmentV2( t, defaultCoinConfig.map((x) => x("TESTKUDOS")), { @@ -63,14 +64,26 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { }, ); - const walletTwo = new WalletCli(t, "walletTwo"); - const walletThree = new WalletCli(t, "walletThree"); + const { walletClient: walletClientTwo } = await createWalletDaemonWithClient( + t, + { + name: "w2", + }, + ); + + const { walletClient: walletClientThree } = + await createWalletDaemonWithClient(t, { + name: "w3", + }); { - const walletZero = new WalletCli(t, "walletZero"); + const { walletClient: walletClientZero } = + await createWalletDaemonWithClient(t, { + name: "w0", + }); - await withdrawViaBank(t, { - wallet: walletZero, + await withdrawViaBankV2(t, { + walletClient: walletClientZero, bank, exchange, amount: "TESTKUDOS:20", @@ -84,15 +97,22 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPayment(t, { wallet: walletZero, merchant, order }); - await walletZero.runUntilDone(); + await makeTestPaymentV2(t, { + walletClient: walletClientZero, + merchant, + order, + }); + await walletClientZero.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } { - const wallet = walletOne; + const walletClient = walletClientOne; - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange, amount: "TESTKUDOS:20", @@ -106,15 +126,18 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPayment(t, { wallet, merchant, order }); - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order }); + await walletClient.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } { - const wallet = walletTwo; + const walletClient = walletClientTwo; - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange, amount: "TESTKUDOS:20", @@ -127,15 +150,18 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPayment(t, { wallet, merchant, order }); - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order }); + await walletClient.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } { - const wallet = walletThree; + const walletClient = walletClientThree; - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange, amount: "TESTKUDOS:20", @@ -148,20 +174,21 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPayment(t, { wallet, merchant, order }); - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order }); + await walletClient.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } // Pay with coin from tipping { const mbu = await BankApi.createRandomBankUser(bank); - const tipReserveResp = await merchantClient.createTippingReserve( - { - exchange_url: exchange.baseUrl, - initial_balance: "TESTKUDOS:10", - wire_method: getWireMethodForTest(), - }, - ); + const tipReserveResp = await merchantClient.createTippingReserve({ + exchange_url: exchange.baseUrl, + initial_balance: "TESTKUDOS:10", + wire_method: getWireMethodForTest(), + }); t.assertDeepEqual( tipReserveResp.accounts[0].payto_uri, @@ -189,17 +216,26 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { next_url: "https://example.com/after-tip", }); - const walletTipping = new WalletCli(t, "age-tipping"); + const { walletClient: walletClientTipping } = + await createWalletDaemonWithClient(t, { + name: "age-tipping", + }); - const ptr = await walletTipping.client.call(WalletApiOperation.PrepareReward, { - talerRewardUri: tip.taler_reward_uri, - }); + const ptr = await walletClientTipping.call( + WalletApiOperation.PrepareReward, + { + talerRewardUri: tip.taler_reward_uri, + }, + ); - await walletTipping.client.call(WalletApiOperation.AcceptReward, { + await walletClientTipping.call(WalletApiOperation.AcceptReward, { walletRewardId: ptr.walletRewardId, }); - await walletTipping.runUntilDone(); + await walletClientTipping.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); const order = { summary: "Buy me!", @@ -208,8 +244,15 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPayment(t, { wallet: walletTipping, merchant, order }); - await walletTipping.runUntilDone(); + await makeTestPaymentV2(t, { + walletClient: walletClientTipping, + merchant, + order, + }); + await walletClientTipping.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } } diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index 9ac16980b..041b10cc0 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -85,13 +85,13 @@ export async function runBankApiTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); await merchant.addDefaultInstance(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], diff --git a/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts b/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts index bf42dc4c6..9a839b677 100644 --- a/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts +++ b/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts @@ -17,12 +17,13 @@ /** * Imports. */ +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { GlobalTestState } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - withdrawViaBank, - makeTestPayment, + createSimpleTestkudosEnvironmentV2, + makeTestPaymentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; /** @@ -53,12 +54,18 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { name: "rsa_dummy", }); - const { wallet, bank, exchange, merchant } = - await createSimpleTestkudosEnvironment(t, coinConfig); + const { walletClient, bank, exchange, merchant } = + await createSimpleTestkudosEnvironmentV2(t, coinConfig); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:20", + }); + await wres.withdrawalFinishedCond; const order = { summary: "Buy me!", @@ -66,8 +73,8 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPayment(t, { wallet, merchant, order }); - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order }); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Test JSON normalization of contract terms: Does the wallet // agree with the merchant? @@ -77,8 +84,8 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPayment(t, { wallet, merchant, order: order2 }); - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order: order2 }); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Test JSON normalization of contract terms: Does the wallet // agree with the merchant? @@ -88,9 +95,8 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPayment(t, { wallet, merchant, order: order3 }); - - await wallet.runUntilDone(); + await makeTestPaymentV2(t, { walletClient, merchant, order: order3 }); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } runClauseSchnorrTest.suites = ["experimental-wallet"]; diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index c67f861e1..718cee0d7 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -105,13 +105,13 @@ export async function runExchangeManagementTest( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], diff --git a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts index 5ae97c3da..401cc4ff2 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts @@ -41,7 +41,11 @@ import { setupDb, WalletCli, } from "../harness/harness.js"; -import { withdrawViaBank } from "../harness/helpers.js"; +import { + applyTimeTravelV2, + createWalletDaemonWithClient, + withdrawViaBankV2, +} from "../harness/helpers.js"; const logger = new Logger("test-exchange-timetravel.ts"); @@ -89,34 +93,6 @@ function getDenomInfoFromKeys(ek: ExchangeKeysJson): DenomInfo[] { return denomInfos; } -async function applyTimeTravel( - timetravelDuration: Duration, - s: { - exchange?: ExchangeService; - merchant?: MerchantService; - wallet?: WalletCli; - }, -): Promise { - if (s.exchange) { - await s.exchange.stop(); - s.exchange.setTimetravel(timetravelDuration); - await s.exchange.start(); - await s.exchange.pingUntilAvailable(); - } - - if (s.merchant) { - await s.merchant.stop(); - s.merchant.setTimetravel(timetravelDuration); - await s.merchant.start(); - await s.merchant.pingUntilAvailable(); - } - - if (s.wallet) { - console.log("setting wallet time travel to", timetravelDuration); - s.wallet.setTimetravel(timetravelDuration); - } -} - const http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false, @@ -173,13 +149,13 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -187,11 +163,19 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { console.log("setup done!"); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "default", + }); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:15", + }); + await wres.withdrawalFinishedCond; const keysResp1 = await http.fetch(exchange.baseUrl + "keys"); const keys1 = await readSuccessResponseJsonOrThrow( @@ -206,11 +190,14 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { // Travel into the future, the deposit expiration is two years // into the future. console.log("applying first time travel"); - await applyTimeTravel(durationFromSpec({ days: 400 }), { - wallet, - exchange, - merchant, - }); + await applyTimeTravelV2( + Duration.toMilliseconds(durationFromSpec({ days: 400 })), + { + walletClient, + exchange, + merchant, + }, + ); const keysResp2 = await http.fetch(exchange.baseUrl + "keys"); const keys2 = await readSuccessResponseJsonOrThrow( diff --git a/packages/taler-harness/src/integrationtests/test-fee-regression.ts b/packages/taler-harness/src/integrationtests/test-fee-regression.ts index e0dc4bc3b..2d84b3a7c 100644 --- a/packages/taler-harness/src/integrationtests/test-fee-regression.ts +++ b/packages/taler-harness/src/integrationtests/test-fee-regression.ts @@ -139,7 +139,7 @@ export async function createMyTestkudosEnvironment( await merchant.pingUntilAvailable(); await merchant.addDefaultInstance(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 0fe24d708..34ad46e03 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -162,7 +162,7 @@ export async function createKycTestkudosEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -171,7 +171,7 @@ export async function createKycTestkudosEnvironment( ), }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts index f03b63f50..5d5beb06e 100644 --- a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts +++ b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts @@ -34,14 +34,18 @@ import { MerchantService, setupDb, WalletCli, + WalletClient, } from "../harness/harness.js"; -import { makeTestPayment } from "../harness/helpers.js"; import { LibeufinNexusApi, LibeufinNexusService, LibeufinSandboxApi, LibeufinSandboxService, } from "../harness/libeufin.js"; +import { + createWalletDaemonWithClient, + makeTestPaymentV2, +} from "../harness/helpers.js"; const exchangeIban = "DE71500105179674997361"; const customerIban = "DE84500105176881385584"; @@ -53,7 +57,7 @@ export interface LibeufinTestEnvironment { exchange: ExchangeService; exchangeBankAccount: HarnessExchangeBankAccount; merchant: MerchantService; - wallet: WalletCli; + walletClient: WalletClient; libeufinSandbox: LibeufinSandboxService; libeufinNexus: LibeufinNexusService; } @@ -202,7 +206,7 @@ export async function createLibeufinTestEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [`payto://iban/${merchantIban}?receiver-name=Merchant`], @@ -213,13 +217,15 @@ export async function createLibeufinTestEnvironment( console.log("setup done!"); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "default ", + }); return { commonDb: db, exchange, merchant, - wallet, + walletClient, exchangeBankAccount, libeufinNexus, libeufinSandbox, @@ -232,14 +238,14 @@ export async function createLibeufinTestEnvironment( export async function runLibeufinBasicTest(t: GlobalTestState) { // Set up test environment - const { wallet, exchange, merchant, libeufinSandbox, libeufinNexus } = + const { walletClient, exchange, merchant, libeufinSandbox, libeufinNexus } = await createLibeufinTestEnvironment(t); - await wallet.client.call(WalletApiOperation.AddExchange, { + await walletClient.call(WalletApiOperation.AddExchange, { exchangeBaseUrl: exchange.baseUrl, }); - const wr = await wallet.client.call( + const wr = await walletClient.call( WalletApiOperation.AcceptManualWithdrawal, { exchangeBaseUrl: exchange.baseUrl, @@ -265,9 +271,9 @@ export async function runLibeufinBasicTest(t: GlobalTestState) { await exchange.runWirewatchOnce(); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - const bal = await wallet.client.call(WalletApiOperation.GetBalances, {}); + const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); console.log("balances", JSON.stringify(bal, undefined, 2)); t.assertAmountEquals(bal.balances[0].available, "EUR:14.7"); @@ -275,10 +281,12 @@ export async function runLibeufinBasicTest(t: GlobalTestState) { summary: "Buy me!", amount: "EUR:5", fulfillment_url: "taler://fulfillment-success/thx", - wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now()), + wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.now(), + ), }; - await makeTestPayment(t, { wallet, merchant, order }); + await makeTestPaymentV2(t, { walletClient, merchant, order }); await exchange.runAggregatorOnce(); await exchange.runTransferOnce(); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts b/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts index e18cd7a0f..2a8ae39d8 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts @@ -41,10 +41,10 @@ import { WalletCli, } from "../harness/harness.js"; import { + createWalletDaemonWithClient, FaultyMerchantTestEnvironment, - withdrawViaBank, + withdrawViaBankV2, } from "../harness/helpers.js"; -import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; /** * Run a test case with a simple TESTKUDOS Taler environment, consisting @@ -110,13 +110,13 @@ export async function createConfusedMerchantTestkudosEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -124,13 +124,15 @@ export async function createConfusedMerchantTestkudosEnvironment( console.log("setup done!"); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "default", + }); return { commonDb: db, exchange, merchant, - wallet, + walletClient, bank, exchangeBankAccount, faultyMerchant, @@ -145,13 +147,13 @@ export async function createConfusedMerchantTestkudosEnvironment( export async function runMerchantExchangeConfusionTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, faultyExchange, faultyMerchant } = + const { walletClient, bank, faultyExchange, faultyMerchant } = await createConfusedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange: faultyExchange, amount: "TESTKUDOS:20", @@ -200,7 +202,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) { console.log(pubUnpaidStatus); - let preparePayResp = await wallet.client.call( + let preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri: pubUnpaidStatus.taler_pay_uri, @@ -231,7 +233,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) { await publicOrderStatusResp.json(), ); - const confirmPayRes = await wallet.client.call( + const confirmPayRes = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId: proposalId, diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts index e6e5bff76..1c99dda76 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts @@ -75,7 +75,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { } // Add an instance, no auth! - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -85,7 +85,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { }); // Add an instance, no auth! - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "myinst", name: "Second Instance", paytoUris: [getPayto("merchant-default")], diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts index f7d89c543..167c54cb4 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts @@ -77,7 +77,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { } // Add an instance, no auth! - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], @@ -87,7 +87,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { }); // Add an instance, no auth! - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "myinst", name: "Second Instance", paytoUris: [getPayto("merchant-default")], diff --git a/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts b/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts index 8efac1fc1..bc53cb533 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts @@ -25,10 +25,11 @@ import { WalletCli, ExchangeServiceInterface, harnessHttpLib, + WalletClient, } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - withdrawViaBank, + createSimpleTestkudosEnvironmentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; import { URL, @@ -46,11 +47,11 @@ async function testRefundApiWithFulfillmentUrl( env: { merchant: MerchantServiceInterface; bank: BankServiceHandle; - wallet: WalletCli; + walletClient: WalletClient; exchange: ExchangeServiceInterface; }, ): Promise { - const { wallet, bank, exchange, merchant } = env; + const { walletClient, bank, exchange, merchant } = env; // Set up order. const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { @@ -75,7 +76,7 @@ async function testRefundApiWithFulfillmentUrl( // Make wallet pay for the order - let preparePayResult = await wallet.client.call( + let preparePayResult = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -86,7 +87,7 @@ async function testRefundApiWithFulfillmentUrl( preparePayResult.status === PreparePayResultType.PaymentPossible, ); - await wallet.client.call(WalletApiOperation.ConfirmPay, { + await walletClient.call(WalletApiOperation.ConfirmPay, { proposalId: preparePayResult.proposalId, }); @@ -98,7 +99,7 @@ async function testRefundApiWithFulfillmentUrl( t.assertTrue(orderStatus.order_status === "paid"); - preparePayResult = await wallet.client.call( + preparePayResult = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -136,7 +137,9 @@ async function testRefundApiWithFulfillmentUrl( preparePayResult.contractTermsHash, ); - let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href); + let publicOrderStatusResp = await harnessHttpLib.fetch( + publicOrderStatusUrl.href, + ); const respData = await publicOrderStatusResp.json(); t.assertTrue(publicOrderStatusResp.status === 200); t.assertAmountEquals(respData.refund_amount, "TESTKUDOS:5"); @@ -158,11 +161,11 @@ async function testRefundApiWithFulfillmentMessage( env: { merchant: MerchantServiceInterface; bank: BankServiceHandle; - wallet: WalletCli; + walletClient: WalletClient; exchange: ExchangeServiceInterface; }, ): Promise { - const { wallet, bank, exchange, merchant } = env; + const { walletClient, bank, exchange, merchant } = env; // Set up order. const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { @@ -187,7 +190,7 @@ async function testRefundApiWithFulfillmentMessage( // Make wallet pay for the order - let preparePayResult = await wallet.client.call( + let preparePayResult = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -198,7 +201,7 @@ async function testRefundApiWithFulfillmentMessage( preparePayResult.status === PreparePayResultType.PaymentPossible, ); - await wallet.client.call(WalletApiOperation.ConfirmPay, { + await walletClient.call(WalletApiOperation.ConfirmPay, { proposalId: preparePayResult.proposalId, }); @@ -210,7 +213,7 @@ async function testRefundApiWithFulfillmentMessage( t.assertTrue(orderStatus.order_status === "paid"); - preparePayResult = await wallet.client.call( + preparePayResult = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -248,7 +251,9 @@ async function testRefundApiWithFulfillmentMessage( preparePayResult.contractTermsHash, ); - let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href); + let publicOrderStatusResp = await harnessHttpLib.fetch( + publicOrderStatusUrl.href, + ); let respData = await publicOrderStatusResp.json(); console.log(respData); t.assertTrue(publicOrderStatusResp.status === 200); @@ -272,22 +277,28 @@ async function testRefundApiWithFulfillmentMessage( export async function runMerchantRefundApiTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, merchant } = - await createSimpleTestkudosEnvironment(t); + const { walletClient, bank, exchange, merchant } = + await createSimpleTestkudosEnvironmentV2(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:20", + }); + await wres.withdrawalFinishedCond; await testRefundApiWithFulfillmentUrl(t, { - wallet, + walletClient, bank, exchange, merchant, }); await testRefundApiWithFulfillmentMessage(t, { - wallet, + walletClient, bank, exchange, merchant, diff --git a/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts b/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts index e959e813b..08c9d4bb2 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts @@ -35,8 +35,9 @@ import { harnessHttpLib, } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - withdrawViaBank, + createSimpleTestkudosEnvironmentV2, + createWalletDaemonWithClient, + withdrawViaBankV2, } from "../harness/helpers.js"; interface Context { @@ -52,10 +53,18 @@ async function testWithClaimToken( t: GlobalTestState, c: Context, ): Promise { - const wallet = new WalletCli(t, "withclaimtoken"); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "wct", + }); const { bank, exchange } = c; const { merchant, merchantBaseUrl } = c; - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:20", + }); + await wres.withdrawalFinishedCond; const sessionId = "mysession"; const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { order: { @@ -104,7 +113,7 @@ async function testWithClaimToken( console.log(r); } - const preparePayResp = await wallet.client.call( + const preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -166,12 +175,9 @@ async function testWithClaimToken( t.assertDeepEqual(httpResp.status, 202); } - const confirmPayRes = await wallet.client.call( - WalletApiOperation.ConfirmPay, - { - proposalId: proposalId, - }, - ); + const confirmPayRes = await walletClient.call(WalletApiOperation.ConfirmPay, { + proposalId: proposalId, + }); t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done); @@ -238,7 +244,7 @@ async function testWithClaimToken( t.assertDeepEqual(httpResp.status, 200); } - const confirmPayRes2 = await wallet.client.call( + const confirmPayRes2 = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId: proposalId, @@ -307,11 +313,19 @@ async function testWithoutClaimToken( t: GlobalTestState, c: Context, ): Promise { - const wallet = new WalletCli(t, "withoutct"); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "wnoct", + }); const sessionId = "mysession2"; const { bank, exchange } = c; const { merchant, merchantBaseUrl } = c; - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:20", + }); + await wres.withdrawalFinishedCond; const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { order: { summary: "Buy me!", @@ -356,7 +370,7 @@ async function testWithoutClaimToken( console.log(r); } - const preparePayResp = await wallet.client.call( + const preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri, @@ -422,12 +436,9 @@ async function testWithoutClaimToken( t.assertDeepEqual(httpResp.status, 402); } - const confirmPayRes = await wallet.client.call( - WalletApiOperation.ConfirmPay, - { - proposalId: proposalId, - }, - ); + const confirmPayRes = await walletClient.call(WalletApiOperation.ConfirmPay, { + proposalId: proposalId, + }); t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done); @@ -492,7 +503,7 @@ async function testWithoutClaimToken( t.assertDeepEqual(httpResp.status, 200); } - const confirmPayRes2 = await wallet.client.call( + const confirmPayRes2 = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId: proposalId, @@ -564,7 +575,7 @@ async function testWithoutClaimToken( * specification of the endpoint. */ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) { - const { bank, exchange, merchant } = await createSimpleTestkudosEnvironment( + const { bank, exchange, merchant } = await createSimpleTestkudosEnvironmentV2( t, ); @@ -572,7 +583,9 @@ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) { const merchantBaseUrl = merchant.makeInstanceBaseUrl(); { - const httpResp = await httpLib.fetch(new URL("config", merchantBaseUrl).href); + const httpResp = await httpLib.fetch( + new URL("config", merchantBaseUrl).href, + ); const r = await httpResp.json(); console.log(r); t.assertDeepEqual(r.currency, "TESTKUDOS"); diff --git a/packages/taler-harness/src/integrationtests/test-pay-paid.ts b/packages/taler-harness/src/integrationtests/test-pay-paid.ts index a377b7237..8d39ad4f6 100644 --- a/packages/taler-harness/src/integrationtests/test-pay-paid.ts +++ b/packages/taler-harness/src/integrationtests/test-pay-paid.ts @@ -17,10 +17,14 @@ /** * Imports. */ -import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js"; import { - withdrawViaBank, + GlobalTestState, + MerchantPrivateApi, + harnessHttpLib, +} from "../harness/harness.js"; +import { createFaultInjectedMerchantTestkudosEnvironment, + withdrawViaBankV2, } from "../harness/helpers.js"; import { PreparePayResultType, @@ -42,18 +46,20 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; export async function runPayPaidTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, faultyExchange, faultyMerchant } = + const { walletClient, bank, faultyExchange, faultyMerchant } = await createFaultInjectedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { - wallet, + const wres = await withdrawViaBankV2(t, { + walletClient, bank, exchange: faultyExchange, amount: "TESTKUDOS:20", }); + await wres.withdrawalFinishedCond; + /** * ========================================================================= * Create an order and let the wallet pay under a session ID @@ -98,7 +104,7 @@ export async function runPayPaidTest(t: GlobalTestState) { console.log(pubUnpaidStatus); - let preparePayResp = await wallet.client.call( + let preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri: pubUnpaidStatus.taler_pay_uri, @@ -121,7 +127,7 @@ export async function runPayPaidTest(t: GlobalTestState) { publicOrderStatusResp.json(), ); - const confirmPayRes = await wallet.client.call( + const confirmPayRes = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId: proposalId, @@ -196,7 +202,7 @@ export async function runPayPaidTest(t: GlobalTestState) { // Pay with new taler://pay URI, which should // have the new session ID! // Wallet should now automatically re-play payment. - preparePayResp = await wallet.client.call( + preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri: orderStatusTwo.taler_pay_uri, diff --git a/packages/taler-harness/src/integrationtests/test-payment-abort.ts b/packages/taler-harness/src/integrationtests/test-payment-abort.ts index 05ca7a543..99140b2ee 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-abort.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-abort.ts @@ -17,10 +17,14 @@ /** * Imports. */ -import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js"; import { - withdrawViaBank, + GlobalTestState, + MerchantPrivateApi, + harnessHttpLib, +} from "../harness/harness.js"; +import { createFaultInjectedMerchantTestkudosEnvironment, + withdrawViaBankV2, } from "../harness/helpers.js"; import { FaultInjectionRequestContext } from "../harness/faultInjection.js"; import { @@ -37,13 +41,13 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; export async function runPaymentAbortTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, faultyMerchant, faultyExchange } = + const { walletClient, bank, exchange, faultyMerchant, faultyExchange } = await createFaultInjectedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange: faultyExchange, amount: "TESTKUDOS:20", @@ -84,7 +88,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) { console.log(pubUnpaidStatus); - let preparePayResp = await wallet.client.call( + let preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri: pubUnpaidStatus.taler_pay_uri, @@ -124,7 +128,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) { }, }); - const confirmPayResp = await wallet.client.call( + const confirmPayResp = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId, @@ -134,19 +138,16 @@ export async function runPaymentAbortTest(t: GlobalTestState) { // Can't have succeeded yet, but network error results in "pending" state. t.assertDeepEqual(confirmPayResp.type, ConfirmPayResultType.Pending); - const txns = await wallet.client.call(WalletApiOperation.GetTransactions, {}); + const txns = await walletClient.call(WalletApiOperation.GetTransactions, {}); console.log(j2s(txns)); - await wallet.client.call(WalletApiOperation.AbortTransaction, { + await walletClient.call(WalletApiOperation.AbortTransaction, { transactionId: txns.transactions[1].transactionId, }); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - const txns2 = await wallet.client.call( - WalletApiOperation.GetTransactions, - {}, - ); + const txns2 = await walletClient.call(WalletApiOperation.GetTransactions, {}); console.log(j2s(txns2)); const txTypes = txns2.transactions.map((x) => x.type); diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index c1438a419..0cc369a6e 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -114,7 +114,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], diff --git a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts index 25e19ae8e..29047e102 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts @@ -27,9 +27,12 @@ import { MerchantPrivateApi, getPayto, } from "../harness/harness.js"; -import { withdrawViaBank } from "../harness/helpers.js"; import { coin_ct10, coin_u1 } from "../harness/denomStructures.js"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { + createWalletDaemonWithClient, + withdrawViaBankV2, +} from "../harness/helpers.js"; async function setupTest(t: GlobalTestState): Promise<{ merchant: MerchantService; @@ -82,13 +85,13 @@ async function setupTest(t: GlobalTestState): Promise<{ await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -113,11 +116,18 @@ export async function runPaymentMultipleTest(t: GlobalTestState) { const { merchant, bank, exchange } = await setupTest(t); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "default", + }); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:100" }); + await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:100", + }); // Set up order. @@ -137,13 +147,12 @@ export async function runPaymentMultipleTest(t: GlobalTestState) { // Make wallet pay for the order - const r1 = await wallet.client.call(WalletApiOperation.PreparePayForUri, { + const r1 = await walletClient.call(WalletApiOperation.PreparePayForUri, { talerPayUri: orderStatus.taler_pay_uri, }); - await wallet.client.call(WalletApiOperation.ConfirmPay, { - // FIXME: should be validated, don't cast! - proposalId: r1.proposalId, + await walletClient.call(WalletApiOperation.ConfirmPay, { + transactionId: r1.transactionId, }); // Check if payment was successful. diff --git a/packages/taler-harness/src/integrationtests/test-payment-transient.ts b/packages/taler-harness/src/integrationtests/test-payment-transient.ts index c2a8e37c5..2cc0af309 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-transient.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-transient.ts @@ -29,8 +29,7 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { FaultInjectionResponseContext } from "../harness/faultInjection.js"; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js"; import { - createFaultInjectedMerchantTestkudosEnvironment, - withdrawViaBank, + createFaultInjectedMerchantTestkudosEnvironment, withdrawViaBankV2, } from "../harness/helpers.js"; @@ -41,13 +40,13 @@ import { export async function runPaymentTransientTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, faultyMerchant, faultyExchange } = + const { walletClient, bank, exchange, faultyMerchant, faultyExchange } = await createFaultInjectedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange: faultyExchange, amount: "TESTKUDOS:20", @@ -88,7 +87,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) { console.log(pubUnpaidStatus); - let preparePayResp = await wallet.client.call( + let preparePayResp = await walletClient.call( WalletApiOperation.PreparePayForUri, { talerPayUri: pubUnpaidStatus.taler_pay_uri, @@ -136,7 +135,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) { }, }); - const confirmPayResp = await wallet.client.call( + const confirmPayResp = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId, @@ -148,7 +147,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) { t.assertTrue(confirmPayResp.type === ConfirmPayResultType.Pending); t.assertTrue(faultInjected); - const confirmPayRespTwo = await wallet.client.call( + const confirmPayRespTwo = await walletClient.call( WalletApiOperation.ConfirmPay, { proposalId, diff --git a/packages/taler-harness/src/integrationtests/test-refund-gone.ts b/packages/taler-harness/src/integrationtests/test-refund-gone.ts index 5f226c7dd..8e402f3fc 100644 --- a/packages/taler-harness/src/integrationtests/test-refund-gone.ts +++ b/packages/taler-harness/src/integrationtests/test-refund-gone.ts @@ -19,9 +19,9 @@ */ import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - withdrawViaBank, - applyTimeTravel, + applyTimeTravelV2, + createSimpleTestkudosEnvironmentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; import { AbsoluteTime, @@ -36,12 +36,17 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; export async function runRefundGoneTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, merchant } = - await createSimpleTestkudosEnvironment(t); + const { walletClient, bank, exchange, merchant } = + await createSimpleTestkudosEnvironmentV2(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:20", + }); // Set up order. @@ -72,11 +77,11 @@ export async function runRefundGoneTest(t: GlobalTestState) { // Make wallet pay for the order - const r1 = await wallet.client.call(WalletApiOperation.PreparePayForUri, { + const r1 = await walletClient.call(WalletApiOperation.PreparePayForUri, { talerPayUri: orderStatus.taler_pay_uri, }); - const r2 = await wallet.client.call(WalletApiOperation.ConfirmPay, { + const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, { proposalId: r1.proposalId, }); @@ -90,7 +95,10 @@ export async function runRefundGoneTest(t: GlobalTestState) { console.log(orderStatus); - await applyTimeTravel(durationFromSpec({ hours: 1 }), { exchange, wallet }); + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ hours: 1 })), + { exchange, walletClient: walletClient }, + ); await exchange.runAggregatorOnce(); @@ -103,16 +111,16 @@ export async function runRefundGoneTest(t: GlobalTestState) { console.log(ref); - await wallet.client.call(WalletApiOperation.StartRefundQuery, { + await walletClient.call(WalletApiOperation.StartRefundQuery, { transactionId: r1.transactionId, }); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - let r = await wallet.client.call(WalletApiOperation.GetBalances, {}); + let r = await walletClient.call(WalletApiOperation.GetBalances, {}); console.log(JSON.stringify(r, undefined, 2)); - const r3 = await wallet.client.call(WalletApiOperation.GetTransactions, {}); + const r3 = await walletClient.call(WalletApiOperation.GetTransactions, {}); console.log(JSON.stringify(r3, undefined, 2)); await t.shutdown(); diff --git a/packages/taler-harness/src/integrationtests/test-revocation.ts b/packages/taler-harness/src/integrationtests/test-revocation.ts index 04707e51a..233780674 100644 --- a/packages/taler-harness/src/integrationtests/test-revocation.ts +++ b/packages/taler-harness/src/integrationtests/test-revocation.ts @@ -28,20 +28,22 @@ import { BankService, delayMs, getPayto, + WalletClient, } from "../harness/harness.js"; import { - withdrawViaBank, - makeTestPayment, - SimpleTestEnvironment, + SimpleTestEnvironmentNg, + createWalletDaemonWithClient, + makeTestPaymentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; async function revokeAllWalletCoins(req: { - wallet: WalletCli; + walletClient: WalletClient; exchange: ExchangeService; merchant: MerchantService; }): Promise { - const { wallet, exchange, merchant } = req; - const coinDump = await wallet.client.call(WalletApiOperation.DumpCoins, {}); + const { walletClient, exchange, merchant } = req; + const coinDump = await walletClient.call(WalletApiOperation.DumpCoins, {}); console.log(coinDump); const usedDenomHashes = new Set(); for (const coin of coinDump.coins) { @@ -60,7 +62,7 @@ async function revokeAllWalletCoins(req: { async function createTestEnvironment( t: GlobalTestState, -): Promise { +): Promise { const db = await setupDb(t); const bank = await BankService.create(t, { @@ -120,13 +122,13 @@ async function createTestEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -136,11 +138,19 @@ async function createTestEnvironment( const wallet = new WalletCli(t); + const { walletService, walletClient } = await createWalletDaemonWithClient( + t, + { + name: "default", + }, + ); + return { commonDb: db, exchange, merchant, - wallet, + walletClient, + walletService, bank, exchangeBankAccount, }; @@ -152,24 +162,30 @@ async function createTestEnvironment( export async function runRevocationTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, merchant } = await createTestEnvironment(t); + const { walletClient, bank, exchange, merchant } = + await createTestEnvironment(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); + const wres = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:15", + }); + await wres.withdrawalFinishedCond; console.log("revoking first time"); - await revokeAllWalletCoins({ wallet, exchange, merchant }); + await revokeAllWalletCoins({ walletClient, exchange, merchant }); // FIXME: this shouldn't be necessary once https://bugs.taler.net/n/6565 // is implemented. - await wallet.client.call(WalletApiOperation.AddExchange, { + await walletClient.call(WalletApiOperation.AddExchange, { exchangeBaseUrl: exchange.baseUrl, forceUpdate: true, }); - await wallet.runUntilDone(); - await wallet.runUntilDone(); - const bal = await wallet.client.call(WalletApiOperation.GetBalances, {}); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); + const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); console.log("wallet balance", bal); const order = { @@ -178,39 +194,43 @@ export async function runRevocationTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPayment(t, { wallet, merchant, order }); + await makeTestPaymentV2(t, { walletClient, merchant, order }); - wallet.deleteDatabase(); + await walletClient.call(WalletApiOperation.ClearDb, {}); - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); + await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:15", + }); - const coinDump = await wallet.client.call(WalletApiOperation.DumpCoins, {}); + const coinDump = await walletClient.call(WalletApiOperation.DumpCoins, {}); console.log(coinDump); const coinPubList = coinDump.coins.map((x) => x.coin_pub); - await wallet.client.call(WalletApiOperation.ForceRefresh, { + await walletClient.call(WalletApiOperation.ForceRefresh, { coinPubList, }); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); console.log("revoking second time"); - await revokeAllWalletCoins({ wallet, exchange, merchant }); + await revokeAllWalletCoins({ walletClient, exchange, merchant }); // FIXME: this shouldn't be necessary once https://bugs.taler.net/n/6565 // is implemented. - await wallet.client.call(WalletApiOperation.AddExchange, { + await walletClient.call(WalletApiOperation.AddExchange, { exchangeBaseUrl: exchange.baseUrl, forceUpdate: true, }); - await wallet.runUntilDone(); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); { - const bal = await wallet.client.call(WalletApiOperation.GetBalances, {}); + const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); console.log("wallet balance", bal); } - await makeTestPayment(t, { wallet, merchant, order }); + await makeTestPaymentV2(t, { walletClient, merchant, order }); } runRevocationTest.timeoutMs = 120000; runRevocationTest.suites = ["wallet"]; -runRevocationTest.excludeByDefault = true; \ No newline at end of file +runRevocationTest.excludeByDefault = true; diff --git a/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts b/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts index 50f9cbcd3..602b6629a 100644 --- a/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts +++ b/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts @@ -38,35 +38,8 @@ import { WalletCli, getPayto, } from "../harness/harness.js"; -import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js"; - -async function applyTimeTravel( - timetravelDuration: Duration, - s: { - exchange?: ExchangeService; - merchant?: MerchantService; - wallet?: WalletCli; - }, -): Promise { - if (s.exchange) { - await s.exchange.stop(); - s.exchange.setTimetravel(timetravelDuration); - await s.exchange.start(); - await s.exchange.pingUntilAvailable(); - } - - if (s.merchant) { - await s.merchant.stop(); - s.merchant.setTimetravel(timetravelDuration); - await s.merchant.start(); - await s.merchant.pingUntilAvailable(); - } - - if (s.wallet) { - console.log("setting wallet time travel to", timetravelDuration); - s.wallet.setTimetravel(timetravelDuration); - } -} +import { applyTimeTravelV2, createWalletDaemonWithClient, withdrawViaBankV2 } from "../harness/helpers.js"; + /** * Basic time travel test. @@ -119,13 +92,13 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], }); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", paytoUris: [getPayto("minst1")], @@ -133,43 +106,46 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { console.log("setup done!"); - const wallet = new WalletCli(t); + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "w1", + }); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); + const wres = await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:15" }); + await wres.withdrawalFinishedCond; // Travel into the future, the deposit expiration is two years // into the future. console.log("applying first time travel"); - await applyTimeTravel(durationFromSpec({ days: 400 }), { - wallet, + await applyTimeTravelV2(Duration.toMilliseconds(durationFromSpec({ days: 400 })), { + walletClient, exchange, merchant, }); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); let p: PendingOperationsResponse; - p = await wallet.client.call(WalletApiOperation.GetPendingOperations, {}); + p = await walletClient.call(WalletApiOperation.GetPendingOperations, {}); console.log("pending operations after first time travel"); console.log(JSON.stringify(p, undefined, 2)); - await startWithdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange, amount: "TESTKUDOS:20", }); - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Travel into the future, the deposit expiration is two years // into the future. console.log("applying second time travel"); - await applyTimeTravel(durationFromSpec({ years: 2, months: 6 }), { - wallet, + await applyTimeTravelV2(Duration.toMilliseconds(durationFromSpec({ years: 2, months: 6 })), { + walletClient, exchange, merchant, }); @@ -178,7 +154,7 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { // It would be too late to refresh them now, as we're past // the two year deposit expiration. - await wallet.runUntilDone(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { order: { @@ -198,7 +174,7 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { t.assertTrue(orderStatus.order_status === "unpaid"); - const r = await wallet.client.call(WalletApiOperation.PreparePayForUri, { + const r = await walletClient.call(WalletApiOperation.PreparePayForUri, { talerPayUri: orderStatus.taler_pay_uri, }); @@ -206,7 +182,7 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { t.assertTrue(r.status === PreparePayResultType.PaymentPossible); - const cpr = await wallet.client.call(WalletApiOperation.ConfirmPay, { + const cpr = await walletClient.call(WalletApiOperation.ConfirmPay, { proposalId: r.proposalId, }); diff --git a/packages/taler-harness/src/integrationtests/test-timetravel-withdraw.ts b/packages/taler-harness/src/integrationtests/test-timetravel-withdraw.ts index ca3e67647..e594d2d72 100644 --- a/packages/taler-harness/src/integrationtests/test-timetravel-withdraw.ts +++ b/packages/taler-harness/src/integrationtests/test-timetravel-withdraw.ts @@ -17,13 +17,16 @@ /** * Imports. */ -import { Duration, TransactionMajorState, TransactionType } from "@gnu-taler/taler-util"; +import { + Duration, + TransactionMajorState, + TransactionType, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, - startWithdrawViaBank, - withdrawViaBank, + createSimpleTestkudosEnvironmentV2, + withdrawViaBankV2, } from "../harness/helpers.js"; /** @@ -32,12 +35,18 @@ import { export async function runTimetravelWithdrawTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange, merchant } = - await createSimpleTestkudosEnvironment(t); + const { walletClient, bank, exchange, merchant } = + await createSimpleTestkudosEnvironmentV2(t); // Withdraw digital cash into the wallet. - await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" }); + const wres1 = await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:15", + }); + await wres1.withdrawalFinishedCond; // Travel 400 days into the future, // as the deposit expiration is two years @@ -47,21 +56,21 @@ export async function runTimetravelWithdrawTest(t: GlobalTestState) { }; await exchange.stop(); - exchange.setTimetravel(timetravelDuration); + exchange.setTimetravel(Duration.toMilliseconds(timetravelDuration)); await exchange.start(); await exchange.pingUntilAvailable(); await exchange.keyup(); await merchant.stop(); - merchant.setTimetravel(timetravelDuration); + merchant.setTimetravel(Duration.toMilliseconds(timetravelDuration)); await merchant.start(); await merchant.pingUntilAvailable(); console.log("starting withdrawal via bank"); // This should fail, as the wallet didn't time travel yet. - await startWithdrawViaBank(t, { - wallet, + await withdrawViaBankV2(t, { + walletClient, bank, exchange, amount: "TESTKUDOS:20", @@ -71,10 +80,7 @@ export async function runTimetravelWithdrawTest(t: GlobalTestState) { // Check that transactions are correct for the failed withdrawal { - console.log("running until done (should run into maxRetries limit)"); - await wallet.runUntilDone({ maxRetries: 5 }); - console.log("wallet done running"); - const transactions = await wallet.client.call( + const transactions = await walletClient.call( WalletApiOperation.GetTransactions, {}, ); @@ -88,7 +94,9 @@ export async function runTimetravelWithdrawTest(t: GlobalTestState) { // Now we also let the wallet time travel - wallet.setTimetravel(timetravelDuration); + walletClient.call(WalletApiOperation.TestingSetTimetravel, { + offsetMs: Duration.toMilliseconds(timetravelDuration), + }); // This doesn't work yet, see https://bugs.taler.net/n/6585 diff --git a/packages/taler-harness/src/integrationtests/test-wallet-backup-basic.ts b/packages/taler-harness/src/integrationtests/test-wallet-backup-basic.ts index 5321cf5c7..21ac662c2 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-backup-basic.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-backup-basic.ts @@ -21,9 +21,8 @@ import { j2s } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState, WalletCli } from "../harness/harness.js"; import { - createSimpleTestkudosEnvironment, createSimpleTestkudosEnvironmentV2, - withdrawViaBank, + createWalletDaemonWithClient, withdrawViaBankV2, } from "../harness/helpers.js"; import { SyncService } from "../harness/sync.js"; @@ -112,40 +111,42 @@ export async function runWalletBackupBasicTest(t: GlobalTestState) { const txs = await walletClient.call(WalletApiOperation.GetTransactions, {}); console.log(`backed up transactions ${j2s(txs)}`); - const wallet2 = new WalletCli(t, "wallet2"); + const { walletClient: walletClient2 } = await createWalletDaemonWithClient(t, { + name: "w2" + }); // Check that the second wallet is a fresh wallet. { - const bal = await wallet2.client.call(WalletApiOperation.GetBalances, {}); + const bal = await walletClient2.call(WalletApiOperation.GetBalances, {}); t.assertTrue(bal.balances.length === 0); } - await wallet2.client.call(WalletApiOperation.ImportBackupRecovery, { + await walletClient2.call(WalletApiOperation.ImportBackupRecovery, { recovery: backupRecovery, }); - await wallet2.client.call(WalletApiOperation.RunBackupCycle, {}); + await walletClient2.call(WalletApiOperation.RunBackupCycle, {}); // Check that now the old balance is available! { - const bal = await wallet2.client.call(WalletApiOperation.GetBalances, {}); + const bal = await walletClient2.call(WalletApiOperation.GetBalances, {}); t.assertTrue(bal.balances.length === 1); console.log(bal); } // Now do some basic checks that the restored wallet is still functional { - const txs = await wallet2.client.call( + const txs = await walletClient2.call( WalletApiOperation.GetTransactions, {}, ); console.log(`restored transactions ${j2s(txs)}`); - const bal1 = await wallet2.client.call(WalletApiOperation.GetBalances, {}); + const bal1 = await walletClient2.call(WalletApiOperation.GetBalances, {}); t.assertAmountEquals(bal1.balances[0].available, "TESTKUDOS:14.1"); - await withdrawViaBank(t, { - wallet: wallet2, + await withdrawViaBankV2(t, { + walletClient: walletClient2, bank, exchange, amount: "TESTKUDOS:10", @@ -153,15 +154,15 @@ export async function runWalletBackupBasicTest(t: GlobalTestState) { await exchange.runWirewatchOnce(); - await wallet2.runUntilDone(); + await walletClient2.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - const txs2 = await wallet2.client.call( + const txs2 = await walletClient2.call( WalletApiOperation.GetTransactions, {}, ); console.log(`tx after withdraw after restore ${j2s(txs2)}`); - const bal2 = await wallet2.client.call(WalletApiOperation.GetBalances, {}); + const bal2 = await walletClient2.call(WalletApiOperation.GetBalances, {}); t.assertAmountEquals(bal2.balances[0].available, "TESTKUDOS:23.82"); } diff --git a/packages/taler-harness/src/integrationtests/test-wallet-backup-doublespend.ts b/packages/taler-harness/src/integrationtests/test-wallet-backup-doublespend.ts index e3e18d5a4..99adc1754 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-backup-doublespend.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-backup-doublespend.ts @@ -19,16 +19,12 @@ */ import { PreparePayResultType } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { - GlobalTestState, - MerchantPrivateApi, - WalletCli, -} from "../harness/harness.js"; +import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2, + createWalletDaemonWithClient, makeTestPaymentV2, - withdrawViaBank, - withdrawViaBankV2 + withdrawViaBankV2, } from "../harness/helpers.js"; import { SyncService } from "../harness/sync.js"; @@ -58,7 +54,12 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) { name: sync.baseUrl, }); - await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:10" }); + await withdrawViaBankV2(t, { + walletClient, + bank, + exchange, + amount: "TESTKUDOS:10", + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); @@ -71,13 +72,16 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) { {}, ); - const wallet2 = new WalletCli(t, "wallet2"); + const { walletClient: walletClientTwo } = await createWalletDaemonWithClient( + t, + { name: "default" }, + ); - await wallet2.client.call(WalletApiOperation.ImportBackupRecovery, { + await walletClientTwo.call(WalletApiOperation.ImportBackupRecovery, { recovery: backupRecovery, }); - await wallet2.client.call(WalletApiOperation.RunBackupCycle, {}); + await walletClientTwo.call(WalletApiOperation.RunBackupCycle, {}); console.log( "wallet1 balance before spend:", @@ -103,7 +107,7 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) { { console.log( "wallet2 balance:", - await wallet2.client.call(WalletApiOperation.GetBalances, {}), + await walletClientTwo.call(WalletApiOperation.GetBalances, {}), ); } @@ -134,11 +138,11 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) { { console.log( "wallet2 balance before preparePay:", - await wallet2.client.call(WalletApiOperation.GetBalances, {}), + await walletClientTwo.call(WalletApiOperation.GetBalances, {}), ); } - const preparePayResult = await wallet2.client.call( + const preparePayResult = await walletClientTwo.call( WalletApiOperation.PreparePayForUri, { talerPayUri: orderStatus.taler_pay_uri, @@ -150,25 +154,28 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) { PreparePayResultType.PaymentPossible, ); - const res = await wallet2.client.call(WalletApiOperation.ConfirmPay, { - proposalId: preparePayResult.proposalId, + const res = await walletClientTwo.call(WalletApiOperation.ConfirmPay, { + transactionId: preparePayResult.transactionId, }); console.log(res); // FIXME: wait for a notification that indicates insufficient funds! - await withdrawViaBank(t, { - wallet: wallet2, + await withdrawViaBankV2(t, { + walletClient: walletClientTwo, bank, exchange, amount: "TESTKUDOS:50", }); - const bal = await wallet2.client.call(WalletApiOperation.GetBalances, {}); + const bal = await walletClientTwo.call(WalletApiOperation.GetBalances, {}); console.log("bal", bal); - await wallet2.runUntilDone(); + await walletClientTwo.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); } } diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index c70fd51d4..3315a71d4 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -92,7 +92,7 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { // Fakebank uses x-taler-bank, but merchant is configured to only accept sepa! const label = "mymerchant"; - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [ diff --git a/packages/taler-harness/src/integrationtests/test-wallettesting.ts b/packages/taler-harness/src/integrationtests/test-wallettesting.ts index a856df79f..4fa870f1c 100644 --- a/packages/taler-harness/src/integrationtests/test-wallettesting.ts +++ b/packages/taler-harness/src/integrationtests/test-wallettesting.ts @@ -91,7 +91,7 @@ export async function createMyEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - await merchant.addInstance({ + await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", paytoUris: [getPayto("merchant-default")], diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts index c3069c317..1ba180fc1 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts @@ -23,7 +23,7 @@ import { BankAccessApiClient, } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; -import { createSimpleTestkudosEnvironment } from "../harness/helpers.js"; +import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; /** * Run test for basic, bank-integrated withdrawal. @@ -31,7 +31,8 @@ import { createSimpleTestkudosEnvironment } from "../harness/helpers.js"; export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // Set up test environment - const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t); + const { walletClient, bank, exchange } = + await createSimpleTestkudosEnvironmentV2(t); // Create a withdrawal operation @@ -48,11 +49,11 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // Hand it to the wallet - await wallet.client.call(WalletApiOperation.GetWithdrawalDetailsForUri, { + await walletClient.call(WalletApiOperation.GetWithdrawalDetailsForUri, { talerWithdrawUri: wop.taler_withdraw_uri, }); - await wallet.runPending(); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Abort it @@ -67,13 +68,10 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // WHY ?! // const e = await t.assertThrowsTalerErrorAsync(async () => { - await wallet.client.call( - WalletApiOperation.AcceptBankIntegratedWithdrawal, - { - exchangeBaseUrl: exchange.baseUrl, - talerWithdrawUri: wop.taler_withdraw_uri, - }, - ); + await walletClient.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { + exchangeBaseUrl: exchange.baseUrl, + talerWithdrawUri: wop.taler_withdraw_uri, + }); }); t.assertDeepEqual( e.errorDetail.code, diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index 06355b964..34dfb8fc9 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -17,22 +17,19 @@ /** * Imports. */ +import { j2s } from "@gnu-taler/taler-util"; import { - GlobalTestState, - WalletCli, - setupDb, - ExchangeService, - BankService, -} from "../harness/harness.js"; -import { - BankAccessApi, BankAccessApiClient, - BankApi, WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { CoinConfig } from "../harness/denomStructures.js"; -import { j2s, URL } from "@gnu-taler/taler-util"; -import { withdrawViaBank } from "../harness/helpers.js"; +import { + BankService, + ExchangeService, + GlobalTestState, + WalletCli, + setupDb, +} from "../harness/harness.js"; const coinRsaCommon = { cipher: "RSA" as const, @@ -119,7 +116,10 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) { }); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); - const wop = await bankAccessApiClient.createWithdrawalOperation(user.username, amount); + const wop = await bankAccessApiClient.createWithdrawalOperation( + user.username, + amount, + ); // Hand it to the wallet diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index 7afd9bc83..3a49cf73c 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -115,6 +115,7 @@ import { runTermOfServiceFormatTest } from "./test-tos-format.js"; import { runExchangePurseTest } from "./test-exchange-purse.js"; import { getSharedTestDir } from "../harness/helpers.js"; import { runStoredBackupsTest } from "./test-stored-backups.js"; +import { runPaymentExpiredTest } from "./test-payment-expired.js"; /** * Test runner. @@ -214,6 +215,7 @@ const allTests: TestMainFunction[] = [ runWithdrawalHugeTest, runTermOfServiceFormatTest, runStoredBackupsTest, + runPaymentExpiredTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/merchant-api-types.ts b/packages/taler-util/src/merchant-api-types.ts index 9f00173f2..ce30aa054 100644 --- a/packages/taler-util/src/merchant-api-types.ts +++ b/packages/taler-util/src/merchant-api-types.ts @@ -47,6 +47,7 @@ import { WireAccount, codecForWireAccount, codecForList, + HashCodeString, } from "@gnu-taler/taler-util"; export interface MerchantPostOrderRequest { @@ -384,3 +385,37 @@ export const codecForMerchantReserveCreateConfirmation = .property("accounts", codecForList(codecForWireAccount())) .property("reserve_pub", codecForString()) .build("MerchantReserveCreateConfirmation"); + +export interface AccountAddDetails { + // payto:// URI of the account. + payto_uri: string; + + // URL from where the merchant can download information + // about incoming wire transfers to this account. + credit_facade_url?: string; + + // Credentials to use when accessing the credit facade. + // Never returned on a GET (as this may be somewhat + // sensitive data). Can be set in POST + // or PATCH requests to update (or delete) credentials. + // To really delete credentials, set them to the type: "none". + credit_facade_credentials?: FacadeCredentials; +} + +export type FacadeCredentials = + | NoFacadeCredentials + | BasicAuthFacadeCredentials; + +export interface NoFacadeCredentials { + type: "none"; +} + +export interface BasicAuthFacadeCredentials { + type: "basic"; + + // Username to use to authenticate + username: string; + + // Password to use to authenticate + password: string; +} diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts index 55cda08a5..46ed37637 100644 --- a/packages/taler-util/src/time.ts +++ b/packages/taler-util/src/time.ts @@ -154,13 +154,27 @@ export interface TalerProtocolDuration { readonly d_us: number | "forever"; } +/** + * Timeshift in milliseconds. + */ let timeshift = 0; +/** + * Set timetravel offset in milliseconds. + * + * Use carefully and only for testing. + */ export function setDangerousTimetravel(dt: number): void { timeshift = dt; } export namespace Duration { + export function toMilliseconds(d: Duration): number { + if (d.d_ms === "forever") { + return Number.MAX_VALUE; + } + return d.d_ms; + } export function getRemaining( deadline: AbsoluteTime, now = AbsoluteTime.now(), diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index d49182e26..0070b18e4 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -2685,3 +2685,13 @@ export const codecForRecoverStoredBackupRequest = buildCodecForObject() .property("name", codecForString()) .build("RecoverStoredBackupRequest"); + +export interface TestingSetTimetravelRequest { + offsetMs: number; +} + +export const codecForTestingSetTimetravelRequest = + (): Codec => + buildCodecForObject() + .property("offsetMs", codecForNumber()) + .build("TestingSetTimetravelRequest"); diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 4d9d40c43..72cd37b10 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -119,6 +119,7 @@ import { CreateStoredBackupResponse, RecoverStoredBackupRequest, DeleteStoredBackupRequest, + TestingSetTimetravelRequest, } from "@gnu-taler/taler-util"; import { AuditorTrustRecord, WalletContractData } from "./db.js"; import { @@ -215,6 +216,7 @@ export enum WalletApiOperation { ValidateIban = "validateIban", TestingWaitTransactionsFinal = "testingWaitTransactionsFinal", TestingWaitRefreshesFinal = "testingWaitRefreshesFinal", + TestingSetTimetravel = "testingSetTimetravel", GetScopedCurrencyInfo = "getScopedCurrencyInfo", ListStoredBackups = "listStoredBackups", CreateStoredBackup = "createStoredBackup", @@ -989,6 +991,15 @@ export type DumpCoinsOp = { response: CoinDumpJson; }; +/** + * Add an offset to the wallet's internal time. + */ +export type TestingSetTimetravelOp = { + op: WalletApiOperation.TestingSetTimetravel; + request: TestingSetTimetravelRequest; + response: EmptyObject; +}; + /** * Wait until all transactions are in a final state. */ @@ -1111,6 +1122,7 @@ export type WalletOperations = { [WalletApiOperation.ValidateIban]: ValidateIbanOp; [WalletApiOperation.TestingWaitTransactionsFinal]: TestingWaitTransactionsFinal; [WalletApiOperation.TestingWaitRefreshesFinal]: TestingWaitRefreshesFinal; + [WalletApiOperation.TestingSetTimetravel]: TestingSetTimetravelOp; [WalletApiOperation.GetScopedCurrencyInfo]: GetScopedCurrencyInfoOp; [WalletApiOperation.CreateStoredBackup]: CreateStoredBackupsOp; [WalletApiOperation.ListStoredBackups]: ListStoredBackupsOp; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 5666d67e0..4194ab9eb 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -126,6 +126,8 @@ import { DeleteStoredBackupRequest, RecoverStoredBackupRequest, codecForRecoverStoredBackupRequest, + codecForTestingSetTimetravelRequest, + setDangerousTimetravel, } from "@gnu-taler/taler-util"; import { HttpRequestLibrary, @@ -1674,6 +1676,11 @@ async function dispatchRequestInternal( return await waitUntilDone(ws); case WalletApiOperation.TestingWaitRefreshesFinal: return await waitUntilRefreshesDone(ws); + case WalletApiOperation.TestingSetTimetravel: { + const req = codecForTestingSetTimetravelRequest().decode(payload); + setDangerousTimetravel(req.offsetMs); + ws.workAvailable.trigger(); + } // default: // assertUnreachable(operation); } -- cgit v1.2.3 From 49b0f5337c27c5da3e85c512de72e6903e928bc8 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 5 Sep 2023 11:35:06 +0200 Subject: harness: check expected balance in test-pay-expired --- packages/taler-harness/src/harness/harness.ts | 6 ++++- packages/taler-harness/src/harness/helpers.ts | 2 +- .../src/integrationtests/test-payment-expired.ts | 30 ++++++++++++++++++++++ packages/taler-wallet-core/src/remote.ts | 1 + packages/taler-wallet-core/src/wallet.ts | 1 + 5 files changed, 38 insertions(+), 2 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index b5197afd7..7c54c0c47 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -384,7 +384,11 @@ export class GlobalTestState { logger.warn(`could not start process (${command})`, err); }); proc.on("exit", (code, signal) => { - logger.warn(`process ${logName} exited ${j2s({ code, signal })}`); + if (code == 0 && signal == null) { + logger.info(`process ${logName} exited with success`); + } else { + logger.warn(`process ${logName} exited ${j2s({ code, signal })}`); + } }); const stderrLogFileName = this.testDir + `/${logName}-stderr.log`; const stderrLog = fs.createWriteStream(stderrLogFileName, { diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 39d411a46..ece003e1b 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -624,7 +624,7 @@ export async function applyTimeTravelV2( } if (s.walletClient) { - s.walletClient.call(WalletApiOperation.TestingSetTimetravel, { + await s.walletClient.call(WalletApiOperation.TestingSetTimetravel, { offsetMs: timetravelOffsetMs, }); } diff --git a/packages/taler-harness/src/integrationtests/test-payment-expired.ts b/packages/taler-harness/src/integrationtests/test-payment-expired.ts index e4034108f..4817efba5 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-expired.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-expired.ts @@ -20,14 +20,17 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState, MerchantApiClient } from "../harness/harness.js"; import { + applyTimeTravelV2, createSimpleTestkudosEnvironmentV2, withdrawViaBankV2, } from "../harness/helpers.js"; import { AbsoluteTime, + ConfirmPayResultType, Duration, MerchantContractTerms, PreparePayResultType, + j2s, } from "@gnu-taler/taler-util"; /** @@ -95,6 +98,33 @@ export async function runPaymentExpiredTest(t: GlobalTestState) { preparePayResult.status, PreparePayResultType.PaymentPossible, ); + + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ hours: 1 })), + { walletClient, exchange, merchant }, + ); + + const confirmPayResult = await walletClient.call( + WalletApiOperation.ConfirmPay, + { transactionId: preparePayResult.transactionId }, + ); + console.log("confirm pay result:"); + console.log(j2s(confirmPayResult)); + t.assertDeepEqual(confirmPayResult.type, ConfirmPayResultType.Pending); + await walletClient.call(WalletApiOperation.AbortTransaction, { + transactionId: preparePayResult.transactionId, + }); + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); + + const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); + console.log(bal); + + t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:18.93"); + + const txns = await walletClient.call(WalletApiOperation.GetTransactions, { + includeRefreshes: true, + }); + console.log(j2s(txns)); } runPaymentExpiredTest.suites = ["wallet"]; diff --git a/packages/taler-wallet-core/src/remote.ts b/packages/taler-wallet-core/src/remote.ts index 89348698e..164f7cfe9 100644 --- a/packages/taler-wallet-core/src/remote.ts +++ b/packages/taler-wallet-core/src/remote.ts @@ -65,6 +65,7 @@ export async function createRemoteWallet( const ctx: RemoteWallet = { makeCoreApiRequest(operation, payload) { const id = `req-${nextRequestId}`; + nextRequestId += 1; const req: CoreApiRequestEnvelope = { operation, id, diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 4194ab9eb..f42365c00 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -1680,6 +1680,7 @@ async function dispatchRequestInternal( const req = codecForTestingSetTimetravelRequest().decode(payload); setDangerousTimetravel(req.offsetMs); ws.workAvailable.trigger(); + return {}; } // default: // assertUnreachable(operation); -- cgit v1.2.3 From 665c42f595151650bb87a3108a19d6df67ed6324 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 10:48:16 +0200 Subject: draft for better operation status codes --- packages/taler-wallet-core/src/db.ts | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index b9d86eb25..0c51a68c9 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -117,11 +117,17 @@ export const TALER_WALLET_MAIN_DB_NAME = "taler-wallet-main-v9"; export const TALER_WALLET_META_DB_NAME = "taler-wallet-meta"; /** - * Stored backups, mainly created when manually importing a backup. + * Name of the "stored backups" database. + * Stored backups are created before manually importing a backup. + * We use IndexedDB for this purpose, since we don't have file system + * access on some platforms. */ export const TALER_WALLET_STORED_BACKUPS_DB_NAME = "taler-wallet-stored-backups"; +/** + * Name of the "meta config" database. + */ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName"; /** @@ -133,6 +139,32 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName"; */ export const WALLET_DB_MINOR_VERSION = 10; + + +/** + * Format of the operation status code: xyznnn + * + * x=1: active + * yz=00: pending + * yz=02: dialog + * yz=03: aborting + * yz=10: suspended + * yz=13: suspended-aborting + * x=2: final + * yz=00: done + * yz=01: failed + * yz=02: expired + * yz=03: aborted + */ +// export const OperationStatusRange = { +// ActiveStart: 10000, +// ActiveEnd: 10999, +// SuspendedStart: 10999, +// SuspendedEnd: 10999, +// FinalStart: 20000, +// FinalEnd: 29999, +//} as const; + /** * Ranges for operation status fields. * -- cgit v1.2.3 From 7450bede5b5809f6a496b7e68852a454386850e5 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 12:32:31 +0200 Subject: get rid of deprecated bank API client, change allowHttp to requireTls --- packages/anastasis-core/src/index.ts | 1 - packages/taler-harness/src/bench2.ts | 1 - packages/taler-harness/src/bench3.ts | 1 - packages/taler-harness/src/harness/harness.ts | 51 ++--- packages/taler-harness/src/harness/helpers.ts | 11 +- .../taler-harness/src/harness/libeufin-apis.ts | 5 +- packages/taler-harness/src/index.ts | 15 +- .../test-age-restrictions-merchant.ts | 20 +- .../src/integrationtests/test-bank-api.ts | 28 ++- .../src/integrationtests/test-exchange-deposit.ts | 1 - .../integrationtests/test-exchange-management.ts | 12 +- .../integrationtests/test-exchange-timetravel.ts | 1 - .../taler-harness/src/integrationtests/test-kyc.ts | 12 +- .../src/integrationtests/test-payment-fault.ts | 14 +- .../src/integrationtests/test-tipping.ts | 22 +- .../integrationtests/test-wallet-notifications.ts | 7 +- .../integrationtests/test-withdrawal-abort-bank.ts | 7 +- .../test-withdrawal-bank-integrated.ts | 12 +- .../src/integrationtests/test-withdrawal-fees.ts | 7 +- .../src/integrationtests/test-withdrawal-manual.ts | 22 +- packages/taler-harness/src/lint.ts | 1 - packages/taler-util/src/MerchantApiClient.ts | 5 +- packages/taler-util/src/http-common.ts | 5 +- packages/taler-util/src/http-impl.node.ts | 6 +- packages/taler-util/src/http-impl.qtart.ts | 6 +- packages/taler-wallet-cli/src/index.ts | 7 +- packages/taler-wallet-core/src/bank-api-client.ts | 250 ++++----------------- packages/taler-wallet-core/src/dbless.ts | 26 +-- packages/taler-wallet-core/src/host-impl.node.ts | 2 +- packages/taler-wallet-core/src/host-impl.qtart.ts | 2 +- 30 files changed, 188 insertions(+), 372 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts index 88f3bdbe2..89cf186dd 100644 --- a/packages/anastasis-core/src/index.ts +++ b/packages/anastasis-core/src/index.ts @@ -138,7 +138,6 @@ export * as validators from "./validators.js"; export * from "./challenge-feedback-types.js"; const httpLib = createPlatformHttpLib({ - allowHttp: true, enableThrottling: false, }); diff --git a/packages/taler-harness/src/bench2.ts b/packages/taler-harness/src/bench2.ts index 48ac76b9f..53db6f6c1 100644 --- a/packages/taler-harness/src/bench2.ts +++ b/packages/taler-harness/src/bench2.ts @@ -57,7 +57,6 @@ export async function runBench2(configJson: any): Promise { const http = createPlatformHttpLib({ enableThrottling: false, - allowHttp: true, }); const numIter = benchConf.iterations ?? 1; diff --git a/packages/taler-harness/src/bench3.ts b/packages/taler-harness/src/bench3.ts index c7eca90a8..0b5371af5 100644 --- a/packages/taler-harness/src/bench3.ts +++ b/packages/taler-harness/src/bench3.ts @@ -52,7 +52,6 @@ export async function runBench3(configJson: any): Promise { const myHttpLib = createPlatformHttpLib({ enableThrottling: false, - allowHttp: true, }); const numIter = b3conf.iterations ?? 1; diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index df3c9b215..d0719b4f7 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -25,62 +25,46 @@ * Imports */ import { + AccountAddDetails, AmountJson, Amounts, - AmountString, - codecForMerchantOrderPrivateStatusResponse, - codecForMerchantPostOrderResponse, - codecForMerchantReserveCreateConfirmation, Configuration, CoreApiResponse, - createEddsaKeyPair, Duration, - eddsaGetPublic, EddsaKeyPair, + Logger, + MerchantInstanceConfig, + PartialMerchantInstanceConfig, + TalerError, + WalletNotification, + createEddsaKeyPair, + eddsaGetPublic, encodeCrock, hash, j2s, - Logger, - MerchantInstancesResponse, - MerchantOrderPrivateStatusResponse, - MerchantPostOrderRequest, - MerchantPostOrderResponse, - MerchantReserveCreateConfirmation, - MerchantTemplateAddDetails, parsePaytoUri, stringToBytes, - TalerError, - TalerProtocolDuration, - RewardCreateConfirmation, - RewardCreateRequest, - TippingReserveStatus, - WalletNotification, - codecForAny, - AccountAddDetails, - MerchantInstanceConfig, - PartialMerchantInstanceConfig, } from "@gnu-taler/taler-util"; import { createPlatformHttpLib, expectSuccessResponseOrThrow, - readSuccessResponseJsonOrThrow, } from "@gnu-taler/taler-util/http"; import { - BankApi, + BankAccessApiClient, BankServiceHandle, HarnessExchangeBankAccount, - openPromise, WalletCoreApiClient, WalletCoreRequestType, WalletCoreResponseType, WalletOperations, + openPromise, } from "@gnu-taler/taler-wallet-core"; import { + RemoteWallet, + WalletNotificationWaiter, createRemoteWallet, getClientFromRemoteWallet, makeNotificationWaiter, - RemoteWallet, - WalletNotificationWaiter, } from "@gnu-taler/taler-wallet-core/remote"; import { deepStrictEqual } from "assert"; import { ChildProcess, spawn } from "child_process"; @@ -594,7 +578,7 @@ export class FakebankService { proc: ProcessWrapper | undefined; - http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false }); + http = createPlatformHttpLib({ enableThrottling: false }); // We store "created" accounts during setup and // register them after startup. @@ -702,13 +686,9 @@ export class FakebankService "bank", ); await this.pingUntilAvailable(); + const bankClient = new BankAccessApiClient(this.bankAccessApiBaseUrl); for (const acc of this.accounts) { - await BankApi.registerAccount( - this, - acc.accountName, - acc.accountPassword, - {}, - ); + await bankClient.registerAccount(acc.accountName, acc.accountPassword); } } @@ -1351,7 +1331,6 @@ export interface MerchantServiceInterface { * Default HTTP client handle for the integration test harness. */ export const harnessHttpLib = createPlatformHttpLib({ - allowHttp: true, enableThrottling: false, }); diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 7b2f7d8f1..f92fd4dd9 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -36,8 +36,7 @@ import { MerchantApiClient, } from "@gnu-taler/taler-util"; import { - BankAccessApi, - BankApi, + BankAccessApiClient, HarnessExchangeBankAccount, WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; @@ -563,8 +562,10 @@ export async function withdrawViaBankV2( ): Promise { const { walletClient: wallet, bank, exchange, amount } = p; - const user = await BankApi.createRandomBankUser(bank); - const wop = await BankAccessApi.createWithdrawalOperation(bank, user, amount); + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + + const user = await bankClient.createRandomBankUser(); + const wop = await bankClient.createWithdrawalOperation(user.username, amount); // Hand it to the wallet @@ -593,7 +594,7 @@ export async function withdrawViaBankV2( // Confirm it - await BankApi.confirmWithdrawalOperation(bank, user, wop); + await bankClient.confirmWithdrawalOperation(user.username, wop); return { withdrawalFinishedCond, diff --git a/packages/taler-harness/src/harness/libeufin-apis.ts b/packages/taler-harness/src/harness/libeufin-apis.ts index 0553223cb..0193f9252 100644 --- a/packages/taler-harness/src/harness/libeufin-apis.ts +++ b/packages/taler-harness/src/harness/libeufin-apis.ts @@ -176,10 +176,7 @@ export interface LibeufinSandboxAddIncomingRequest { direction: string; } -const libeufinHarnessHttpLib = createPlatformHttpLib({ - allowHttp: true, - enableThrottling: false, -}); +const libeufinHarnessHttpLib = createPlatformHttpLib(); /** * APIs spread across Legacy and Access, it is therefore diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index ed2e545f7..185f6226d 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -236,14 +236,15 @@ deploymentCli console.log(tipReserveResp); - const bankAccessApiClient = new BankAccessApiClient({ - baseUrl: args.tipTopup.bankAccessUrl, - auth: { - username: args.tipTopup.bankAccount, - password: args.tipTopup.bankPassword, + const bankAccessApiClient = new BankAccessApiClient( + args.tipTopup.bankAccessUrl, + { + auth: { + username: args.tipTopup.bankAccount, + password: args.tipTopup.bankPassword, + }, }, - allowHttp: true, - }); + ); const paytoUri = addPaytoQueryParams(tipReserveResp.accounts[0].payto_uri, { message: `tip-reserve ${tipReserveResp.reserve_pub}`, diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts index 4e096e0ea..bff13ae40 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankApi, + BankAccessApiClient, WalletApiOperation, WireGatewayApiClient, } from "@gnu-taler/taler-wallet-core"; @@ -179,7 +179,8 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { // Pay with coin from tipping { - const mbu = await BankApi.createRandomBankUser(bank); + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const mbu = await bankClient.createRandomBankUser(); const tipReserveResp = await merchantClient.createTippingReserve({ exchange_url: exchange.baseUrl, initial_balance: "TESTKUDOS:10", @@ -191,12 +192,15 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { exchangeBankAccount.accountPaytoUri, ); - const wireGatewayApiClient = new WireGatewayApiClient({ - wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl, - accountName: exchangeBankAccount.accountName, - accountPassword: exchangeBankAccount.accountPassword, - allowHttp: true, - }); + const wireGatewayApiClient = new WireGatewayApiClient( + exchangeBankAccount.wireGatewayApiBaseUrl, + { + auth: { + username: exchangeBankAccount.accountName, + password: exchangeBankAccount.accountPassword, + }, + }, + ); await wireGatewayApiClient.adminAddIncoming({ amount: "TESTKUDOS:10", diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index e645d60f1..afb06b61a 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -19,8 +19,7 @@ */ import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util"; import { - BankAccessApi, - BankApi, + BankAccessApiClient, CreditDebitIndicator, WireGatewayApiClient, } from "@gnu-taler/taler-wallet-core"; @@ -99,17 +98,19 @@ export async function runBankApiTest(t: GlobalTestState) { console.log("setup done!"); - const bankUser = await BankApi.registerAccount(bank, "user1", "pw1", {}); + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + + const bankUser = await bankClient.registerAccount("user1", "pw1"); // Make sure that registering twice results in a 409 Conflict { const e = await t.assertThrowsTalerErrorAsync(async () => { - await BankApi.registerAccount(bank, "user1", "pw2", {}); + await bankClient.registerAccount("user1", "pw1"); }); t.assertTrue(e.errorDetail.httpStatusCode === 409); } - let balResp = await BankAccessApi.getAccountBalance(bank, bankUser); + let balResp = await bankClient.getAccountBalance(bankUser.username); console.log(balResp); @@ -121,12 +122,15 @@ export async function runBankApiTest(t: GlobalTestState) { const res = createEddsaKeyPair(); - const wireGatewayApiClient = new WireGatewayApiClient({ - wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl, - accountName: exchangeBankAccount.accountName, - accountPassword: exchangeBankAccount.accountPassword, - allowHttp: true, - }); + const wireGatewayApiClient = new WireGatewayApiClient( + exchangeBankAccount.wireGatewayApiBaseUrl, + { + auth: { + username: exchangeBankAccount.accountName, + password: exchangeBankAccount.accountPassword, + }, + }, + ); await wireGatewayApiClient.adminAddIncoming({ amount: "TESTKUDOS:115", @@ -134,7 +138,7 @@ export async function runBankApiTest(t: GlobalTestState) { reservePub: encodeCrock(res.eddsaPub), }); - balResp = await BankAccessApi.getAccountBalance(bank, bankUser); + balResp = await bankClient.getAccountBalance(bankUser.username); t.assertAmountEquals(balResp.balance.amount, "TESTKUDOS:15"); t.assertTrue( balResp.balance.credit_debit_indicator === CreditDebitIndicator.Debit, diff --git a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts index 05bbbfaa1..96255f5b5 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts @@ -49,7 +49,6 @@ export async function runExchangeDepositTest(t: GlobalTestState) { const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(t); const http = createPlatformHttpLib({ - allowHttp: true, enableThrottling: false, }); const cryptiDisp = new CryptoDispatcher( diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index 718cee0d7..19be7c962 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -28,8 +28,7 @@ import { } from "../harness/harness.js"; import { WalletApiOperation, - BankApi, - BankAccessApi, + BankAccessApiClient, } from "@gnu-taler/taler-wallet-core"; import { ExchangesListResponse, @@ -266,10 +265,11 @@ export async function runExchangeManagementTest( // Create withdrawal operation - const user = await BankApi.createRandomBankUser(bank); - const wop = await BankAccessApi.createWithdrawalOperation( - bank, - user, + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + + const user = await bankClient.createRandomBankUser(); + const wop = await bankClient.createWithdrawalOperation( + user.username, "TESTKUDOS:10", ); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts index 401cc4ff2..2ef7683b3 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts @@ -94,7 +94,6 @@ function getDenomInfoFromKeys(ek: ExchangeKeysJson): DenomInfo[] { } const http = createPlatformHttpLib({ - allowHttp: true, enableThrottling: false, }); diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 22c8ce03c..88875d4fc 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -28,8 +28,7 @@ import { } from "@gnu-taler/taler-util"; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; import { - BankAccessApi, - BankApi, + BankAccessApiClient, WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import * as http from "node:http"; @@ -305,9 +304,11 @@ export async function runKycTest(t: GlobalTestState) { // Withdraw digital cash into the wallet. + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const amount = "TESTKUDOS:20"; - const user = await BankApi.createRandomBankUser(bank); - const wop = await BankAccessApi.createWithdrawalOperation(bank, user, amount); + const user = await bankClient.createRandomBankUser(); + const wop = await bankClient.createWithdrawalOperation(user.username, amount); // Hand it to the wallet @@ -332,7 +333,7 @@ export async function runKycTest(t: GlobalTestState) { // Confirm it - await BankApi.confirmWithdrawalOperation(bank, user, wop); + await bankClient.confirmWithdrawalOperation(user.username, wop); const kycNotificationCond = walletClient.waitForNotificationCond((x) => { if ( @@ -376,7 +377,6 @@ export async function runKycTest(t: GlobalTestState) { // which would usually done in the browser. const httpLib = createPlatformHttpLib({ - allowHttp: true, enableThrottling: false, }); const kycServerResp = await httpLib.fetch(kycUrl); diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index 70fa587e7..3ad11d82d 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -23,8 +23,7 @@ */ import { CoreApiResponse, MerchantApiClient } from "@gnu-taler/taler-util"; import { - BankAccessApi, - BankApi, + BankAccessApiClient, WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { defaultCoinConfig } from "../harness/denomStructures.js"; @@ -127,10 +126,11 @@ export async function runPaymentFaultTest(t: GlobalTestState) { // Create withdrawal operation - const user = await BankApi.createRandomBankUser(bank); - const wop = await BankAccessApi.createWithdrawalOperation( - bank, - user, + const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + + const user = await bankClient.createRandomBankUser(); + const wop = await bankClient.createWithdrawalOperation( + user.username, "TESTKUDOS:20", ); @@ -152,7 +152,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { // Confirm it - await BankApi.confirmWithdrawalOperation(bank, user, wop); + await bankClient.confirmWithdrawalOperation(user.username, wop); await wallet.runUntilDone(); diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index f4a7c020e..9b980acad 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -38,10 +38,9 @@ export async function runTippingTest(t: GlobalTestState) { const { walletClient, bank, exchange, merchant, exchangeBankAccount } = await createSimpleTestkudosEnvironmentV2(t); - const bankAccessApiClient = new BankAccessApiClient({ - allowHttp: true, - baseUrl: bank.bankAccessApiBaseUrl, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const mbu = await bankAccessApiClient.createRandomBankUser(); const merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl()); @@ -59,12 +58,15 @@ export async function runTippingTest(t: GlobalTestState) { exchangeBankAccount.accountPaytoUri, ); - const wireGatewayApiClient = new WireGatewayApiClient({ - wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl, - accountName: exchangeBankAccount.accountName, - accountPassword: exchangeBankAccount.accountPassword, - allowHttp: true, - }); + const wireGatewayApiClient = new WireGatewayApiClient( + exchangeBankAccount.wireGatewayApiBaseUrl, + { + auth: { + username: exchangeBankAccount.accountName, + password: exchangeBankAccount.accountPassword, + }, + }, + ); await wireGatewayApiClient.adminAddIncoming({ amount: "TESTKUDOS:10", diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index 3315a71d4..9b35884f0 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -123,10 +123,9 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { skipDefaults: true, }); - const bankAccessApiClient = new BankAccessApiClient({ - allowHttp: true, - baseUrl: bank.bankAccessApiBaseUrl, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); const wop = await bankAccessApiClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts index 1ba180fc1..c62b98623 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts @@ -36,10 +36,9 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient({ - allowHttp: true, - baseUrl: bank.bankAccessApiBaseUrl, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); const wop = await bankAccessApiClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts index 61687ec02..76c973a12 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -19,7 +19,10 @@ */ import { GlobalTestState } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; -import { BankAccessApiClient, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { + BankAccessApiClient, + WalletApiOperation, +} from "@gnu-taler/taler-wallet-core"; import { j2s, NotificationType, @@ -40,10 +43,9 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient({ - allowHttp: true, - baseUrl: bank.bankAccessApiBaseUrl, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); const wop = await bankAccessApiClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index 34dfb8fc9..9f4631c7e 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -110,10 +110,9 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) { const amount = "TESTKUDOS:7.5"; - const bankAccessApiClient = new BankAccessApiClient({ - allowHttp: true, - baseUrl: bank.bankAccessApiBaseUrl, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); const wop = await bankAccessApiClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts index d49235f89..324b8abc5 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts @@ -39,10 +39,9 @@ export async function runWithdrawalManualTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient({ - baseUrl: bank.bankAccessApiBaseUrl, - allowHttp: true, - }); + const bankAccessApiClient = new BankAccessApiClient( + bank.bankAccessApiBaseUrl, + ); const user = await bankAccessApiClient.createRandomBankUser(); @@ -74,12 +73,15 @@ export async function runWithdrawalManualTest(t: GlobalTestState) { const reservePub: string = wres.reservePub; - const wireGatewayApiClient = new WireGatewayApiClient({ - wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl, - accountName: exchangeBankAccount.accountName, - accountPassword: exchangeBankAccount.accountPassword, - allowHttp: true, - }); + const wireGatewayApiClient = new WireGatewayApiClient( + exchangeBankAccount.wireGatewayApiBaseUrl, + { + auth: { + username: exchangeBankAccount.accountName, + password: exchangeBankAccount.accountPassword, + }, + }, + ); await wireGatewayApiClient.adminAddIncoming({ amount: "TESTKUDOS:10", diff --git a/packages/taler-harness/src/lint.ts b/packages/taler-harness/src/lint.ts index 6d8e679db..a45e6db9d 100644 --- a/packages/taler-harness/src/lint.ts +++ b/packages/taler-harness/src/lint.ts @@ -55,7 +55,6 @@ interface PubkeyConf { const httpLib = createPlatformHttpLib({ enableThrottling: false, - allowHttp: true, }); interface ShellResult { diff --git a/packages/taler-util/src/MerchantApiClient.ts b/packages/taler-util/src/MerchantApiClient.ts index cf4788d9e..cbdcb9fdf 100644 --- a/packages/taler-util/src/MerchantApiClient.ts +++ b/packages/taler-util/src/MerchantApiClient.ts @@ -138,10 +138,7 @@ export class MerchantApiClient { }; } - httpClient = createPlatformHttpLib({ - allowHttp: true, - enableThrottling: false, - }); + httpClient = createPlatformHttpLib(); async changeAuth(auth: MerchantAuthConfiguration): Promise { const url = new URL("private/auth", this.baseUrl); diff --git a/packages/taler-util/src/http-common.ts b/packages/taler-util/src/http-common.ts index 93cf9bba0..02ec8ce72 100644 --- a/packages/taler-util/src/http-common.ts +++ b/packages/taler-util/src/http-common.ts @@ -436,7 +436,10 @@ export function getExpiry( export interface HttpLibArgs { enableThrottling?: boolean; - allowHttp?: boolean; + /** + * Only allow HTTPS connections, not plain http. + */ + requireTls?: boolean; } export function encodeBody(body: any): ArrayBuffer { diff --git a/packages/taler-util/src/http-impl.node.ts b/packages/taler-util/src/http-impl.node.ts index 07648a28d..528d303be 100644 --- a/packages/taler-util/src/http-impl.node.ts +++ b/packages/taler-util/src/http-impl.node.ts @@ -63,11 +63,11 @@ const textDecoder = new TextDecoder(); export class HttpLibImpl implements HttpRequestLibrary { private throttle = new RequestThrottler(); private throttlingEnabled = true; - private allowHttp = false; + private requireTls = false; constructor(args?: HttpLibArgs) { this.throttlingEnabled = args?.enableThrottling ?? false; - this.allowHttp = args?.allowHttp ?? false; + this.requireTls = args?.requireTls ?? false; } /** @@ -94,7 +94,7 @@ export class HttpLibImpl implements HttpRequestLibrary { `request to origin ${parsedUrl.origin} was throttled`, ); } - if (!this.allowHttp && parsedUrl.protocol !== "https:") { + if (this.requireTls && parsedUrl.protocol !== "https:") { throw TalerError.fromDetail( TalerErrorCode.WALLET_NETWORK_ERROR, { diff --git a/packages/taler-util/src/http-impl.qtart.ts b/packages/taler-util/src/http-impl.qtart.ts index 3e076e96d..fb642ac89 100644 --- a/packages/taler-util/src/http-impl.qtart.ts +++ b/packages/taler-util/src/http-impl.qtart.ts @@ -41,11 +41,11 @@ const textDecoder = new TextDecoder(); export class HttpLibImpl implements HttpRequestLibrary { private throttle = new RequestThrottler(); private throttlingEnabled = true; - private allowHttp = false; + private requireTls = false; constructor(args?: HttpLibArgs) { this.throttlingEnabled = args?.enableThrottling ?? false; - this.allowHttp = args?.allowHttp ?? false; + this.requireTls = args?.requireTls ?? false; } /** @@ -72,7 +72,7 @@ export class HttpLibImpl implements HttpRequestLibrary { `request to origin ${parsedUrl.origin} was throttled`, ); } - if (!this.allowHttp && parsedUrl.protocol !== "https:") { + if (this.requireTls && parsedUrl.protocol !== "https:") { throw TalerError.fromDetail( TalerErrorCode.WALLET_NETWORK_ERROR, { diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index a0f44fb41..943283a36 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -244,7 +244,7 @@ async function createLocalWallet( const dbPath = walletCliArgs.wallet.walletDbFile ?? defaultWalletDbPath; const myHttpLib = createPlatformHttpLib({ enableThrottling: walletCliArgs.wallet.noThrottle ? false : true, - allowHttp: walletCliArgs.wallet.noHttp ? false : true, + requireTls: walletCliArgs.wallet.noHttp, }); const wallet = await createNativeWalletHost({ persistentStoragePath: dbPath !== ":memory:" ? dbPath : undefined, @@ -1259,10 +1259,7 @@ advancedCli help: "Run the 'bench-internal' benchmark", }) .action(async (args) => { - const myHttpLib = createPlatformHttpLib({ - enableThrottling: false, - allowHttp: true, - }); + const myHttpLib = createPlatformHttpLib(); const res = await createNativeWalletHost2({ // No persistent DB storage. persistentStoragePath: undefined, diff --git a/packages/taler-wallet-core/src/bank-api-client.ts b/packages/taler-wallet-core/src/bank-api-client.ts index 3174667f1..f1289525d 100644 --- a/packages/taler-wallet-core/src/bank-api-client.ts +++ b/packages/taler-wallet-core/src/bank-api-client.ts @@ -99,177 +99,9 @@ const codecForWithdrawalOperationInfo = (): Codec => .property("taler_withdraw_uri", codecForString()) .build("WithdrawalOperationInfo"); -/** - * @deprecated Use BankAccessApiClient or WireGatewayApi - */ -export namespace BankApi { - // FIXME: Move to BankAccessApi?! - export async function registerAccount( - bank: BankServiceHandle, - username: string, - password: string, - options: { - iban?: string; - }, - ): Promise { - const url = new URL("testing/register", bank.bankAccessApiBaseUrl); - const resp = await bank.http.postJson(url.href, { - username, - password, - iban: options?.iban, - }); - let paytoUri = `payto://x-taler-bank/localhost/${username}`; - if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) { - logger.error(`${j2s(await resp.json())}`); - throw TalerError.fromDetail( - TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, - { - httpStatusCode: resp.status, - }, - ); - } - try { - // Pybank has no body, thus this might throw. - const respJson = await resp.json(); - // LibEuFin demobank returns payto URI in response - if (respJson.paytoUri) { - paytoUri = respJson.paytoUri; - } - } catch (e) { - // Do nothing - } - return { - password, - username, - accountPaytoUri: paytoUri, - }; - } - - // FIXME: Move to BankAccessApi?! - export async function createRandomBankUser( - bank: BankServiceHandle, - ): Promise { - const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); - const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase(); - // FIXME: This is just a temporary workaround, because demobank is running out of short IBANs - const iban = generateIban("DE", 15); - return await registerAccount(bank, username, password, { - iban, - }); - } - - export async function confirmWithdrawalOperation( - bank: BankServiceHandle, - bankUser: BankUser, - wopi: WithdrawalOperationInfo, - ): Promise { - const url = new URL( - `accounts/${bankUser.username}/withdrawals/${wopi.withdrawal_id}/confirm`, - bank.bankAccessApiBaseUrl, - ); - logger.info(`confirming withdrawal operation via ${url.href}`); - const resp = await bank.http.postJson( - url.href, - {}, - { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }, - ); - - logger.info(`response status ${resp.status}`); - const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny()); - - // FIXME: We don't check the status here! - } - - export async function abortWithdrawalOperation( - bank: BankServiceHandle, - bankUser: BankUser, - wopi: WithdrawalOperationInfo, - ): Promise { - const url = new URL( - `accounts/${bankUser.username}/withdrawals/${wopi.withdrawal_id}/abort`, - bank.bankAccessApiBaseUrl, - ); - const resp = await bank.http.postJson( - url.href, - {}, - { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }, - ); - await readSuccessResponseJsonOrThrow(resp, codecForAny()); - } -} - -/** - * @deprecated use BankAccessApiClient - */ -export namespace BankAccessApi { - export async function getAccountBalance( - bank: BankServiceHandle, - bankUser: BankUser, - ): Promise { - const url = new URL( - `accounts/${bankUser.username}`, - bank.bankAccessApiBaseUrl, - ); - const resp = await bank.http.fetch(url.href, { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }); - return await resp.json(); - } - - export async function createWithdrawalOperation( - bank: BankServiceHandle, - bankUser: BankUser, - amount: string, - ): Promise { - const url = new URL( - `accounts/${bankUser.username}/withdrawals`, - bank.bankAccessApiBaseUrl, - ); - const resp = await bank.http.postJson( - url.href, - { - amount, - }, - { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }, - ); - return readSuccessResponseJsonOrThrow( - resp, - codecForWithdrawalOperationInfo(), - ); - } -} - export interface BankAccessApiClientArgs { - baseUrl: string; auth?: { username: string; password: string }; - enableThrottling?: boolean; - allowHttp?: boolean; + httpClient?: HttpRequestLibrary; } export interface BankAccessApiCreateTransactionRequest { @@ -278,11 +110,11 @@ export interface BankAccessApiCreateTransactionRequest { } export class WireGatewayApiClientArgs { - accountName: string; - accountPassword: string; - wireGatewayApiBaseUrl: string; - enableThrottling?: boolean; - allowHttp?: boolean; + auth?: { + username: string; + password: string; + }; + httpClient?: HttpRequestLibrary; } /** @@ -292,11 +124,21 @@ export class WireGatewayApiClientArgs { export class WireGatewayApiClient { httpLib; - constructor(private args: WireGatewayApiClientArgs) { - this.httpLib = createPlatformHttpLib({ - enableThrottling: !!args.enableThrottling, - allowHttp: !!args.allowHttp, - }); + constructor( + private baseUrl: string, + private args: WireGatewayApiClientArgs = {}, + ) { + this.httpLib = args.httpClient ?? createPlatformHttpLib(); + } + + private makeAuthHeader(): Record { + const auth = this.args.auth; + if (auth) { + return { + Authorization: makeBasicAuthHeader(auth.username, auth.password), + }; + } + return {}; } async adminAddIncoming(params: { @@ -304,7 +146,7 @@ export class WireGatewayApiClient { reservePub: string; debitAccountPayto: string; }): Promise { - let url = new URL(`admin/add-incoming`, this.args.wireGatewayApiBaseUrl); + let url = new URL(`admin/add-incoming`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", body: { @@ -312,12 +154,7 @@ export class WireGatewayApiClient { reserve_pub: params.reservePub, debit_account: params.debitAccountPayto, }, - headers: { - Authorization: makeBasicAuthHeader( - this.args.accountName, - this.args.accountPassword, - ), - }, + headers: this.makeAuthHeader(), }); logger.info(`add-incoming response status: ${resp.status}`); await checkSuccessResponseOrThrow(resp); @@ -331,11 +168,11 @@ export class WireGatewayApiClient { export class BankAccessApiClient { httpLib: HttpRequestLibrary; - constructor(private args: BankAccessApiClientArgs) { - this.httpLib = createPlatformHttpLib({ - enableThrottling: !!args.enableThrottling, - allowHttp: !!args.allowHttp, - }); + constructor( + private baseUrl: string, + private args: BankAccessApiClientArgs = {}, + ) { + this.httpLib = args.httpClient ?? createPlatformHttpLib(); } setAuth(auth: { username: string; password: string }) { @@ -355,12 +192,18 @@ export class BankAccessApiClient { }; } + async getAccountBalance( + username: string, + ): Promise { + const url = new URL(`accounts/${username}`, this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + headers: this.makeAuthHeader(), + }); + return await resp.json(); + } + async getTransactions(username: string): Promise { - const auth = this.args.auth; - const reqUrl = new URL( - `accounts/${username}/transactions`, - this.args.baseUrl, - ); + const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); const resp = await this.httpLib.fetch(reqUrl.href, { method: "GET", headers: { @@ -376,10 +219,7 @@ export class BankAccessApiClient { username: string, req: BankAccessApiCreateTransactionRequest, ): Promise { - const reqUrl = new URL( - `accounts/${username}/transactions`, - this.args.baseUrl, - ); + const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); const resp = await this.httpLib.fetch(reqUrl.href, { method: "POST", @@ -395,9 +235,9 @@ export class BankAccessApiClient { password: string, options: { iban?: string; - }, + } = {}, ): Promise { - const url = new URL("testing/register", this.args.baseUrl); + const url = new URL("testing/register", this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", body: { @@ -447,7 +287,7 @@ export class BankAccessApiClient { user: string, amount: string, ): Promise { - const url = new URL(`accounts/${user}/withdrawals`, this.args.baseUrl); + const url = new URL(`accounts/${user}/withdrawals`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", body: { @@ -467,7 +307,7 @@ export class BankAccessApiClient { ): Promise { const url = new URL( `accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`, - this.args.baseUrl, + this.baseUrl, ); logger.info(`confirming withdrawal operation via ${url.href}`); const resp = await this.httpLib.fetch(url.href, { @@ -488,7 +328,7 @@ export class BankAccessApiClient { ): Promise { const url = new URL( `accounts/${accountName}/withdrawals/${wopi.withdrawal_id}/abort`, - this.args.baseUrl, + this.baseUrl, ); const resp = await this.httpLib.fetch(url.href, { method: "POST", diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 5532345ae..357b7d289 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -48,24 +48,20 @@ import { parsePaytoUri, UnblindedSignature, } from "@gnu-taler/taler-util"; -import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; -import { DenominationRecord } from "./db.js"; -import { - BankAccessApi, - BankApi, - BankServiceHandle, -} from "./bank-api-client.js"; import { HttpRequestLibrary, readSuccessResponseJsonOrThrow, } from "@gnu-taler/taler-util/http"; +import { BankAccessApiClient, BankServiceHandle } from "./bank-api-client.js"; +import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; +import { DenominationRecord } from "./db.js"; +import { isWithdrawableDenom } from "./index.js"; +import { ExchangeInfo } from "./operations/exchanges.js"; +import { assembleRefreshRevealRequest } from "./operations/refresh.js"; import { getBankStatusUrl, getBankWithdrawalInfo, } from "./operations/withdraw.js"; -import { ExchangeInfo } from "./operations/exchanges.js"; -import { assembleRefreshRevealRequest } from "./operations/refresh.js"; -import { isWithdrawableDenom, WalletConfig } from "./index.js"; const logger = new Logger("dbless.ts"); @@ -125,10 +121,10 @@ export async function topupReserveWithDemobank( bankAccessApiBaseUrl: bankAccessApiBaseUrl, http, }; - const bankUser = await BankApi.createRandomBankUser(bankHandle); - const wopi = await BankAccessApi.createWithdrawalOperation( - bankHandle, - bankUser, + const bankClient = new BankAccessApiClient(bankAccessApiBaseUrl); + const bankUser = await bankClient.createRandomBankUser(); + const wopi = await bankClient.createWithdrawalOperation( + bankUser.username, amount, ); const bankInfo = await getBankWithdrawalInfo(http, wopi.taler_withdraw_uri); @@ -149,7 +145,7 @@ export async function topupReserveWithDemobank( httpResp, codecForBankWithdrawalOperationPostResponse(), ); - await BankApi.confirmWithdrawalOperation(bankHandle, bankUser, wopi); + await bankClient.confirmWithdrawalOperation(bankUser.username, wopi); } export async function withdrawCoin(args: { diff --git a/packages/taler-wallet-core/src/host-impl.node.ts b/packages/taler-wallet-core/src/host-impl.node.ts index 0626b9254..a6dae58a1 100644 --- a/packages/taler-wallet-core/src/host-impl.node.ts +++ b/packages/taler-wallet-core/src/host-impl.node.ts @@ -134,7 +134,7 @@ export async function createNativeWalletHost2( } else { myHttpLib = createPlatformHttpLib({ enableThrottling: true, - allowHttp: args.config?.features?.allowHttp, + requireTls: !args.config?.features?.allowHttp, }); } diff --git a/packages/taler-wallet-core/src/host-impl.qtart.ts b/packages/taler-wallet-core/src/host-impl.qtart.ts index 81dbe0acd..85f8df6e5 100644 --- a/packages/taler-wallet-core/src/host-impl.qtart.ts +++ b/packages/taler-wallet-core/src/host-impl.qtart.ts @@ -188,7 +188,7 @@ export async function createNativeWalletHost2( } else { myHttpLib = createPlatformHttpLib({ enableThrottling: true, - allowHttp: args.config?.features?.allowHttp, + requireTls: !args.config?.features?.allowHttp, }); } -- cgit v1.2.3 From b63937703ce1e269055497ee14ac90a28de2fc74 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 13:24:34 +0200 Subject: move bank API client to taler-util, update typescript config --- .vscode/tasks.json | 33 +- package.json | 3 +- packages/aml-backoffice-ui/package.json | 2 +- packages/aml-backoffice-ui/tsconfig.json | 15 +- packages/anastasis-cli/package.json | 6 +- packages/anastasis-cli/tsconfig.json | 6 +- packages/anastasis-core/package.json | 2 +- packages/anastasis-core/tsconfig.json | 2 +- packages/anastasis-webui/package.json | 2 +- packages/anastasis-webui/tsconfig.json | 6 +- packages/demobank-ui/package.json | 2 +- packages/demobank-ui/tsconfig.json | 15 +- packages/idb-bridge/package.json | 2 +- packages/idb-bridge/tsconfig.json | 4 +- packages/merchant-backend-ui/package.json | 2 +- packages/merchant-backoffice-ui/package.json | 4 +- packages/merchant-backoffice-ui/tsconfig.json | 117 ++- packages/pogen/package.json | 2 +- packages/pogen/tsconfig.json | 2 +- packages/taler-harness/package.json | 2 +- packages/taler-harness/src/harness/harness.ts | 17 +- packages/taler-harness/src/harness/helpers.ts | 24 +- packages/taler-harness/src/index.ts | 2 +- .../test-age-restrictions-merchant.ts | 12 +- .../src/integrationtests/test-bank-api.ts | 5 +- .../integrationtests/test-exchange-management.ts | 26 +- .../taler-harness/src/integrationtests/test-kyc.ts | 6 +- .../src/integrationtests/test-libeufin-basic.ts | 6 +- .../integrationtests/test-merchant-refund-api.ts | 4 +- .../src/integrationtests/test-payment-fault.ts | 7 +- .../src/integrationtests/test-tipping.ts | 4 +- .../integrationtests/test-wallet-notifications.ts | 6 +- .../integrationtests/test-withdrawal-abort-bank.ts | 7 +- .../test-withdrawal-bank-integrated.ts | 8 +- .../src/integrationtests/test-withdrawal-fees.ts | 7 +- .../src/integrationtests/test-withdrawal-manual.ts | 8 +- packages/taler-harness/tsconfig.json | 4 +- packages/taler-util/package.json | 6 +- packages/taler-util/src/bank-api-client.ts | 325 ++++++ packages/taler-util/src/http-common.ts | 2 +- packages/taler-util/src/index.ts | 1 + packages/taler-util/tsconfig.json | 4 +- packages/taler-wallet-cli/package.json | 4 +- packages/taler-wallet-cli/tsconfig.json | 4 +- packages/taler-wallet-core/package.json | 4 +- packages/taler-wallet-core/src/bank-api-client.ts | 340 ------- packages/taler-wallet-core/src/dbless.ts | 6 +- packages/taler-wallet-core/src/index.ts | 2 - packages/taler-wallet-core/src/wallet.ts | 6 +- packages/taler-wallet-core/tsconfig.json | 11 +- packages/taler-wallet-embedded/tsconfig.json | 4 +- packages/taler-wallet-webextension/package.json | 2 +- .../taler-wallet-webextension/src/wxBackend.ts | 11 +- packages/taler-wallet-webextension/tsconfig.json | 19 +- packages/web-util/package.json | 2 +- packages/web-util/tsconfig.json | 17 +- pnpm-lock.yaml | 1042 ++++++++++++++------ 57 files changed, 1279 insertions(+), 915 deletions(-) create mode 100644 packages/taler-util/src/bank-api-client.ts delete mode 100644 packages/taler-wallet-core/src/bank-api-client.ts (limited to 'packages/taler-wallet-core/src') diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 00c61e8a4..4c931ad04 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,18 +1,17 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "type": "typescript", - "tsconfig": "tsconfig.build.json", - "problemMatcher": [ - "$tsc" - ], - "group": { - "kind": "build", - "isDefault": true, - }, - } - ] -} \ No newline at end of file + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "typescript", + "tsconfig": "tsconfig.build.json", + "problemMatcher": ["$tsc"], + "group": { + "kind": "build", + "isDefault": true + }, + "label": "tsc: build - tsconfig.build.json" + } + ] +} diff --git a/package.json b/package.json index 9ce6d628e..e7b4b52d7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "eslint": "^8.29.0", "eslint-config-prettier": "^8.5.0", "nx": "15.0.1", - "prettier": "^2.8.8" + "prettier": "^2.8.8", + "typescript": "^5.2.2" } } diff --git a/packages/aml-backoffice-ui/package.json b/packages/aml-backoffice-ui/package.json index 3fde72b74..a761374df 100644 --- a/packages/aml-backoffice-ui/package.json +++ b/packages/aml-backoffice-ui/package.json @@ -59,7 +59,7 @@ "postcss": "^8.4.23", "postcss-cli": "^10.1.0", "tailwindcss": "^3.3.2", - "typescript": "5.1.3" + "typescript": "5.2.2" }, "pogen": { "domain": "aml-backoffice" diff --git a/packages/aml-backoffice-ui/tsconfig.json b/packages/aml-backoffice-ui/tsconfig.json index cc5bdf396..9826fac07 100644 --- a/packages/aml-backoffice-ui/tsconfig.json +++ b/packages/aml-backoffice-ui/tsconfig.json @@ -1,12 +1,9 @@ { "compilerOptions": { /* Basic Options */ - "target": "ES5", - "module": "ES6", - "lib": [ - "DOM", - "ES2017" - ], + "target": "ES2020", + "module": "Node16", + "lib": ["DOM", "ES2020"], "allowJs": true /* Allow javascript files to be compiled. */, // "checkJs": true, /* Report errors in .js files. */ "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, @@ -45,7 +42,5 @@ /* Advanced Options */ "skipLibCheck": true /* Skip type checking of declaration files. */ }, - "include": [ - "src/**/*" - ] -} \ No newline at end of file + "include": ["src/**/*"] +} diff --git a/packages/anastasis-cli/package.json b/packages/anastasis-cli/package.json index 2bbf32c3b..55af7cc06 100644 --- a/packages/anastasis-cli/package.json +++ b/packages/anastasis-cli/package.json @@ -33,12 +33,12 @@ "@types/node": "^18.11.17", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "typedoc": "^0.24.8", - "typescript": "^5.1.3" + "typedoc": "^0.25.1", + "typescript": "^5.2.2" }, "dependencies": { - "@gnu-taler/taler-util": "workspace:*", "@gnu-taler/anastasis-core": "workspace:*", + "@gnu-taler/taler-util": "workspace:*", "tslib": "^2.5.3" } } diff --git a/packages/anastasis-cli/tsconfig.json b/packages/anastasis-cli/tsconfig.json index 83da34277..7675edfbc 100644 --- a/packages/anastasis-cli/tsconfig.json +++ b/packages/anastasis-cli/tsconfig.json @@ -2,11 +2,11 @@ "compileOnSave": true, "compilerOptions": { "composite": true, - "target": "ES2018", - "module": "ESNext", + "target": "ES2020", + "module": "Node16", "moduleResolution": "Node16", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "strict": true, diff --git a/packages/anastasis-core/package.json b/packages/anastasis-core/package.json index c3a7106fb..aa182e047 100644 --- a/packages/anastasis-core/package.json +++ b/packages/anastasis-core/package.json @@ -18,7 +18,7 @@ "devDependencies": { "ava": "^4.3.3", "rimraf": "^3.0.2", - "typescript": "^5.1.3" + "typescript": "^5.2.2" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/anastasis-core/tsconfig.json b/packages/anastasis-core/tsconfig.json index 44a159836..a12f2e641 100644 --- a/packages/anastasis-core/tsconfig.json +++ b/packages/anastasis-core/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "composite": true, "target": "ES2020", - "module": "ESNext", + "module": "Node16", "moduleResolution": "Node16", "sourceMap": true, "lib": ["ES2020"], diff --git a/packages/anastasis-webui/package.json b/packages/anastasis-webui/package.json index eff5ba04d..efee9633e 100644 --- a/packages/anastasis-webui/package.json +++ b/packages/anastasis-webui/package.json @@ -44,6 +44,6 @@ "chai": "^4.3.6", "mocha": "^9.2.0", "sass": "1.56.1", - "typescript": "^5.1.3" + "typescript": "^5.2.2" } } diff --git a/packages/anastasis-webui/tsconfig.json b/packages/anastasis-webui/tsconfig.json index 642c34f5a..9e52f2b7e 100644 --- a/packages/anastasis-webui/tsconfig.json +++ b/packages/anastasis-webui/tsconfig.json @@ -1,11 +1,11 @@ { "compilerOptions": { /* Basic Options */ - "target": "ES5", - "module": "ES6", + "target": "ES2020", + "module": "Node16", "lib": [ "DOM", - "ES2017" + "ES2020" ], "allowJs": true /* Allow javascript files to be compiled. */, // "checkJs": true, /* Report errors in .js files. */ diff --git a/packages/demobank-ui/package.json b/packages/demobank-ui/package.json index a584bbf35..d33fae709 100644 --- a/packages/demobank-ui/package.json +++ b/packages/demobank-ui/package.json @@ -60,7 +60,7 @@ "po2json": "^0.4.5", "preact-render-to-string": "^5.2.6", "sass": "1.56.1", - "typescript": "5.1.3" + "typescript": "5.2.2" }, "pogen": { "domain": "bank" diff --git a/packages/demobank-ui/tsconfig.json b/packages/demobank-ui/tsconfig.json index abb9a9f36..9826fac07 100644 --- a/packages/demobank-ui/tsconfig.json +++ b/packages/demobank-ui/tsconfig.json @@ -1,12 +1,9 @@ { "compilerOptions": { /* Basic Options */ - "target": "ES5", - "module": "ES6", - "lib": [ - "DOM", - "ES2016" - ], + "target": "ES2020", + "module": "Node16", + "lib": ["DOM", "ES2020"], "allowJs": true /* Allow javascript files to be compiled. */, // "checkJs": true, /* Report errors in .js files. */ "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, @@ -45,7 +42,5 @@ /* Advanced Options */ "skipLibCheck": true /* Skip type checking of declaration files. */ }, - "include": [ - "src/**/*" - ] -} \ No newline at end of file + "include": ["src/**/*"] +} diff --git a/packages/idb-bridge/package.json b/packages/idb-bridge/package.json index 1c9c46b02..ce64314ff 100644 --- a/packages/idb-bridge/package.json +++ b/packages/idb-bridge/package.json @@ -29,7 +29,7 @@ "ava": "^5.3.1", "prettier": "^2.8.8", "rimraf": "^5.0.1", - "typescript": "^5.1.6" + "typescript": "^5.2.2" }, "dependencies": { "tslib": "^2.6.0" diff --git a/packages/idb-bridge/tsconfig.json b/packages/idb-bridge/tsconfig.json index 19e9c2a74..44a27284b 100644 --- a/packages/idb-bridge/tsconfig.json +++ b/packages/idb-bridge/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "composite": true, - "lib": ["es6"], - "module": "ES2020", + "lib": ["ES2020"], + "module": "Node16", "moduleResolution": "Node16", "target": "ES2020", "allowJs": true, diff --git a/packages/merchant-backend-ui/package.json b/packages/merchant-backend-ui/package.json index 23e5007e9..03e64308c 100644 --- a/packages/merchant-backend-ui/package.json +++ b/packages/merchant-backend-ui/package.json @@ -65,6 +65,6 @@ "sirv-cli": "^1.0.11", "ts-node": "^10.9.1", "tslib": "2.5.3", - "typescript": "5.1.3" + "typescript": "5.2.2" } } diff --git a/packages/merchant-backoffice-ui/package.json b/packages/merchant-backoffice-ui/package.json index 3d568a502..12aeb4b0e 100644 --- a/packages/merchant-backoffice-ui/package.json +++ b/packages/merchant-backoffice-ui/package.json @@ -75,8 +75,8 @@ "rimraf": "^3.0.2", "sass": "1.56.1", "source-map-support": "^0.5.21", - "typedoc": "^0.24.8", - "typescript": "5.1.3" + "typedoc": "^0.25.1", + "typescript": "5.2.2" }, "pogen": { "domain": "taler-merchant-backoffice" diff --git a/packages/merchant-backoffice-ui/tsconfig.json b/packages/merchant-backoffice-ui/tsconfig.json index 02c562f96..396f1e9e7 100644 --- a/packages/merchant-backoffice-ui/tsconfig.json +++ b/packages/merchant-backoffice-ui/tsconfig.json @@ -1,61 +1,58 @@ { - "compilerOptions": { - /* Basic Options */ - "target": "ES6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "ESNext", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": [ - "es2021", - "dom" - ], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "jsxFactory": "h", /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */ - "jsxFragmentFactory": "Fragment", // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - /* Module Resolution Options */ - "moduleResolution": "node16", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "esModuleInterop": true, /* */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */ - }, - "include": [ - "src/**/*", - "tests/**/*" - ] -} \ No newline at end of file + "compilerOptions": { + /* Basic Options */ + "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, + "module": "Node16" /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "lib": [ + "es2020", + "dom" + ] /* Specify library files to be included in the compilation: */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, + "jsxFactory": "h" /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */, + "jsxFragmentFactory": "Fragment", // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + "noEmit": true /* Do not emit outputs. */, + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node16" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "esModuleInterop": true /* */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "skipLibCheck": true /* Skip type checking of declaration files. */ + }, + "include": ["src/**/*", "tests/**/*"] +} diff --git a/packages/pogen/package.json b/packages/pogen/package.json index ae1dfac3b..9160e699c 100644 --- a/packages/pogen/package.json +++ b/packages/pogen/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "po2json": "^0.4.5", - "typescript": "^5.1.3" + "typescript": "^5.2.2" }, "dependencies": { "@types/node": "^18.11.17", diff --git a/packages/pogen/tsconfig.json b/packages/pogen/tsconfig.json index 68225832d..74cdc6ad7 100644 --- a/packages/pogen/tsconfig.json +++ b/packages/pogen/tsconfig.json @@ -7,7 +7,7 @@ "incremental": true, "moduleResolution": "node", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "types": ["node"] }, "include": ["src/**/*.ts"] diff --git a/packages/taler-harness/package.json b/packages/taler-harness/package.json index 8916e5e9e..9f2b0d8e3 100644 --- a/packages/taler-harness/package.json +++ b/packages/taler-harness/package.json @@ -35,7 +35,7 @@ "esbuild": "^0.17.7", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "typescript": "^5.1.3" + "typescript": "^5.2.2" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index d0719b4f7..24e42099e 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -28,6 +28,7 @@ import { AccountAddDetails, AmountJson, Amounts, + BankAccessApiClient, Configuration, CoreApiResponse, Duration, @@ -46,13 +47,11 @@ import { stringToBytes, } from "@gnu-taler/taler-util"; import { + HttpRequestLibrary, createPlatformHttpLib, expectSuccessResponseOrThrow, } from "@gnu-taler/taler-util/http"; import { - BankAccessApiClient, - BankServiceHandle, - HarnessExchangeBankAccount, WalletCoreApiClient, WalletCoreRequestType, WalletCoreResponseType, @@ -569,6 +568,13 @@ class BankServiceBase { ) {} } +export interface HarnessExchangeBankAccount { + accountName: string; + accountPassword: string; + accountPaytoUri: string; + wireGatewayApiBaseUrl: string; +} + /** * Implementation of the bank service using the "taler-fakebank-run" tool. */ @@ -701,6 +707,11 @@ export class FakebankService // Use libeufin bank instead of pybank. const useLibeufinBank = false; +export interface BankServiceHandle { + readonly bankAccessApiBaseUrl: string; + readonly http: HttpRequestLibrary; +} + export type BankService = BankServiceHandle; export const BankService = FakebankService; diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index f92fd4dd9..9892e600b 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -25,21 +25,18 @@ */ import { AmountString, + BankAccessApiClient, ConfirmPayResultType, - MerchantContractTerms, Duration, - PreparePayResultType, - NotificationType, - WalletNotification, - TransactionMajorState, Logger, MerchantApiClient, + MerchantContractTerms, + NotificationType, + PreparePayResultType, + TransactionMajorState, + WalletNotification, } from "@gnu-taler/taler-util"; -import { - BankAccessApiClient, - HarnessExchangeBankAccount, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig, defaultCoinConfig } from "./denomStructures.js"; import { FaultInjectedExchangeService, @@ -51,16 +48,17 @@ import { ExchangeService, ExchangeServiceInterface, FakebankService, - getPayto, GlobalTestState, + HarnessExchangeBankAccount, MerchantService, MerchantServiceInterface, - setupDb, - setupSharedDb, WalletCli, WalletClient, WalletService, WithAuthorization, + getPayto, + setupDb, + setupSharedDb, } from "./harness.js"; import * as fs from "fs"; diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 185f6226d..534aec8c7 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -20,6 +20,7 @@ import { addPaytoQueryParams, Amounts, + BankAccessApiClient, Configuration, decodeCrock, j2s, @@ -31,7 +32,6 @@ import { import { clk } from "@gnu-taler/taler-util/clk"; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; import { - BankAccessApiClient, CryptoDispatcher, downloadExchangeInfo, SynchronousCryptoWorkerFactoryPlain, diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts index bff13ae40..7f936a479 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -17,11 +17,7 @@ /** * Imports. */ -import { - BankAccessApiClient, - WalletApiOperation, - WireGatewayApiClient, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { defaultCoinConfig } from "../harness/denomStructures.js"; import { getWireMethodForTest, GlobalTestState } from "../harness/harness.js"; import { @@ -30,7 +26,11 @@ import { makeTestPaymentV2, withdrawViaBankV2, } from "../harness/helpers.js"; -import { MerchantApiClient } from "@gnu-taler/taler-util"; +import { + BankAccessApiClient, + MerchantApiClient, + WireGatewayApiClient, +} from "@gnu-taler/taler-util"; /** * Run test for basic, bank-integrated withdrawal and payment. diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index afb06b61a..77a13b791 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -17,12 +17,13 @@ /** * Imports. */ -import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util"; import { BankAccessApiClient, CreditDebitIndicator, WireGatewayApiClient, -} from "@gnu-taler/taler-wallet-core"; + createEddsaKeyPair, + encodeCrock, +} from "@gnu-taler/taler-util"; import { defaultCoinConfig } from "../harness/denomStructures.js"; import { BankService, diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index 19be7c962..9338a8988 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -18,29 +18,27 @@ * Imports. */ import { - GlobalTestState, - WalletCli, - setupDb, - BankService, - ExchangeService, - MerchantService, - getPayto, -} from "../harness/harness.js"; -import { - WalletApiOperation, BankAccessApiClient, -} from "@gnu-taler/taler-wallet-core"; -import { ExchangesListResponse, - URL, TalerErrorCode, + URL, j2s, } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { defaultCoinConfig } from "../harness/denomStructures.js"; import { FaultInjectedExchangeService, FaultInjectionResponseContext, } from "../harness/faultInjection.js"; -import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { + BankService, + ExchangeService, + GlobalTestState, + MerchantService, + WalletCli, + getPayto, + setupDb, +} from "../harness/harness.js"; /** * Test if the wallet handles outdated exchange versions correctly. diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 88875d4fc..1f7358b66 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -18,6 +18,7 @@ * Imports. */ import { + BankAccessApiClient, Duration, j2s, Logger, @@ -27,10 +28,7 @@ import { TransactionType, } from "@gnu-taler/taler-util"; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; -import { - BankAccessApiClient, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import * as http from "node:http"; import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts index 20fa34437..d87278197 100644 --- a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts +++ b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts @@ -22,15 +22,13 @@ import { Duration, MerchantContractTerms, } from "@gnu-taler/taler-util"; -import { - HarnessExchangeBankAccount, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { DbInfo, ExchangeService, GlobalTestState, + HarnessExchangeBankAccount, MerchantService, WalletClient, setupDb, diff --git a/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts b/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts index 369f261dd..1b69b9de6 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts @@ -24,11 +24,9 @@ import { URL, durationFromSpec, } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { BankServiceHandle, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; -import { ExchangeServiceInterface, GlobalTestState, MerchantServiceInterface, diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index 3ad11d82d..e57427fac 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -21,11 +21,12 @@ /** * Imports. */ -import { CoreApiResponse, MerchantApiClient } from "@gnu-taler/taler-util"; import { BankAccessApiClient, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; + CoreApiResponse, + MerchantApiClient, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { defaultCoinConfig } from "../harness/denomStructures.js"; import { FaultInjectedExchangeService, diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index 9b980acad..4140311ab 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -18,13 +18,13 @@ * Imports. */ import { + BankAccessApiClient, MerchantApiClient, TransactionMajorState, + WireGatewayApiClient, } from "@gnu-taler/taler-util"; import { - BankAccessApiClient, WalletApiOperation, - WireGatewayApiClient, } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState, getWireMethodForTest } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index 9b35884f0..9a0eb77ae 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -18,14 +18,12 @@ * Imports. */ import { + BankAccessApiClient, Duration, NotificationType, TransactionMajorState, } from "@gnu-taler/taler-util"; -import { - BankAccessApiClient, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { ExchangeService, diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts index c62b98623..aa5e2b770 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts @@ -17,11 +17,8 @@ /** * Imports. */ -import { TalerErrorCode } from "@gnu-taler/taler-util"; -import { - WalletApiOperation, - BankAccessApiClient, -} from "@gnu-taler/taler-wallet-core"; +import { BankAccessApiClient, TalerErrorCode } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts index 76c973a12..232b6d7c2 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -17,13 +17,8 @@ /** * Imports. */ -import { GlobalTestState } from "../harness/harness.js"; -import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; import { BankAccessApiClient, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; -import { j2s, NotificationType, TransactionMajorState, @@ -31,6 +26,9 @@ import { TransactionType, WithdrawalType, } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { GlobalTestState } from "../harness/harness.js"; +import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; /** * Run test for basic, bank-integrated withdrawal. diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index 9f4631c7e..bc2946a18 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -17,11 +17,8 @@ /** * Imports. */ -import { j2s } from "@gnu-taler/taler-util"; -import { - BankAccessApiClient, - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { BankAccessApiClient, j2s } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig } from "../harness/denomStructures.js"; import { BankService, diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts index 324b8abc5..1d98cd46e 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts @@ -17,12 +17,14 @@ /** * Imports. */ -import { AbsoluteTime, Logger, j2s } from "@gnu-taler/taler-util"; import { + AbsoluteTime, BankAccessApiClient, - WalletApiOperation, + Logger, WireGatewayApiClient, -} from "@gnu-taler/taler-wallet-core"; + j2s, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; diff --git a/packages/taler-harness/tsconfig.json b/packages/taler-harness/tsconfig.json index d022b16e8..ece83a85f 100644 --- a/packages/taler-harness/tsconfig.json +++ b/packages/taler-harness/tsconfig.json @@ -3,10 +3,10 @@ "compilerOptions": { "composite": true, "target": "ES2018", - "module": "ESNext", + "module": "Node16", "moduleResolution": "Node16", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "strict": true, diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json index 6ac9a2689..0bb98767d 100644 --- a/packages/taler-util/package.json +++ b/packages/taler-util/package.json @@ -68,14 +68,14 @@ "esbuild": "^0.17.7", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "typescript": "^5.1.3" + "typescript": "^5.2.2" }, "dependencies": { "big-integer": "^1.6.51", "fflate": "^0.7.4", + "hash-wasm": "^4.9.0", "jed": "^1.1.1", - "tslib": "^2.5.3", - "hash-wasm": "^4.9.0" + "tslib": "^2.5.3" }, "ava": { "files": [ diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts new file mode 100644 index 000000000..cc4123500 --- /dev/null +++ b/packages/taler-util/src/bank-api-client.ts @@ -0,0 +1,325 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Client for the Taler (demo-)bank. + */ + +/** + * Imports. + */ +import { + AmountString, + base64FromArrayBuffer, + buildCodecForObject, + Codec, + codecForAny, + codecForString, + encodeCrock, + generateIban, + getRandomBytes, + j2s, + Logger, + stringToBytes, + TalerError, + TalerErrorCode, +} from "@gnu-taler/taler-util"; +import { + checkSuccessResponseOrThrow, + createPlatformHttpLib, + HttpRequestLibrary, + readSuccessResponseJsonOrThrow, +} from "@gnu-taler/taler-util/http"; + +const logger = new Logger("bank-api-client.ts"); + +export enum CreditDebitIndicator { + Credit = "credit", + Debit = "debit", +} + +export interface BankAccountBalanceResponse { + balance: { + amount: AmountString; + credit_debit_indicator: CreditDebitIndicator; + }; +} + +export interface BankUser { + username: string; + password: string; + accountPaytoUri: string; +} + +export interface WithdrawalOperationInfo { + withdrawal_id: string; + taler_withdraw_uri: string; +} + +/** + * Helper function to generate the "Authorization" HTTP header. + */ +function makeBasicAuthHeader(username: string, password: string): string { + const auth = `${username}:${password}`; + const authEncoded: string = base64FromArrayBuffer(stringToBytes(auth)); + return `Basic ${authEncoded}`; +} + +const codecForWithdrawalOperationInfo = (): Codec => + buildCodecForObject() + .property("withdrawal_id", codecForString()) + .property("taler_withdraw_uri", codecForString()) + .build("WithdrawalOperationInfo"); + +export interface BankAccessApiClientArgs { + auth?: { username: string; password: string }; + httpClient?: HttpRequestLibrary; +} + +export interface BankAccessApiCreateTransactionRequest { + amount: AmountString; + paytoUri: string; +} + +export class WireGatewayApiClientArgs { + auth?: { + username: string; + password: string; + }; + httpClient?: HttpRequestLibrary; +} + +/** + * This API look like it belongs to harness + * but it will be nice to have in utils to be used by others + */ +export class WireGatewayApiClient { + httpLib; + + constructor( + private baseUrl: string, + private args: WireGatewayApiClientArgs = {}, + ) { + this.httpLib = args.httpClient ?? createPlatformHttpLib(); + } + + private makeAuthHeader(): Record { + const auth = this.args.auth; + if (auth) { + return { + Authorization: makeBasicAuthHeader(auth.username, auth.password), + }; + } + return {}; + } + + async adminAddIncoming(params: { + amount: string; + reservePub: string; + debitAccountPayto: string; + }): Promise { + let url = new URL(`admin/add-incoming`, this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: { + amount: params.amount, + reserve_pub: params.reservePub, + debit_account: params.debitAccountPayto, + }, + headers: this.makeAuthHeader(), + }); + logger.info(`add-incoming response status: ${resp.status}`); + await checkSuccessResponseOrThrow(resp); + } +} + +/** + * This API look like it belongs to harness + * but it will be nice to have in utils to be used by others + */ +export class BankAccessApiClient { + httpLib: HttpRequestLibrary; + + constructor( + private baseUrl: string, + private args: BankAccessApiClientArgs = {}, + ) { + this.httpLib = args.httpClient ?? createPlatformHttpLib(); + } + + setAuth(auth: { username: string; password: string }) { + this.args.auth = auth; + } + + private makeAuthHeader(): Record { + if (!this.args.auth) { + return {}; + } + const authHeaderValue = makeBasicAuthHeader( + this.args.auth.username, + this.args.auth.password, + ); + return { + Authorization: authHeaderValue, + }; + } + + async getAccountBalance( + username: string, + ): Promise { + const url = new URL(`accounts/${username}`, this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + headers: this.makeAuthHeader(), + }); + return await resp.json(); + } + + async getTransactions(username: string): Promise { + const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); + const resp = await this.httpLib.fetch(reqUrl.href, { + method: "GET", + headers: { + ...this.makeAuthHeader(), + }, + }); + + const res = await readSuccessResponseJsonOrThrow(resp, codecForAny()); + logger.info(`result: ${j2s(res)}`); + } + + async createTransaction( + username: string, + req: BankAccessApiCreateTransactionRequest, + ): Promise { + const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); + + const resp = await this.httpLib.fetch(reqUrl.href, { + method: "POST", + body: req, + headers: this.makeAuthHeader(), + }); + + return await readSuccessResponseJsonOrThrow(resp, codecForAny()); + } + + async registerAccount( + username: string, + password: string, + options: { + iban?: string; + } = {}, + ): Promise { + const url = new URL("testing/register", this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: { + username, + password, + iban: options?.iban, + }, + }); + let paytoUri = `payto://x-taler-bank/localhost/${username}`; + if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) { + logger.error(`${j2s(await resp.json())}`); + throw TalerError.fromDetail( + TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, + { + httpStatusCode: resp.status, + }, + ); + } + try { + // Pybank has no body, thus this might throw. + const respJson = await resp.json(); + // LibEuFin demobank returns payto URI in response + if (respJson.paytoUri) { + paytoUri = respJson.paytoUri; + } + } catch (e) { + // Do nothing + } + return { + password, + username, + accountPaytoUri: paytoUri, + }; + } + + async createRandomBankUser(): Promise { + const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + // FIXME: This is just a temporary workaround, because demobank is running out of short IBANs + const iban = generateIban("DE", 15); + return await this.registerAccount(username, password, { + iban, + }); + } + + async createWithdrawalOperation( + user: string, + amount: string, + ): Promise { + const url = new URL(`accounts/${user}/withdrawals`, this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: { + amount, + }, + headers: this.makeAuthHeader(), + }); + return readSuccessResponseJsonOrThrow( + resp, + codecForWithdrawalOperationInfo(), + ); + } + + async confirmWithdrawalOperation( + username: string, + wopi: WithdrawalOperationInfo, + ): Promise { + const url = new URL( + `accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`, + this.baseUrl, + ); + logger.info(`confirming withdrawal operation via ${url.href}`); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: {}, + headers: this.makeAuthHeader(), + }); + + logger.info(`response status ${resp.status}`); + const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny()); + + // FIXME: We don't check the status here! + } + + async abortWithdrawalOperation( + accountName: string, + wopi: WithdrawalOperationInfo, + ): Promise { + const url = new URL( + `accounts/${accountName}/withdrawals/${wopi.withdrawal_id}/abort`, + this.baseUrl, + ); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: {}, + headers: this.makeAuthHeader(), + }); + await readSuccessResponseJsonOrThrow(resp, codecForAny()); + } +} diff --git a/packages/taler-util/src/http-common.ts b/packages/taler-util/src/http-common.ts index 02ec8ce72..f25705545 100644 --- a/packages/taler-util/src/http-common.ts +++ b/packages/taler-util/src/http-common.ts @@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL3.0-or-later */ -import { CancellationToken } from "./CancellationToken.js"; +import type { CancellationToken } from "./CancellationToken.js"; import { Codec } from "./codec.js"; import { j2s } from "./helpers.js"; import { diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts index 0b75619ab..568e2f438 100644 --- a/packages/taler-util/src/index.ts +++ b/packages/taler-util/src/index.ts @@ -41,3 +41,4 @@ export * from "./iban.js"; export * from "./transaction-test-data.js"; export * from "./libeufin-api-types.js"; export * from "./MerchantApiClient.js"; +export * from "./bank-api-client.js"; diff --git a/packages/taler-util/tsconfig.json b/packages/taler-util/tsconfig.json index 34f35d253..2e97142ce 100644 --- a/packages/taler-util/tsconfig.json +++ b/packages/taler-util/tsconfig.json @@ -5,8 +5,8 @@ "declaration": true, "declarationMap": false, "target": "ES2020", - "module": "ES2020", - "moduleResolution": "node16", + "module": "Node16", + "moduleResolution": "Node16", "sourceMap": true, "lib": ["ES2020"], "types": ["node"], diff --git a/packages/taler-wallet-cli/package.json b/packages/taler-wallet-cli/package.json index 06df1da76..6196c8971 100644 --- a/packages/taler-wallet-cli/package.json +++ b/packages/taler-wallet-cli/package.json @@ -33,8 +33,8 @@ "@types/node": "^18.11.17", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "typedoc": "^0.24.8", - "typescript": "^5.1.3" + "typedoc": "^0.25.1", + "typescript": "^5.2.2" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/taler-wallet-cli/tsconfig.json b/packages/taler-wallet-cli/tsconfig.json index 100339e43..42f0d88a8 100644 --- a/packages/taler-wallet-cli/tsconfig.json +++ b/packages/taler-wallet-cli/tsconfig.json @@ -3,10 +3,10 @@ "compilerOptions": { "composite": true, "target": "ES2018", - "module": "ESNext", + "module": "Node16", "moduleResolution": "Node16", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "strict": true, diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json index 9cd6f6466..fda7b6081 100644 --- a/packages/taler-wallet-core/package.json +++ b/packages/taler-wallet-core/package.json @@ -65,8 +65,8 @@ "po2json": "^0.4.5", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "typedoc": "^0.24.8", - "typescript": "^5.1.3" + "typedoc": "^0.25.1", + "typescript": "^5.2.2" }, "dependencies": { "@gnu-taler/idb-bridge": "workspace:*", diff --git a/packages/taler-wallet-core/src/bank-api-client.ts b/packages/taler-wallet-core/src/bank-api-client.ts deleted file mode 100644 index f1289525d..000000000 --- a/packages/taler-wallet-core/src/bank-api-client.ts +++ /dev/null @@ -1,340 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see - */ - -/** - * Client for the Taler (demo-)bank. - */ - -/** - * Imports. - */ -import { - AmountString, - base64FromArrayBuffer, - buildCodecForObject, - Codec, - codecForAny, - codecForString, - encodeCrock, - generateIban, - getRandomBytes, - j2s, - Logger, - stringToBytes, - TalerError, - TalerErrorCode, -} from "@gnu-taler/taler-util"; -import { - checkSuccessResponseOrThrow, - createPlatformHttpLib, - HttpRequestLibrary, - readSuccessResponseJsonOrThrow, -} from "@gnu-taler/taler-util/http"; - -const logger = new Logger("bank-api-client.ts"); - -export enum CreditDebitIndicator { - Credit = "credit", - Debit = "debit", -} - -export interface BankAccountBalanceResponse { - balance: { - amount: AmountString; - credit_debit_indicator: CreditDebitIndicator; - }; -} - -export interface BankServiceHandle { - readonly bankAccessApiBaseUrl: string; - readonly http: HttpRequestLibrary; -} - -export interface BankUser { - username: string; - password: string; - accountPaytoUri: string; -} - -export interface WithdrawalOperationInfo { - withdrawal_id: string; - taler_withdraw_uri: string; -} - -/** - * FIXME: Rename, this is not part of the integration test harness anymore. - */ -export interface HarnessExchangeBankAccount { - accountName: string; - accountPassword: string; - accountPaytoUri: string; - wireGatewayApiBaseUrl: string; -} - -/** - * Helper function to generate the "Authorization" HTTP header. - */ -function makeBasicAuthHeader(username: string, password: string): string { - const auth = `${username}:${password}`; - const authEncoded: string = base64FromArrayBuffer(stringToBytes(auth)); - return `Basic ${authEncoded}`; -} - -const codecForWithdrawalOperationInfo = (): Codec => - buildCodecForObject() - .property("withdrawal_id", codecForString()) - .property("taler_withdraw_uri", codecForString()) - .build("WithdrawalOperationInfo"); - -export interface BankAccessApiClientArgs { - auth?: { username: string; password: string }; - httpClient?: HttpRequestLibrary; -} - -export interface BankAccessApiCreateTransactionRequest { - amount: AmountString; - paytoUri: string; -} - -export class WireGatewayApiClientArgs { - auth?: { - username: string; - password: string; - }; - httpClient?: HttpRequestLibrary; -} - -/** - * This API look like it belongs to harness - * but it will be nice to have in utils to be used by others - */ -export class WireGatewayApiClient { - httpLib; - - constructor( - private baseUrl: string, - private args: WireGatewayApiClientArgs = {}, - ) { - this.httpLib = args.httpClient ?? createPlatformHttpLib(); - } - - private makeAuthHeader(): Record { - const auth = this.args.auth; - if (auth) { - return { - Authorization: makeBasicAuthHeader(auth.username, auth.password), - }; - } - return {}; - } - - async adminAddIncoming(params: { - amount: string; - reservePub: string; - debitAccountPayto: string; - }): Promise { - let url = new URL(`admin/add-incoming`, this.baseUrl); - const resp = await this.httpLib.fetch(url.href, { - method: "POST", - body: { - amount: params.amount, - reserve_pub: params.reservePub, - debit_account: params.debitAccountPayto, - }, - headers: this.makeAuthHeader(), - }); - logger.info(`add-incoming response status: ${resp.status}`); - await checkSuccessResponseOrThrow(resp); - } -} - -/** - * This API look like it belongs to harness - * but it will be nice to have in utils to be used by others - */ -export class BankAccessApiClient { - httpLib: HttpRequestLibrary; - - constructor( - private baseUrl: string, - private args: BankAccessApiClientArgs = {}, - ) { - this.httpLib = args.httpClient ?? createPlatformHttpLib(); - } - - setAuth(auth: { username: string; password: string }) { - this.args.auth = auth; - } - - private makeAuthHeader(): Record { - if (!this.args.auth) { - return {}; - } - const authHeaderValue = makeBasicAuthHeader( - this.args.auth.username, - this.args.auth.password, - ); - return { - Authorization: authHeaderValue, - }; - } - - async getAccountBalance( - username: string, - ): Promise { - const url = new URL(`accounts/${username}`, this.baseUrl); - const resp = await this.httpLib.fetch(url.href, { - headers: this.makeAuthHeader(), - }); - return await resp.json(); - } - - async getTransactions(username: string): Promise { - const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); - const resp = await this.httpLib.fetch(reqUrl.href, { - method: "GET", - headers: { - ...this.makeAuthHeader(), - }, - }); - - const res = await readSuccessResponseJsonOrThrow(resp, codecForAny()); - logger.info(`result: ${j2s(res)}`); - } - - async createTransaction( - username: string, - req: BankAccessApiCreateTransactionRequest, - ): Promise { - const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); - - const resp = await this.httpLib.fetch(reqUrl.href, { - method: "POST", - body: req, - headers: this.makeAuthHeader(), - }); - - return await readSuccessResponseJsonOrThrow(resp, codecForAny()); - } - - async registerAccount( - username: string, - password: string, - options: { - iban?: string; - } = {}, - ): Promise { - const url = new URL("testing/register", this.baseUrl); - const resp = await this.httpLib.fetch(url.href, { - method: "POST", - body: { - username, - password, - iban: options?.iban, - }, - }); - let paytoUri = `payto://x-taler-bank/localhost/${username}`; - if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) { - logger.error(`${j2s(await resp.json())}`); - throw TalerError.fromDetail( - TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, - { - httpStatusCode: resp.status, - }, - ); - } - try { - // Pybank has no body, thus this might throw. - const respJson = await resp.json(); - // LibEuFin demobank returns payto URI in response - if (respJson.paytoUri) { - paytoUri = respJson.paytoUri; - } - } catch (e) { - // Do nothing - } - return { - password, - username, - accountPaytoUri: paytoUri, - }; - } - - async createRandomBankUser(): Promise { - const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); - const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase(); - // FIXME: This is just a temporary workaround, because demobank is running out of short IBANs - const iban = generateIban("DE", 15); - return await this.registerAccount(username, password, { - iban, - }); - } - - async createWithdrawalOperation( - user: string, - amount: string, - ): Promise { - const url = new URL(`accounts/${user}/withdrawals`, this.baseUrl); - const resp = await this.httpLib.fetch(url.href, { - method: "POST", - body: { - amount, - }, - headers: this.makeAuthHeader(), - }); - return readSuccessResponseJsonOrThrow( - resp, - codecForWithdrawalOperationInfo(), - ); - } - - async confirmWithdrawalOperation( - username: string, - wopi: WithdrawalOperationInfo, - ): Promise { - const url = new URL( - `accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`, - this.baseUrl, - ); - logger.info(`confirming withdrawal operation via ${url.href}`); - const resp = await this.httpLib.fetch(url.href, { - method: "POST", - body: {}, - headers: this.makeAuthHeader(), - }); - - logger.info(`response status ${resp.status}`); - const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny()); - - // FIXME: We don't check the status here! - } - - async abortWithdrawalOperation( - accountName: string, - wopi: WithdrawalOperationInfo, - ): Promise { - const url = new URL( - `accounts/${accountName}/withdrawals/${wopi.withdrawal_id}/abort`, - this.baseUrl, - ); - const resp = await this.httpLib.fetch(url.href, { - method: "POST", - body: {}, - headers: this.makeAuthHeader(), - }); - await readSuccessResponseJsonOrThrow(resp, codecForAny()); - } -} diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 357b7d289..0aad477e4 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -52,7 +52,7 @@ import { HttpRequestLibrary, readSuccessResponseJsonOrThrow, } from "@gnu-taler/taler-util/http"; -import { BankAccessApiClient, BankServiceHandle } from "./bank-api-client.js"; +import { BankAccessApiClient } from "../../taler-util/src/bank-api-client.js"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { DenominationRecord } from "./db.js"; import { isWithdrawableDenom } from "./index.js"; @@ -117,10 +117,6 @@ export async function topupReserveWithDemobank( args: TopupReserveWithDemobankArgs, ) { const { http, bankAccessApiBaseUrl, amount, exchangeInfo, reservePub } = args; - const bankHandle: BankServiceHandle = { - bankAccessApiBaseUrl: bankAccessApiBaseUrl, - http, - }; const bankClient = new BankAccessApiClient(bankAccessApiBaseUrl); const bankUser = await bankClient.createRandomBankUser(); const wopi = await bankClient.createWithdrawalOperation( diff --git a/packages/taler-wallet-core/src/index.ts b/packages/taler-wallet-core/src/index.ts index d64f7d5e6..643d65620 100644 --- a/packages/taler-wallet-core/src/index.ts +++ b/packages/taler-wallet-core/src/index.ts @@ -44,8 +44,6 @@ export * from "./operations/backup/index.js"; export * from "./operations/exchanges.js"; -export * from "./bank-api-client.js"; - export * from "./operations/withdraw.js"; export * from "./operations/refresh.js"; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index f42365c00..9a3b8f235 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -129,10 +129,8 @@ import { codecForTestingSetTimetravelRequest, setDangerousTimetravel, } from "@gnu-taler/taler-util"; -import { - HttpRequestLibrary, - readSuccessResponseJsonOrThrow, -} from "@gnu-taler/taler-util/http"; +import type { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; +import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { CryptoDispatcher, diff --git a/packages/taler-wallet-core/tsconfig.json b/packages/taler-wallet-core/tsconfig.json index 8de28b3d8..663a4dd98 100644 --- a/packages/taler-wallet-core/tsconfig.json +++ b/packages/taler-wallet-core/tsconfig.json @@ -4,12 +4,12 @@ "composite": true, "declaration": true, "declarationMap": false, - "target": "ES2017", - "module": "ESNext", + "target": "ES2020", + "module": "Node16", "moduleResolution": "Node16", "resolveJsonModule": true, "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "resolvePackageJsonImports": true, "types": ["node"], "noImplicitReturns": true, @@ -33,8 +33,5 @@ "path": "../taler-util/" } ], - "include": [ - "src/**/*", - "src/*.json" - ] + "include": ["src/**/*", "src/*.json", "../taler-util/src/bank-api-client.ts"] } diff --git a/packages/taler-wallet-embedded/tsconfig.json b/packages/taler-wallet-embedded/tsconfig.json index 7b27ca6b7..e8b265fb9 100644 --- a/packages/taler-wallet-embedded/tsconfig.json +++ b/packages/taler-wallet-embedded/tsconfig.json @@ -5,10 +5,10 @@ "declaration": true, "declarationMap": true, "target": "ES6", - "module": "ESNext", + "module": "Node16", "moduleResolution": "Node16", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "strict": true, diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 040878529..f442b1509 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -64,7 +64,7 @@ "preact-cli": "^3.3.5", "preact-render-to-string": "^5.1.19", "rimraf": "^3.0.2", - "typescript": "5.1.3" + "typescript": "5.2.2" }, "nyc": { "include": [ diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index e7385abe5..d5f6ca2cd 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -51,14 +51,11 @@ import { importDb, openPromise, } from "@gnu-taler/taler-wallet-core"; -import { - MessageFromBackend, - MessageFromFrontend, - MessageResponse, -} from "./platform/api.js"; +import { MessageFromFrontend, MessageResponse } from "./platform/api.js"; import { platform } from "./platform/background.js"; import { ExtensionOperations } from "./taler-wallet-interaction-loader.js"; import { BackgroundOperations } from "./wxApi.js"; +import { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; /** * Currently active wallet instance. Might be unloaded and @@ -297,7 +294,7 @@ async function reinitWallet(): Promise { } currentDatabase = undefined; // setBadgeText({ text: "" }); - let httpLib; + let httpLib: HttpRequestLibrary; let cryptoWorker; let timer; @@ -318,7 +315,7 @@ async function reinitWallet(): Promise { logger.info("Setting up wallet"); const wallet = await Wallet.create( indexedDB as any, - httpLib, + httpLib as any, timer, cryptoWorker, { diff --git a/packages/taler-wallet-webextension/tsconfig.json b/packages/taler-wallet-webextension/tsconfig.json index 773853302..08cbc871a 100644 --- a/packages/taler-wallet-webextension/tsconfig.json +++ b/packages/taler-wallet-webextension/tsconfig.json @@ -1,15 +1,12 @@ { "compilerOptions": { "composite": true, - "lib": [ - "es2021", - "DOM" - ], - "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "jsxFactory": "h", /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */ + "lib": ["es2020", "DOM"], + "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, + "jsxFactory": "h" /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */, "jsxFragmentFactory": "Fragment", // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories "moduleResolution": "Node16", - "module": "ES2020", + "module": "Node16", "target": "ES6", "skipLibCheck": true, "preserveSymlinks": true, @@ -23,9 +20,7 @@ "esModuleInterop": true, "importHelpers": true, "rootDir": "./src", - "typeRoots": [ - "./node_modules/@types" - ] + "typeRoots": ["./node_modules/@types"] }, "references": [ { @@ -35,7 +30,5 @@ "path": "../taler-util/" } ], - "include": [ - "src/**/*" - ] + "include": ["src/**/*"] } diff --git a/packages/web-util/package.json b/packages/web-util/package.json index 6cfe19258..81eee949a 100644 --- a/packages/web-util/package.json +++ b/packages/web-util/package.json @@ -56,7 +56,7 @@ "sass": "1.56.1", "swr": "2.0.3", "tslib": "^2.5.3", - "typescript": "^5.1.3", + "typescript": "^5.2.2", "ws": "7.4.5" }, "dependencies": { diff --git a/packages/web-util/tsconfig.json b/packages/web-util/tsconfig.json index fc69cad06..a315dda1c 100644 --- a/packages/web-util/tsconfig.json +++ b/packages/web-util/tsconfig.json @@ -3,17 +3,14 @@ "composite": true, "declaration": true, "declarationMap": true, - "target": "ES6", - "module": "ESNext", + "target": "ES2020", + "module": "Node16", "jsx": "react", "jsxFactory": "h", "jsxFragmentFactory": "Fragment", "moduleResolution": "Node16", "sourceMap": true, - "lib": [ - "DOM", - "es6" - ], + "lib": ["DOM", "ES2020"], "outDir": "lib", "preserveSymlinks": true, "skipLibCheck": true, @@ -27,11 +24,7 @@ "esModuleInterop": true, "importHelpers": true, "rootDir": "./src", - "typeRoots": [ - "./node_modules/@types" - ] + "typeRoots": ["./node_modules/@types"] }, - "include": [ - "src/**/*" - ] + "include": ["src/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a389bf50..347dbf0a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -32,6 +32,9 @@ importers: prettier: specifier: ^2.8.8 version: 2.8.8 + typescript: + specifier: ^5.2.2 + version: 5.2.2 packages/aml-backoffice-ui: dependencies: @@ -92,7 +95,7 @@ importers: version: 0.17.19 eslint-config-preact: specifier: ^1.2.0 - version: 1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.42.0)(typescript@5.1.3) + version: 1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.48.0)(typescript@5.2.2) mocha: specifier: ^9.2.0 version: 9.2.2 @@ -109,8 +112,8 @@ importers: specifier: ^3.3.2 version: 3.3.2 typescript: - specifier: 5.1.3 - version: 5.1.3 + specifier: 5.2.2 + version: 5.2.2 packages/anastasis-cli: dependencies: @@ -134,11 +137,11 @@ importers: specifier: ^3.0.2 version: 3.0.2 typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.1.3) + specifier: ^0.25.1 + version: 0.25.1(typescript@5.2.2) typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/anastasis-core: dependencies: @@ -159,8 +162,8 @@ importers: specifier: ^3.0.2 version: 3.0.2 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/anastasis-webui: dependencies: @@ -220,8 +223,8 @@ importers: specifier: 1.56.1 version: 1.56.1 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/demobank-ui: dependencies: @@ -273,10 +276,10 @@ importers: version: 18.11.17 '@typescript-eslint/eslint-plugin': specifier: ^5.41.0 - version: 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.42.0)(typescript@5.1.3) + version: 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.48.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^5.41.0 - version: 5.41.0(eslint@8.42.0)(typescript@5.1.3) + version: 5.41.0(eslint@8.48.0)(typescript@5.2.2) bulma: specifier: ^0.9.4 version: 0.9.4 @@ -294,7 +297,7 @@ importers: version: 0.17.7 eslint-config-preact: specifier: ^1.2.0 - version: 1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.42.0)(typescript@5.1.3) + version: 1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.48.0)(typescript@5.2.2) mocha: specifier: ^9.2.0 version: 9.2.2 @@ -308,8 +311,8 @@ importers: specifier: 1.56.1 version: 1.56.1 typescript: - specifier: 5.1.3 - version: 5.1.3 + specifier: 5.2.2 + version: 5.2.2 packages/idb-bridge: dependencies: @@ -319,7 +322,7 @@ importers: optionalDependencies: better-sqlite3: specifier: ^8.4.0 - version: 8.4.0 + version: 8.6.0 devDependencies: '@types/better-sqlite3': specifier: ^7.6.4 @@ -337,8 +340,8 @@ importers: specifier: ^5.0.1 version: 5.0.1 typescript: - specifier: ^5.1.6 - version: 5.1.6 + specifier: ^5.2.2 + version: 5.2.2 packages/merchant-backend-ui: dependencies: @@ -381,10 +384,10 @@ importers: version: 4.2.1 '@typescript-eslint/eslint-plugin': specifier: ^4.22.0 - version: 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.3) + version: 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^4.22.0 - version: 4.33.0(eslint@7.32.0)(typescript@5.1.3) + version: 4.33.0(eslint@7.32.0)(typescript@5.2.2) babel-loader: specifier: ^8.2.2 version: 8.2.5(@babel/core@7.18.9)(webpack@4.46.0) @@ -396,7 +399,7 @@ importers: version: 7.32.0 eslint-config-preact: specifier: ^1.1.4 - version: 1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.3) + version: 1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.2.2) eslint-plugin-header: specifier: ^3.1.1 version: 3.1.1(eslint@7.32.0) @@ -417,13 +420,13 @@ importers: version: 1.0.14 ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.4.1)(typescript@5.1.3) + version: 10.9.1(@types/node@20.5.9)(typescript@5.2.2) tslib: specifier: 2.5.3 version: 2.5.3 typescript: - specifier: 5.1.3 - version: 5.1.3 + specifier: 5.2.2 + version: 5.2.2 packages/merchant-backoffice-ui: dependencies: @@ -478,10 +481,10 @@ importers: version: 18.11.17 '@typescript-eslint/eslint-plugin': specifier: ^4.22.0 - version: 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.3) + version: 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^4.22.0 - version: 4.33.0(eslint@7.32.0)(typescript@5.1.3) + version: 4.33.0(eslint@7.32.0)(typescript@5.2.2) base64-inline-loader: specifier: ^1.1.1 version: 1.1.1(webpack@4.46.0) @@ -517,7 +520,7 @@ importers: version: 7.32.0 eslint-config-preact: specifier: ^1.1.4 - version: 1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.3) + version: 1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.2.2) eslint-plugin-header: specifier: ^3.1.1 version: 3.1.1(eslint@7.32.0) @@ -529,7 +532,7 @@ importers: version: 0.0.10 html-webpack-skip-assets-plugin: specifier: ^1.0.1 - version: 1.0.3(html-webpack-plugin@5.5.1)(webpack@4.46.0) + version: 1.0.3(html-webpack-plugin@5.5.3)(webpack@4.46.0) inline-chunk-html-plugin: specifier: ^1.1.1 version: 1.1.1 @@ -549,11 +552,11 @@ importers: specifier: ^0.5.21 version: 0.5.21 typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.1.3) + specifier: ^0.25.1 + version: 0.25.1(typescript@5.2.2) typescript: - specifier: 5.1.3 - version: 5.1.3 + specifier: 5.2.2 + version: 5.2.2 packages/pogen: dependencies: @@ -568,8 +571,8 @@ importers: specifier: ^0.4.5 version: 0.4.5 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/taler-harness: dependencies: @@ -596,8 +599,8 @@ importers: specifier: ^3.0.2 version: 3.0.2 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/taler-util: dependencies: @@ -633,8 +636,8 @@ importers: specifier: ^3.0.2 version: 3.0.2 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/taler-wallet-cli: dependencies: @@ -658,11 +661,11 @@ importers: specifier: ^3.0.2 version: 3.0.2 typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.1.3) + specifier: ^0.25.1 + version: 0.25.1(typescript@5.2.2) typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/taler-wallet-core: dependencies: @@ -693,10 +696,10 @@ importers: version: link:../pogen '@typescript-eslint/eslint-plugin': specifier: ^5.36.1 - version: 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.1.3) + version: 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^5.36.1 - version: 5.41.0(eslint@8.26.0)(typescript@5.1.3) + version: 5.41.0(eslint@8.26.0)(typescript@5.2.2) ava: specifier: ^4.3.3 version: 4.3.3(@ava/typescript@4.0.0) @@ -734,11 +737,11 @@ importers: specifier: ^3.0.2 version: 3.0.2 typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.1.3) + specifier: ^0.25.1 + version: 0.25.1(typescript@5.2.2) typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 packages/taler-wallet-embedded: dependencies: @@ -803,10 +806,10 @@ importers: devDependencies: '@babel/preset-react': specifier: ^7.22.3 - version: 7.22.3(@babel/core@7.18.9) + version: 7.22.3(@babel/core@7.22.15) '@babel/preset-typescript': specifier: 7.18.6 - version: 7.18.6(@babel/core@7.18.9) + version: 7.18.6(@babel/core@7.22.15) '@gnu-taler/pogen': specifier: workspace:* version: link:../pogen @@ -865,8 +868,8 @@ importers: specifier: ^3.0.2 version: 3.0.2 typescript: - specifier: 5.1.3 - version: 5.1.3 + specifier: 5.2.2 + version: 5.2.2 packages/web-util: dependencies: @@ -956,14 +959,19 @@ importers: specifier: ^2.5.3 version: 2.5.3 typescript: - specifier: ^5.1.3 - version: 5.1.3 + specifier: ^5.2.2 + version: 5.2.2 ws: specifier: 7.4.5 version: 7.4.5 packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -975,6 +983,14 @@ packages: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + /@apideck/better-ajv-errors@0.3.6(ajv@8.11.0): resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} engines: {node: '>=10'} @@ -1014,6 +1030,14 @@ packages: dependencies: '@babel/highlight': 7.18.6 + /@babel/code-frame@7.22.13: + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.13 + chalk: 2.4.2 + dev: true + /@babel/compat-data@7.19.4: resolution: {integrity: sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==} engines: {node: '>=6.9.0'} @@ -1028,6 +1052,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/compat-data@7.22.9: + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.13.16: resolution: {integrity: sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==} engines: {node: '>=6.9.0'} @@ -1096,6 +1125,29 @@ packages: - supports-color dev: true + /@babel/core@7.22.15: + resolution: {integrity: sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.15 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.22.15(@babel/core@7.22.15) + '@babel/helpers': 7.22.15 + '@babel/parser': 7.22.15 + '@babel/template': 7.22.15 + '@babel/traverse': 7.22.15 + '@babel/types': 7.22.15 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/eslint-parser@7.19.1(@babel/core@7.18.9)(eslint@7.32.0): resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} @@ -1110,7 +1162,7 @@ packages: semver: 6.3.0 dev: true - /@babel/eslint-parser@7.19.1(@babel/core@7.18.9)(eslint@8.42.0): + /@babel/eslint-parser@7.19.1(@babel/core@7.18.9)(eslint@8.48.0): resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -1119,7 +1171,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.42.0 + eslint: 8.48.0 eslint-visitor-keys: 2.1.0 semver: 6.3.0 dev: true @@ -1142,6 +1194,16 @@ packages: '@jridgewell/trace-mapping': 0.3.17 jsesc: 2.5.2 + /@babel/generator@7.22.15: + resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.15 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + dev: true + /@babel/generator@7.22.3: resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==} engines: {node: '>=6.9.0'} @@ -1286,6 +1348,17 @@ packages: semver: 6.3.0 dev: true + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + /@babel/helper-create-class-features-plugin@7.20.12(@babel/core@7.18.9): resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} engines: {node: '>=6.9.0'} @@ -1324,6 +1397,25 @@ packages: - supports-color dev: true + /@babel/helper-create-class-features-plugin@7.20.12(@babel/core@7.22.15): + resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-member-expression-to-functions': 7.20.7 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/helper-split-export-declaration': 7.18.6 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-create-class-features-plugin@7.22.1(@babel/core@7.18.9): resolution: {integrity: sha512-SowrZ9BWzYFgzUMwUmowbPSGu6CXL5MSuuCkG3bejahSpSymioPmuLdhPxNOc9MjuNGjy7M/HaXvJ8G82Lywlw==} engines: {node: '>=6.9.0'} @@ -1455,6 +1547,11 @@ packages: resolution: {integrity: sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==} engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-explode-assignable-expression@7.18.6: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} @@ -1477,12 +1574,27 @@ packages: '@babel/template': 7.21.9 '@babel/types': 7.22.4 + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.22.15 + dev: true + /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.4 + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.15 + dev: true + /@babel/helper-member-expression-to-functions@7.18.9: resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} engines: {node: '>=6.9.0'} @@ -1517,6 +1629,13 @@ packages: dependencies: '@babel/types': 7.22.4 + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.15 + dev: true + /@babel/helper-module-transforms@7.19.6: resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==} engines: {node: '>=6.9.0'} @@ -1564,6 +1683,20 @@ packages: - supports-color dev: true + /@babel/helper-module-transforms@7.22.15(@babel/core@7.22.15): + resolution: {integrity: sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.15 + dev: true + /@babel/helper-optimise-call-expression@7.18.6: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} @@ -1665,6 +1798,13 @@ packages: dependencies: '@babel/types': 7.22.4 + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.15 + dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.18.9: resolution: {integrity: sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==} engines: {node: '>=6.9.0'} @@ -1685,6 +1825,13 @@ packages: dependencies: '@babel/types': 7.22.4 + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.15 + dev: true + /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} @@ -1694,10 +1841,20 @@ packages: resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} engines: {node: '>=6.9.0'} + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.22.15: + resolution: {integrity: sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} @@ -1707,6 +1864,11 @@ packages: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-wrap-function@7.19.0: resolution: {integrity: sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==} engines: {node: '>=6.9.0'} @@ -1740,6 +1902,17 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers@7.22.15: + resolution: {integrity: sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.22.15 + '@babel/types': 7.22.15 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helpers@7.22.3: resolution: {integrity: sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==} engines: {node: '>=6.9.0'} @@ -1759,6 +1932,15 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 + /@babel/highlight@7.22.13: + resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.15 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + /@babel/parser@7.19.6: resolution: {integrity: sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==} engines: {node: '>=6.0.0'} @@ -1772,6 +1954,14 @@ packages: dependencies: '@babel/types': 7.21.5 + /@babel/parser@7.22.15: + resolution: {integrity: sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.15 + dev: true + /@babel/parser@7.22.4: resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} engines: {node: '>=6.0.0'} @@ -2432,6 +2622,16 @@ packages: '@babel/helper-plugin-utils': 7.21.5 dev: true + /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.15): + resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.18.9): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -2580,23 +2780,23 @@ packages: '@babel/helper-plugin-utils': 7.21.5 dev: true - /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.18.9): + /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.22.1): resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.9 + '@babel/core': 7.22.1 '@babel/helper-plugin-utils': 7.21.5 dev: true - /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.22.1): + /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.22.15): resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.1 + '@babel/core': 7.22.15 '@babel/helper-plugin-utils': 7.21.5 dev: true @@ -3520,6 +3720,16 @@ packages: '@babel/helper-plugin-utils': 7.21.5 dev: true + /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.22.15): + resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.18.9): resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} @@ -3530,6 +3740,16 @@ packages: '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.18.9) dev: true + /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.22.15): + resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.22.15) + dev: true + /@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.22.1): resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} engines: {node: '>=6.9.0'} @@ -3558,6 +3778,20 @@ packages: '@babel/types': 7.22.4 dev: true + /@babel/plugin-transform-react-jsx@7.22.3(@babel/core@7.22.15): + resolution: {integrity: sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.15) + '@babel/types': 7.22.4 + dev: true + /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.18.9): resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} engines: {node: '>=6.9.0'} @@ -3569,6 +3803,17 @@ packages: '@babel/helper-plugin-utils': 7.21.5 dev: true + /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.22.15): + resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + /@babel/plugin-transform-regenerator@7.18.6(@babel/core@7.18.9): resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} engines: {node: '>=6.9.0'} @@ -3769,30 +4014,30 @@ packages: '@babel/helper-plugin-utils': 7.21.5 dev: true - /@babel/plugin-transform-typescript@7.20.13(@babel/core@7.18.9): + /@babel/plugin-transform-typescript@7.20.13(@babel/core@7.22.1): resolution: {integrity: sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.9 - '@babel/helper-create-class-features-plugin': 7.20.12(@babel/core@7.18.9) + '@babel/core': 7.22.1 + '@babel/helper-create-class-features-plugin': 7.20.12(@babel/core@7.22.1) '@babel/helper-plugin-utils': 7.21.5 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.18.9) + '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.22.1) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-typescript@7.20.13(@babel/core@7.22.1): + /@babel/plugin-transform-typescript@7.20.13(@babel/core@7.22.15): resolution: {integrity: sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.1 - '@babel/helper-create-class-features-plugin': 7.20.12(@babel/core@7.22.1) + '@babel/core': 7.22.15 + '@babel/helper-create-class-features-plugin': 7.20.12(@babel/core@7.22.15) '@babel/helper-plugin-utils': 7.21.5 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.22.1) + '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.22.15) transitivePeerDependencies: - supports-color dev: true @@ -4190,30 +4435,45 @@ packages: '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.18.9) dev: true - /@babel/preset-typescript@7.18.6(@babel/core@7.18.9): + /@babel/preset-react@7.22.3(@babel/core@7.22.15): + resolution: {integrity: sha512-lxDz1mnZ9polqClBCVBjIVUypoB4qV3/tZUDb/IlYbW1kiiLaXaX+bInbRjl+lNQ/iUZraQ3+S8daEmoELMWug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.15 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.22.15) + '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.22.15) + '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.22.15) + '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.22.15) + dev: true + + /@babel/preset-typescript@7.18.6(@babel/core@7.22.1): resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.9 + '@babel/core': 7.22.1 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-typescript': 7.20.13(@babel/core@7.18.9) + '@babel/plugin-transform-typescript': 7.20.13(@babel/core@7.22.1) transitivePeerDependencies: - supports-color dev: true - /@babel/preset-typescript@7.18.6(@babel/core@7.22.1): + /@babel/preset-typescript@7.18.6(@babel/core@7.22.15): resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.1 + '@babel/core': 7.22.15 '@babel/helper-plugin-utils': 7.19.0 '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-typescript': 7.20.13(@babel/core@7.22.1) + '@babel/plugin-transform-typescript': 7.20.13(@babel/core@7.22.15) transitivePeerDependencies: - supports-color dev: true @@ -4284,6 +4544,15 @@ packages: '@babel/parser': 7.22.4 '@babel/types': 7.22.4 + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.22.15 + '@babel/types': 7.22.15 + dev: true + /@babel/traverse@7.19.6: resolution: {integrity: sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==} engines: {node: '>=6.9.0'} @@ -4319,6 +4588,24 @@ packages: transitivePeerDependencies: - supports-color + /@babel/traverse@7.22.15: + resolution: {integrity: sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.15 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.15 + '@babel/types': 7.22.15 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/traverse@7.22.4: resolution: {integrity: sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ==} engines: {node: '>=6.9.0'} @@ -4353,6 +4640,15 @@ packages: '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + /@babel/types@7.22.15: + resolution: {integrity: sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.15 + to-fast-properties: 2.0.0 + dev: true + /@babel/types@7.22.4: resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} engines: {node: '>=6.9.0'} @@ -4792,18 +5088,18 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.42.0 - eslint-visitor-keys: 3.4.1 + eslint: 8.48.0 + eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.5.1: - resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} + /@eslint-community/regexpp@4.8.0: + resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true @@ -4841,14 +5137,14 @@ packages: - supports-color dev: true - /@eslint/eslintrc@2.0.3: - resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.5.2 - globals: 13.20.0 + espree: 9.6.1 + globals: 13.21.0 ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -4858,8 +5154,8 @@ packages: - supports-color dev: true - /@eslint/js@8.42.0: - resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==} + /@eslint/js@8.48.0: + resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -4887,8 +5183,8 @@ packages: react: 18.2.0 dev: false - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + /@humanwhocodes/config-array@0.11.11: + resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 @@ -4978,13 +5274,18 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.19 dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} @@ -4996,11 +5297,11 @@ packages: '@jridgewell/trace-mapping': 0.3.17 dev: true - /@jridgewell/source-map@0.3.3: - resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.19 dev: true /@jridgewell/sourcemap-codec@1.4.14: @@ -5016,11 +5317,11 @@ packages: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 dev: true /@jridgewell/trace-mapping@0.3.9: @@ -5731,6 +6032,10 @@ packages: resolution: {integrity: sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==} dev: true + /@types/node@20.5.9: + resolution: {integrity: sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==} + dev: true + /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: true @@ -5833,7 +6138,7 @@ packages: '@types/node': 18.11.17 dev: true - /@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.3): + /@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -5844,8 +6149,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.1.3) - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.3) + '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 4.33.0 debug: 4.3.4 eslint: 7.32.0 @@ -5853,13 +6158,13 @@ packages: ignore: 5.2.0 regexpp: 3.2.0 semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/eslint-plugin@5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.1.3): + /@typescript-eslint/eslint-plugin@5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.2.2): resolution: {integrity: sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5870,22 +6175,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 5.41.0 - '@typescript-eslint/type-utils': 5.41.0(eslint@8.26.0)(typescript@5.1.3) - '@typescript-eslint/utils': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/type-utils': 5.41.0(eslint@8.26.0)(typescript@5.2.2) + '@typescript-eslint/utils': 5.41.0(eslint@8.26.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.26.0 ignore: 5.2.0 regexpp: 3.2.0 semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/eslint-plugin@5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.42.0)(typescript@5.1.3): + /@typescript-eslint/eslint-plugin@5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5896,22 +6201,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.41.0(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.41.0(eslint@8.48.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 5.41.0 - '@typescript-eslint/type-utils': 5.41.0(eslint@8.42.0)(typescript@5.1.3) - '@typescript-eslint/utils': 5.41.0(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/type-utils': 5.41.0(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/utils': 5.41.0(eslint@8.48.0)(typescript@5.2.2) debug: 4.3.4 - eslint: 8.42.0 + eslint: 8.48.0 ignore: 5.2.0 regexpp: 3.2.0 semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils@4.33.0(eslint@7.32.0)(typescript@5.1.3): + /@typescript-eslint/experimental-utils@4.33.0(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -5920,7 +6225,7 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.2.2) eslint: 7.32.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@7.32.0) @@ -5929,33 +6234,33 @@ packages: - typescript dev: true - /@typescript-eslint/experimental-utils@5.41.0(eslint@7.32.0)(typescript@5.1.3): + /@typescript-eslint/experimental-utils@5.41.0(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-/qxT2Kd2q/A22JVIllvws4rvc00/3AT4rAo/0YgEN28y+HPhbJbk6X4+MAHEoZzpNyAOugIT7D/OLnKBW8FfhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.41.0(eslint@7.32.0)(typescript@5.1.3) + '@typescript-eslint/utils': 5.41.0(eslint@7.32.0)(typescript@5.2.2) eslint: 7.32.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/experimental-utils@5.41.0(eslint@8.42.0)(typescript@5.1.3): + /@typescript-eslint/experimental-utils@5.41.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-/qxT2Kd2q/A22JVIllvws4rvc00/3AT4rAo/0YgEN28y+HPhbJbk6X4+MAHEoZzpNyAOugIT7D/OLnKBW8FfhA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.41.0(eslint@8.42.0)(typescript@5.1.3) - eslint: 8.42.0 + '@typescript-eslint/utils': 5.41.0(eslint@8.48.0)(typescript@5.2.2) + eslint: 8.48.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.1.3): + /@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -5967,15 +6272,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.2.2) debug: 4.3.4 eslint: 7.32.0 - typescript: 5.1.3 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.41.0(eslint@8.26.0)(typescript@5.1.3): + /@typescript-eslint/parser@5.41.0(eslint@8.26.0)(typescript@5.2.2): resolution: {integrity: sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5987,15 +6292,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.41.0 '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) debug: 4.3.4 eslint: 8.26.0 - typescript: 5.1.3 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.41.0(eslint@8.42.0)(typescript@5.1.3): + /@typescript-eslint/parser@5.41.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6007,10 +6312,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.41.0 '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) debug: 4.3.4 - eslint: 8.42.0 - typescript: 5.1.3 + eslint: 8.48.0 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -6031,7 +6336,7 @@ packages: '@typescript-eslint/visitor-keys': 5.41.0 dev: true - /@typescript-eslint/type-utils@5.41.0(eslint@8.26.0)(typescript@5.1.3): + /@typescript-eslint/type-utils@5.41.0(eslint@8.26.0)(typescript@5.2.2): resolution: {integrity: sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6041,17 +6346,17 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) - '@typescript-eslint/utils': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) + '@typescript-eslint/utils': 5.41.0(eslint@8.26.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.26.0 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/type-utils@5.41.0(eslint@8.42.0)(typescript@5.1.3): + /@typescript-eslint/type-utils@5.41.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6061,12 +6366,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) - '@typescript-eslint/utils': 5.41.0(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) + '@typescript-eslint/utils': 5.41.0(eslint@8.48.0)(typescript@5.2.2) debug: 4.3.4 - eslint: 8.42.0 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + eslint: 8.48.0 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -6081,7 +6386,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@4.33.0(typescript@5.1.3): + /@typescript-eslint/typescript-estree@4.33.0(typescript@5.2.2): resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -6096,13 +6401,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@5.41.0(typescript@5.1.3): + /@typescript-eslint/typescript-estree@5.41.0(typescript@5.2.2): resolution: {integrity: sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6117,13 +6422,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.41.0(eslint@7.32.0)(typescript@5.1.3): + /@typescript-eslint/utils@5.41.0(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6133,7 +6438,7 @@ packages: '@types/semver': 7.3.12 '@typescript-eslint/scope-manager': 5.41.0 '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) eslint: 7.32.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@7.32.0) @@ -6143,7 +6448,7 @@ packages: - typescript dev: true - /@typescript-eslint/utils@5.41.0(eslint@8.26.0)(typescript@5.1.3): + /@typescript-eslint/utils@5.41.0(eslint@8.26.0)(typescript@5.2.2): resolution: {integrity: sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6153,7 +6458,7 @@ packages: '@types/semver': 7.3.12 '@typescript-eslint/scope-manager': 5.41.0 '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) eslint: 8.26.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@8.26.0) @@ -6163,7 +6468,7 @@ packages: - typescript dev: true - /@typescript-eslint/utils@5.41.0(eslint@8.42.0)(typescript@5.1.3): + /@typescript-eslint/utils@5.41.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -6173,10 +6478,10 @@ packages: '@types/semver': 7.3.12 '@typescript-eslint/scope-manager': 5.41.0 '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.1.3) - eslint: 8.42.0 + '@typescript-eslint/typescript-estree': 5.41.0(typescript@5.2.2) + eslint: 8.48.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.42.0) + eslint-utils: 3.0.0(eslint@8.48.0) semver: 7.3.8 transitivePeerDependencies: - supports-color @@ -6383,20 +6688,20 @@ packages: acorn: 7.4.1 dev: true - /acorn-jsx@5.3.2(acorn@8.8.1): + /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.8.1 + acorn: 8.10.0 dev: true - /acorn-jsx@5.3.2(acorn@8.8.2): + /acorn-jsx@5.3.2(acorn@8.8.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.8.2 + acorn: 8.8.1 dev: true /acorn-walk@6.2.0: @@ -6420,6 +6725,12 @@ packages: engines: {node: '>=0.4.0'} dev: true + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /acorn@8.8.1: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} engines: {node: '>=0.4.0'} @@ -6546,8 +6857,8 @@ packages: engines: {node: '>=12'} dev: true - /ansi-sequence-parser@1.1.0: - resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==} + /ansi-sequence-parser@1.1.1: + resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} dev: true /ansi-styles@1.0.0: @@ -6779,8 +7090,8 @@ packages: engines: {node: '>=8'} dev: true - /async-each@1.0.3: - resolution: {integrity: sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==} + /async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} requiresBuild: true dev: true optional: true @@ -6805,6 +7116,7 @@ packages: /atob@2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} + hasBin: true dev: true /autoprefixer@10.4.14(postcss@8.4.23): @@ -7187,8 +7499,8 @@ packages: tweetnacl: 0.14.5 dev: true - /better-sqlite3@8.4.0: - resolution: {integrity: sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw==} + /better-sqlite3@8.6.0: + resolution: {integrity: sha512-jwAudeiTMTSyby+/SfbHDebShbmC2MCH8mU2+DXi0WJfv13ypEJm47cd3kljmy/H130CazEvkf2Li//ewcMJ1g==} requiresBuild: true dependencies: bindings: 1.5.0 @@ -7368,7 +7680,7 @@ packages: resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} dependencies: cipher-base: 1.0.4 - des.js: 1.0.1 + des.js: 1.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 dev: true @@ -7390,7 +7702,7 @@ packages: elliptic: 6.5.4 inherits: 2.0.4 parse-asn1: 5.1.6 - readable-stream: 3.6.0 + readable-stream: 3.6.2 safe-buffer: 5.2.1 dev: true @@ -7400,6 +7712,17 @@ packages: pako: 1.0.11 dev: true + /browserslist@4.21.10: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001527 + electron-to-chromium: 1.4.508 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.10) + dev: true + /browserslist@4.21.4: resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -7529,7 +7852,7 @@ packages: chownr: 1.1.4 figgy-pudding: 3.5.2 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 infer-owner: 1.0.4 lru-cache: 5.1.1 mississippi: 3.0.0 @@ -7653,7 +7976,7 @@ packages: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} dependencies: pascal-case: 3.1.2 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /camelcase-css@2.0.1: @@ -7682,6 +8005,10 @@ packages: /caniuse-lite@1.0.30001482: resolution: {integrity: sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ==} + /caniuse-lite@1.0.30001527: + resolution: {integrity: sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==} + dev: true + /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true @@ -7776,7 +8103,7 @@ packages: requiresBuild: true dependencies: anymatch: 2.0.0 - async-each: 1.0.3 + async-each: 1.0.6 braces: 2.3.2 glob-parent: 3.1.0 inherits: 2.0.4 @@ -7805,7 +8132,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -8134,7 +8461,7 @@ packages: dependencies: buffer-from: 1.1.2 inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 typedarray: 0.0.6 dev: true @@ -8667,8 +8994,8 @@ packages: array-find-index: 1.0.2 dev: true - /cyclist@1.0.1: - resolution: {integrity: sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==} + /cyclist@1.0.2: + resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==} dev: true /damerau-levenshtein@1.0.8: @@ -8763,8 +9090,8 @@ packages: engines: {node: '>=10'} dev: true - /decode-uri-component@0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} + /decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} engines: {node: '>=0.10'} dev: true @@ -8909,8 +9236,8 @@ packages: engines: {node: '>= 0.6.0'} dev: true - /des.js@1.0.1: - resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} + /des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 @@ -9054,7 +9381,7 @@ packages: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: no-case: 3.0.4 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /dot-prop@5.3.0: @@ -9092,7 +9419,7 @@ packages: dependencies: end-of-stream: 1.4.4 inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 stream-shift: 1.0.1 dev: true @@ -9128,6 +9455,10 @@ packages: /electron-to-chromium@1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + /electron-to-chromium@1.4.508: + resolution: {integrity: sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==} + dev: true + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: @@ -9188,7 +9519,7 @@ packages: resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==} engines: {node: '>=6.9.0'} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 memory-fs: 0.5.0 tapable: 1.1.3 dev: true @@ -9219,6 +9550,7 @@ packages: /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true dependencies: prr: 1.0.1 dev: true @@ -9412,14 +9744,14 @@ packages: eslint: ^7.32.0 || ^8.2.0 eslint-plugin-import: ^2.25.3 dependencies: - '@typescript-eslint/eslint-plugin': 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.1.3) - '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/eslint-plugin': 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0)(typescript@5.2.2) + '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.2.2) eslint: 8.26.0 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.26.0)(eslint@8.26.0) eslint-plugin-import: 2.26.0(@typescript-eslint/parser@5.41.0)(eslint@8.26.0) dev: true - /eslint-config-preact@1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.3): + /eslint-config-preact@1.3.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-yHYXg5qNzEJd3D/30AmsIW0W8MuY858KpApXp7xxBF08IYUljSKCOqMx+dVucXHQnAm7+11wOnMkgVHIBAechw==} peerDependencies: eslint: 6.x || 7.x || 8.x @@ -9431,7 +9763,7 @@ packages: '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.18.9) eslint: 7.32.0 eslint-plugin-compat: 4.0.2(eslint@7.32.0) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.3) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.2.2) eslint-plugin-react: 7.31.10(eslint@7.32.0) eslint-plugin-react-hooks: 4.6.0(eslint@7.32.0) transitivePeerDependencies: @@ -9441,21 +9773,21 @@ packages: - typescript dev: true - /eslint-config-preact@1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.42.0)(typescript@5.1.3): + /eslint-config-preact@1.3.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-yHYXg5qNzEJd3D/30AmsIW0W8MuY858KpApXp7xxBF08IYUljSKCOqMx+dVucXHQnAm7+11wOnMkgVHIBAechw==} peerDependencies: eslint: 6.x || 7.x || 8.x dependencies: '@babel/core': 7.18.9 - '@babel/eslint-parser': 7.19.1(@babel/core@7.18.9)(eslint@8.42.0) + '@babel/eslint-parser': 7.19.1(@babel/core@7.18.9)(eslint@8.48.0) '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.18.9) '@babel/plugin-syntax-decorators': 7.19.0(@babel/core@7.18.9) '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.18.9) - eslint: 8.42.0 - eslint-plugin-compat: 4.0.2(eslint@8.42.0) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.42.0)(typescript@5.1.3) - eslint-plugin-react: 7.31.10(eslint@8.42.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.42.0) + eslint: 8.48.0 + eslint-plugin-compat: 4.0.2(eslint@8.48.0) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.48.0)(typescript@5.2.2) + eslint-plugin-react: 7.31.10(eslint@8.48.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.48.0) transitivePeerDependencies: - '@typescript-eslint/eslint-plugin' - jest @@ -9502,7 +9834,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.2.2) debug: 3.2.7 eslint: 8.26.0 eslint-import-resolver-node: 0.3.6 @@ -9527,7 +9859,7 @@ packages: semver: 7.3.5 dev: true - /eslint-plugin-compat@4.0.2(eslint@8.42.0): + /eslint-plugin-compat@4.0.2(eslint@8.48.0): resolution: {integrity: sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==} engines: {node: '>=9.x'} peerDependencies: @@ -9538,7 +9870,7 @@ packages: browserslist: 4.21.5 caniuse-lite: 1.0.30001482 core-js: 3.26.0 - eslint: 8.42.0 + eslint: 8.48.0 find-up: 5.0.0 lodash.memoize: 4.1.2 semver: 7.3.5 @@ -9562,7 +9894,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.41.0(eslint@8.26.0)(typescript@5.2.2) array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 @@ -9583,7 +9915,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.3): + /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.2.2): resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -9596,15 +9928,15 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.3) - '@typescript-eslint/experimental-utils': 5.41.0(eslint@7.32.0)(typescript@5.1.3) + '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/experimental-utils': 5.41.0(eslint@7.32.0)(typescript@5.2.2) eslint: 7.32.0 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.42.0)(typescript@5.1.3): + /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.41.0)(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -9617,9 +9949,9 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.42.0)(typescript@5.1.3) - '@typescript-eslint/experimental-utils': 5.41.0(eslint@8.42.0)(typescript@5.1.3) - eslint: 8.42.0 + '@typescript-eslint/eslint-plugin': 5.41.0(@typescript-eslint/parser@5.41.0)(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/experimental-utils': 5.41.0(eslint@8.48.0)(typescript@5.2.2) + eslint: 8.48.0 transitivePeerDependencies: - supports-color - typescript @@ -9665,13 +9997,13 @@ packages: eslint: 8.26.0 dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.42.0): + /eslint-plugin-react-hooks@4.6.0(eslint@8.48.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.42.0 + eslint: 8.48.0 dev: true /eslint-plugin-react@7.31.10(eslint@7.32.0): @@ -9720,7 +10052,7 @@ packages: string.prototype.matchall: 4.0.7 dev: true - /eslint-plugin-react@7.31.10(eslint@8.42.0): + /eslint-plugin-react@7.31.10(eslint@8.48.0): resolution: {integrity: sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==} engines: {node: '>=4'} peerDependencies: @@ -9729,7 +10061,7 @@ packages: array-includes: 3.1.5 array.prototype.flatmap: 1.3.0 doctrine: 2.1.0 - eslint: 8.42.0 + eslint: 8.48.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 @@ -9767,8 +10099,8 @@ packages: estraverse: 5.3.0 dev: true - /eslint-scope@7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 @@ -9812,13 +10144,13 @@ packages: eslint-visitor-keys: 2.1.0 dev: true - /eslint-utils@3.0.0(eslint@8.42.0): + /eslint-utils@3.0.0(eslint@8.48.0): resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.42.0 + eslint: 8.48.0 eslint-visitor-keys: 2.1.0 dev: true @@ -9837,8 +10169,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -9984,16 +10316,16 @@ packages: - supports-color dev: true - /eslint@8.42.0: - resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} + /eslint@8.48.0: + resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) - '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.0.3 - '@eslint/js': 8.42.0 - '@humanwhocodes/config-array': 0.11.10 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@eslint-community/regexpp': 4.8.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.48.0 + '@humanwhocodes/config-array': 0.11.11 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 @@ -10002,19 +10334,18 @@ packages: debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.1 - espree: 9.5.2 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 + globals: 13.21.0 graphemer: 1.4.0 ignore: 5.2.4 - import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -10024,9 +10355,8 @@ packages: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.1 + optionator: 0.9.3 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color @@ -10055,13 +10385,13 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /espree@9.5.2: - resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.8.2 - acorn-jsx: 5.3.2(acorn@8.8.2) - eslint-visitor-keys: 3.4.1 + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.3 dev: true /esprima@4.0.1: @@ -10492,7 +10822,7 @@ packages: resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} dependencies: inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /follow-redirects@1.15.2: @@ -10607,7 +10937,7 @@ packages: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} dependencies: inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /fromentries@1.3.2: @@ -10665,10 +10995,10 @@ packages: /fs-write-stream-atomic@1.0.10: resolution: {integrity: sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 iferr: 0.1.5 imurmurhash: 0.1.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /fs.realpath@1.0.0: @@ -10686,8 +11016,8 @@ packages: dev: true optional: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -10921,8 +11251,8 @@ packages: type-fest: 0.20.2 dev: true - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -10985,6 +11315,10 @@ packages: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: true + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true @@ -11105,7 +11439,7 @@ packages: engines: {node: '>=4'} dependencies: inherits: 2.0.4 - readable-stream: 3.6.0 + readable-stream: 3.6.2 safe-buffer: 5.2.1 dev: true @@ -11201,7 +11535,7 @@ packages: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.17.7 + terser: 5.19.4 dev: true /html-minifier@3.5.21: @@ -11253,8 +11587,8 @@ packages: webpack: 4.46.0 dev: true - /html-webpack-plugin@5.5.1(webpack@4.46.0): - resolution: {integrity: sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==} + /html-webpack-plugin@5.5.3(webpack@4.46.0): + resolution: {integrity: sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==} engines: {node: '>=10.13.0'} peerDependencies: webpack: ^5.20.0 @@ -11267,13 +11601,13 @@ packages: webpack: 4.46.0 dev: true - /html-webpack-skip-assets-plugin@1.0.3(html-webpack-plugin@5.5.1)(webpack@4.46.0): + /html-webpack-skip-assets-plugin@1.0.3(html-webpack-plugin@5.5.3)(webpack@4.46.0): resolution: {integrity: sha512-vpdh+JZGlE1Df3IftH2gw5P7b6yfTsahcOIJnkkkj5iJU9dUStXgzgALoXWwl8+17wWgFm3edcJzeYTJBYfMAw==} peerDependencies: html-webpack-plugin: '>=3.0.0' webpack: '>=3.0.0' dependencies: - html-webpack-plugin: 5.5.1(webpack@4.46.0) + html-webpack-plugin: 5.5.3(webpack@4.46.0) minimatch: 3.0.4 webpack: 4.46.0 dev: true @@ -12137,6 +12471,13 @@ packages: minimist: 1.2.7 dev: true + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + /json5@2.2.1: resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} engines: {node: '>=6'} @@ -12319,6 +12660,15 @@ packages: json5: 1.0.1 dev: true + /loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + dev: true + /loader-utils@2.0.3: resolution: {integrity: sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==} engines: {node: '>=8.9.0'} @@ -12431,7 +12781,7 @@ packages: /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: - tslib: 2.6.1 + tslib: 2.6.2 dev: true /lowercase-keys@1.0.1: @@ -12483,7 +12833,7 @@ packages: engines: {node: '>=6'} dependencies: pify: 4.0.1 - semver: 5.7.1 + semver: 5.7.2 dev: true /make-dir@3.1.0: @@ -12576,7 +12926,7 @@ packages: resolution: {integrity: sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==} dependencies: errno: 0.1.8 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /memory-fs@0.5.0: @@ -12584,7 +12934,7 @@ packages: engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} dependencies: errno: 0.1.8 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /merge-descriptors@1.0.1: @@ -12638,6 +12988,7 @@ packages: /miller-rabin@4.0.1: resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true dependencies: bn.js: 4.12.0 brorand: 1.1.0 @@ -12744,9 +13095,20 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist@1.2.7: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + /minipass-collect@1.0.2: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} engines: {node: '>= 8'} @@ -12833,8 +13195,9 @@ packages: /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true dependencies: - minimist: 1.2.7 + minimist: 1.2.8 dev: true /mkdirp@1.0.4: @@ -12995,7 +13358,7 @@ packages: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: lower-case: 2.0.2 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /node-abi@3.45.0: @@ -13049,13 +13412,13 @@ packages: process: 0.11.10 punycode: 1.4.1 querystring-es3: 0.2.1 - readable-stream: 2.3.7 + readable-stream: 2.3.8 stream-browserify: 2.0.2 stream-http: 2.8.3 string_decoder: 1.3.0 timers-browserify: 2.0.12 tty-browserify: 0.0.0 - url: 0.11.0 + url: 0.11.1 util: 0.11.1 vm-browserify: 1.1.2 dev: true @@ -13070,6 +13433,10 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} @@ -13420,6 +13787,18 @@ packages: word-wrap: 1.2.3 dev: true + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} @@ -13571,9 +13950,9 @@ packages: /parallel-transform@1.2.0: resolution: {integrity: sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==} dependencies: - cyclist: 1.0.1 + cyclist: 1.0.2 inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /param-case@2.1.1: @@ -13586,7 +13965,7 @@ packages: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: dot-case: 3.0.4 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /parent-module@1.0.1: @@ -13651,7 +14030,7 @@ packages: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} dependencies: no-case: 3.0.4 - tslib: 2.6.1 + tslib: 2.6.2 dev: true /pascalcase@0.1.1: @@ -14895,10 +15274,6 @@ packages: pump: 2.0.1 dev: true - /punycode@1.3.2: - resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} - dev: true - /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: true @@ -14931,6 +15306,13 @@ packages: side-channel: 1.0.4 dev: true + /qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + /qs@6.5.3: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} @@ -14941,11 +15323,6 @@ packages: engines: {node: '>=0.4.x'} dev: true - /querystring@0.2.0: - resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} - engines: {node: '>=0.4.x'} - dev: true - /querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} @@ -15050,6 +15427,18 @@ packages: util-deprecate: 1.0.2 dev: true + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + /readable-stream@3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} @@ -15058,14 +15447,23 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + /readdirp@2.2.1: resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} engines: {node: '>=0.10'} requiresBuild: true dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 micromatch: 3.1.10 - readable-stream: 2.3.7 + readable-stream: 2.3.8 transitivePeerDependencies: - supports-color dev: true @@ -15315,6 +15713,7 @@ packages: /resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated dev: true /resolve@1.22.1: @@ -15420,7 +15819,7 @@ packages: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /run-parallel@1.2.0: @@ -15565,9 +15964,19 @@ packages: hasBin: true dev: true + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + /semver@7.3.4: resolution: {integrity: sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==} engines: {node: '>=10'} @@ -15689,6 +16098,7 @@ packages: /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 @@ -15725,10 +16135,10 @@ packages: engines: {node: '>=8'} dev: true - /shiki@0.14.2: - resolution: {integrity: sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==} + /shiki@0.14.4: + resolution: {integrity: sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==} dependencies: - ansi-sequence-parser: 1.1.0 + ansi-sequence-parser: 1.1.1 jsonc-parser: 3.2.0 vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 @@ -15905,9 +16315,10 @@ packages: /source-map-resolve@0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated dependencies: atob: 2.1.2 - decode-uri-component: 0.2.0 + decode-uri-component: 0.2.2 resolve-url: 0.2.1 source-map-url: 0.4.1 urix: 0.1.0 @@ -16076,7 +16487,7 @@ packages: resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} dependencies: inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 dev: true /stream-each@1.2.3: @@ -16091,7 +16502,7 @@ packages: dependencies: builtin-status-codes: 3.0.0 inherits: 2.0.4 - readable-stream: 2.3.7 + readable-stream: 2.3.8 to-arraybuffer: 1.0.1 xtend: 4.0.2 dev: true @@ -16531,8 +16942,9 @@ packages: /terser@4.8.1: resolution: {integrity: sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==} engines: {node: '>=6.0.0'} + hasBin: true dependencies: - acorn: 8.8.2 + acorn: 8.10.0 commander: 2.20.3 source-map: 0.6.1 source-map-support: 0.5.21 @@ -16548,13 +16960,13 @@ packages: source-map-support: 0.5.21 dev: true - /terser@5.17.7: - resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==} + /terser@5.19.4: + resolution: {integrity: sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==} engines: {node: '>=10'} hasBin: true dependencies: - '@jridgewell/source-map': 0.3.3 - acorn: 8.8.2 + '@jridgewell/source-map': 0.3.5 + acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -16590,7 +17002,7 @@ packages: /through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: - readable-stream: 2.3.7 + readable-stream: 2.3.8 xtend: 4.0.2 dev: true @@ -16728,7 +17140,7 @@ packages: tslib: 2.6.1 dev: true - /ts-node@10.9.1(@types/node@20.4.1)(typescript@5.1.3): + /ts-node@10.9.1(@types/node@20.5.9)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -16747,14 +17159,14 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 20.4.1 + '@types/node': 20.5.9 acorn: 8.8.1 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.1.3 + typescript: 5.2.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: true @@ -16799,14 +17211,18 @@ packages: resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} dev: true - /tsutils@3.21.0(typescript@5.1.3): + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + + /tsutils@3.21.0(typescript@5.2.2): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 5.1.3 + typescript: 5.2.2 dev: true /tty-browserify@0.0.0: @@ -16879,18 +17295,18 @@ packages: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: true - /typedoc@0.24.8(typescript@5.1.3): - resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==} - engines: {node: '>= 14.14'} + /typedoc@0.25.1(typescript@5.2.2): + resolution: {integrity: sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==} + engines: {node: '>= 16'} hasBin: true peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.1 - shiki: 0.14.2 - typescript: 5.1.3 + minimatch: 9.0.3 + shiki: 0.14.4 + typescript: 5.2.2 dev: true /typescript@4.6.4: @@ -16899,13 +17315,8 @@ packages: hasBin: true dev: true - /typescript@5.1.3: - resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==} - engines: {node: '>=14.17'} - dev: true - - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -17025,6 +17436,7 @@ packages: /upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} + requiresBuild: true dev: true /update-browserslist-db@1.0.10(browserslist@4.21.4): @@ -17048,6 +17460,17 @@ packages: escalade: 3.1.1 picocolors: 1.0.0 + /update-browserslist-db@1.0.11(browserslist@4.21.10): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.10 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /update-notifier@5.1.0: resolution: {integrity: sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==} engines: {node: '>=10'} @@ -17080,6 +17503,7 @@ packages: /urix@0.1.0: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated dev: true /url-loader@4.1.1(file-loader@6.2.0)(webpack@4.46.0): @@ -17106,11 +17530,11 @@ packages: prepend-http: 2.0.0 dev: true - /url@0.11.0: - resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} + /url@0.11.1: + resolution: {integrity: sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==} dependencies: - punycode: 1.3.2 - querystring: 0.2.0 + punycode: 1.4.1 + qs: 6.11.2 dev: true /use-sync-external-store@1.2.0(react@18.2.0): @@ -17260,7 +17684,7 @@ packages: /watchpack@1.7.5: resolution: {integrity: sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 neo-async: 2.6.2 optionalDependencies: chokidar: 3.5.3 @@ -17445,7 +17869,7 @@ packages: eslint-scope: 4.0.3 json-parse-better-errors: 1.0.2 loader-runner: 2.4.0 - loader-utils: 1.4.0 + loader-utils: 1.4.2 memory-fs: 0.4.1 micromatch: 3.1.10 mkdirp: 0.5.6 -- cgit v1.2.3 From 6affe04fe6919767181274891fd948688dedd700 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 14:19:24 +0200 Subject: harness: wait for withdrawal, configure instance properly --- .../src/integrationtests/test-bank-api.ts | 2 +- .../src/integrationtests/test-denom-unoffered.ts | 3 ++- .../src/integrationtests/test-payment-multiple.ts | 4 ++- .../src/integrationtests/test-refund-gone.ts | 4 ++- .../src/integrationtests/test-wallet-balance.ts | 17 ++++++++++-- .../taler-wallet-core/src/util/coinSelection.ts | 30 +++++++++++----------- 6 files changed, 39 insertions(+), 21 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index 1c359732e..a13ff63c7 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -106,7 +106,7 @@ export async function runBankApiTest(t: GlobalTestState) { // Make sure that registering twice results in a 409 Conflict { const e = await t.assertThrowsTalerErrorAsync(async () => { - await bankClient.registerAccount("user1", "pw1"); + await bankClient.registerAccount("user1", "pw2"); }); t.assertTrue(e.errorDetail.httpStatusCode === 409); } diff --git a/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts b/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts index afd0c901b..b4268ee42 100644 --- a/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts +++ b/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts @@ -50,13 +50,14 @@ export async function runDenomUnofferedTest(t: GlobalTestState) { // Effectively we completely reset the exchange, // but keep the exchange master public key. + await merchant.stop(); + await exchange.stop(); await exchange.purgeDatabase(); await exchange.purgeSecmodKeys(); await exchange.start(); await exchange.pingUntilAvailable(); - await merchant.stop(); await merchant.start(); await merchant.pingUntilAvailable(); diff --git a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts index 23972ed63..4ef5e3bff 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts @@ -123,13 +123,15 @@ export async function runPaymentMultipleTest(t: GlobalTestState) { // Withdraw digital cash into the wallet. - await withdrawViaBankV2(t, { + const wres = await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:100", }); + await wres.withdrawalFinishedCond; + // Set up order. const orderResp = await merchantClient.createOrder({ diff --git a/packages/taler-harness/src/integrationtests/test-refund-gone.ts b/packages/taler-harness/src/integrationtests/test-refund-gone.ts index 9ba078a6d..d50919934 100644 --- a/packages/taler-harness/src/integrationtests/test-refund-gone.ts +++ b/packages/taler-harness/src/integrationtests/test-refund-gone.ts @@ -44,13 +44,15 @@ export async function runRefundGoneTest(t: GlobalTestState) { // Withdraw digital cash into the wallet. - await withdrawViaBankV2(t, { + const wres = await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:20", }); + await wres.withdrawalFinishedCond; + // Set up order. const orderResp = await merchantClient.createOrder({ diff --git a/packages/taler-harness/src/integrationtests/test-wallet-balance.ts b/packages/taler-harness/src/integrationtests/test-wallet-balance.ts index 243c90e2e..fc2774adf 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-balance.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-balance.ts @@ -19,7 +19,9 @@ */ import { Amounts, + Duration, MerchantApiClient, + MerchantContractTerms, PreparePayResultType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -41,7 +43,18 @@ export async function runWalletBalanceTest(t: GlobalTestState) { const { merchant, walletClient, exchange, bank } = await createSimpleTestkudosEnvironmentV2(t); - const merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl()); + await merchant.addInstanceWithWireAccount({ + id: "myinst", + name: "My Instance", + paytoUris: ["payto://void/foo"], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + const merchantClient = new MerchantApiClient( + merchant.makeInstanceBaseUrl("myinst"), + ); // Withdraw digital cash into the wallet. @@ -54,7 +67,7 @@ export async function runWalletBalanceTest(t: GlobalTestState) { await wres.withdrawalFinishedCond; - const order = { + const order: Partial = { summary: "Buy me!", amount: "TESTKUDOS:5", fulfillment_url: "taler://fulfillment-success/thx", diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts index daba2ead5..abf0bbc02 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.ts @@ -588,22 +588,22 @@ async function selectPayMerchantCandidates( for (const acc of exchangeDetails.wireInfo.accounts) { const pp = parsePaytoUri(acc.payto_uri); checkLogicInvariant(!!pp); - if (pp.targetType === req.wireMethod) { - // also check that wire method is supported now - const wireFeeStr = exchangeDetails.wireInfo.feesForType[ - req.wireMethod - ]?.find((x) => { - return AbsoluteTime.isBetween( - AbsoluteTime.now(), - AbsoluteTime.fromProtocolTimestamp(x.startStamp), - AbsoluteTime.fromProtocolTimestamp(x.endStamp), - ); - })?.wireFee; - if (wireFeeStr) { - wireMethodFee = wireFeeStr; - } - break; + if (pp.targetType !== req.wireMethod) { + continue; } + const wireFeeStr = exchangeDetails.wireInfo.feesForType[ + req.wireMethod + ]?.find((x) => { + return AbsoluteTime.isBetween( + AbsoluteTime.now(), + AbsoluteTime.fromProtocolTimestamp(x.startStamp), + AbsoluteTime.fromProtocolTimestamp(x.endStamp), + ); + })?.wireFee; + if (wireFeeStr) { + wireMethodFee = wireFeeStr; + } + break; } if (!wireMethodFee) { break; -- cgit v1.2.3 From cd9c3a143bc1ad88ce77d53c212a90f60660069a Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 18:35:43 +0200 Subject: remove deprecated auditor trust management --- packages/taler-util/src/wallet-types.ts | 11 --- packages/taler-wallet-core/src/db.ts | 81 ---------------- .../taler-wallet-core/src/internal-wallet-state.ts | 4 - .../taler-wallet-core/src/operations/balance.ts | 2 +- .../taler-wallet-core/src/operations/exchanges.ts | 51 ---------- .../src/operations/pay-peer-push-credit.ts | 1 - .../taler-wallet-core/src/operations/withdraw.ts | 104 +++++++++------------ packages/taler-wallet-core/src/wallet-api-types.ts | 3 +- packages/taler-wallet-core/src/wallet.ts | 39 ++------ 9 files changed, 51 insertions(+), 245 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 0070b18e4..353fb900d 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1464,22 +1464,11 @@ export interface ExchangeWithdrawalDetails { */ selectedDenoms: DenomSelectionState; - /** - * Does the wallet know about an auditor for - * the exchange that the reserve. - */ - isAudited: boolean; - /** * Did the user already accept the current terms of service for the exchange? */ termsOfServiceAccepted: boolean; - /** - * The exchange is trusted directly. - */ - isTrusted: boolean; - /** * The earliest deposit expiration of the selected coins. */ diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 0c51a68c9..4c0a6168d 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -139,8 +139,6 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName"; */ export const WALLET_DB_MINOR_VERSION = 10; - - /** * Format of the operation status code: xyznnn * @@ -293,61 +291,6 @@ export interface ReserveBankInfo { timestampBankConfirmed: TalerPreciseTimestamp | undefined; } -/** - * Record that indicates the wallet trusts - * a particular auditor. - */ -export interface AuditorTrustRecord { - /** - * Currency that we trust this auditor for. - */ - currency: string; - - /** - * Base URL of the auditor. - */ - auditorBaseUrl: string; - - /** - * Public key of the auditor. - */ - auditorPub: string; - - /** - * UIDs for the operation of adding this auditor - * as a trusted auditor. - * - * (Used for backup/sync merging and tombstones.) - */ - uids: string[]; -} - -/** - * Record to indicate trust for a particular exchange. - */ -export interface ExchangeTrustRecord { - /** - * Currency that we trust this exchange for. - */ - currency: string; - - /** - * Canonicalized exchange base URL. - */ - exchangeBaseUrl: string; - - /** - * Master public key of the exchange. - */ - exchangeMasterPub: string; - - /** - * UIDs for the operation of adding this exchange - * as trusted. - */ - uids: string[]; -} - /** * Status of a denomination. */ @@ -2451,30 +2394,6 @@ export const WalletStoresV1 = { describeContents({ keyPath: "key" }), {}, ), - auditorTrust: describeStore( - "auditorTrust", - describeContents({ - keyPath: ["currency", "auditorBaseUrl"], - }), - { - byAuditorPub: describeIndex("byAuditorPub", "auditorPub"), - byUid: describeIndex("byUid", "uids", { - multiEntry: true, - }), - }, - ), - exchangeTrust: describeStore( - "exchangeTrust", - describeContents({ - keyPath: ["currency", "exchangeBaseUrl"], - }), - { - byExchangeMasterPub: describeIndex( - "byExchangeMasterPub", - "exchangeMasterPub", - ), - }, - ), denominations: describeStore( "denominations", describeContents({ diff --git a/packages/taler-wallet-core/src/internal-wallet-state.ts b/packages/taler-wallet-core/src/internal-wallet-state.ts index a189c9cb3..20f8a7511 100644 --- a/packages/taler-wallet-core/src/internal-wallet-state.ts +++ b/packages/taler-wallet-core/src/internal-wallet-state.ts @@ -107,10 +107,6 @@ export interface ExchangeOperations { }>, exchangeBaseUrl: string, ): Promise; - getExchangeTrust( - ws: InternalWalletState, - exchangeInfo: ExchangeEntryRecord, - ): Promise; updateExchangeFromUrl( ws: InternalWalletState, baseUrl: string, diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 0fcab0542..9c08a57bf 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -281,7 +281,7 @@ export async function getAcceptableExchangeBaseUrls( const acceptableExchangeUrls = new Set(); const depositableExchangeUrls = new Set(); await ws.db - .mktx((x) => [x.exchanges, x.exchangeDetails, x.auditorTrust]) + .mktx((x) => [x.exchanges, x.exchangeDetails]) .runReadOnly(async (tx) => { // FIXME: We should have a DB index to look up all exchanges // for a particular auditor ... diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 311a71a6e..690bc3cec 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -972,54 +972,3 @@ export async function getExchangePaytoUri( )}`, ); } - -/** - * Check if and how an exchange is trusted and/or audited. - */ -export async function getExchangeTrust( - ws: InternalWalletState, - exchangeInfo: ExchangeEntryRecord, -): Promise { - let isTrusted = false; - let isAudited = false; - - return await ws.db - .mktx((x) => [ - x.exchanges, - x.exchangeDetails, - x.exchangeTrust, - x.auditorTrust, - ]) - .runReadOnly(async (tx) => { - const exchangeDetails = await getExchangeDetails( - tx, - exchangeInfo.baseUrl, - ); - - if (!exchangeDetails) { - throw Error(`exchange ${exchangeInfo.baseUrl} details not available`); - } - const exchangeTrustRecord = - await tx.exchangeTrust.indexes.byExchangeMasterPub.get( - exchangeDetails.masterPublicKey, - ); - if ( - exchangeTrustRecord && - exchangeTrustRecord.uids.length > 0 && - exchangeTrustRecord.currency === exchangeDetails.currency - ) { - isTrusted = true; - } - - for (const auditor of exchangeDetails.auditors) { - const auditorTrustRecord = - await tx.auditorTrust.indexes.byAuditorPub.get(auditor.auditor_pub); - if (auditorTrustRecord && auditorTrustRecord.uids.length > 0) { - isAudited = true; - break; - } - } - - return { isTrusted, isAudited }; - }); -} diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts index 47e9eaddd..afeeb2c6b 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts @@ -465,7 +465,6 @@ async function handlePendingMerge( x.reserves, x.exchanges, x.exchangeDetails, - x.exchangeTrust, ]) .runReadWrite(async (tx) => { const peerInc = await tx.peerPushPaymentIncoming.get( diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index d8ce0a9a2..2b76613e7 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -119,7 +119,6 @@ import { import { getExchangeDetails, getExchangePaytoUri, - getExchangeTrust, updateExchangeFromUrl, } from "./exchanges.js"; import { @@ -722,7 +721,9 @@ interface WithdrawalBatchResult { batchResp: ExchangeWithdrawBatchResponse; } enum AmlStatus { - normal= 0, pending = 1, fronzen = 2, + normal = 0, + pending = 1, + fronzen = 2, } async function handleKycRequired( @@ -769,7 +770,9 @@ async function handleKycRequired( const kycStatus = await kycStatusRes.json(); logger.info(`kyc status: ${j2s(kycStatus)}`); kycUrl = kycStatus.kyc_url; - } else if (kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons) { + } else if ( + kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons + ) { const kycStatus = await kycStatusRes.json(); logger.info(`aml status: ${j2s(kycStatus)}`); amlStatus = kycStatus.aml_status; @@ -805,11 +808,15 @@ async function handleKycRequired( requirementRow: uuidResp.requirement_row, }; wg2.kycUrl = kycUrl; - wg2.status = amlStatus === AmlStatus.normal || amlStatus === undefined ? WithdrawalGroupStatus.PendingKyc : - amlStatus === AmlStatus.pending ? WithdrawalGroupStatus.PendingAml : - amlStatus === AmlStatus.fronzen ? WithdrawalGroupStatus.SuspendedAml : - assertUnreachable(amlStatus); - + wg2.status = + amlStatus === AmlStatus.normal || amlStatus === undefined + ? WithdrawalGroupStatus.PendingKyc + : amlStatus === AmlStatus.pending + ? WithdrawalGroupStatus.PendingAml + : amlStatus === AmlStatus.fronzen + ? WithdrawalGroupStatus.SuspendedAml + : assertUnreachable(amlStatus); + await tx.withdrawalGroups.put(wg2); const newTxState = computeWithdrawalTransactionStatus(wg2); return { @@ -919,31 +926,31 @@ async function processPlanchetExchangeBatchRequest( // FIXME: handle individual error codes better! - const reqUrl = new URL( - `reserves/${withdrawalGroup.reservePub}/batch-withdraw`, - withdrawalGroup.exchangeBaseUrl, - ).href; + const reqUrl = new URL( + `reserves/${withdrawalGroup.reservePub}/batch-withdraw`, + withdrawalGroup.exchangeBaseUrl, + ).href; - try { - const resp = await ws.http.postJson(reqUrl, batchReq); - if (resp.status === HttpStatusCode.UnavailableForLegalReasons) { - await handleKycRequired(ws, withdrawalGroup, resp, 0, requestCoinIdxs); - } - const r = await readSuccessResponseJsonOrThrow( - resp, - codecForWithdrawBatchResponse(), - ); - return { - coinIdxs: requestCoinIdxs, - batchResp: r, - }; - } catch (e) { - await storeCoinError(e, requestCoinIdxs[0]); - return { - batchResp: { ev_sigs: [] }, - coinIdxs: [], - }; + try { + const resp = await ws.http.postJson(reqUrl, batchReq); + if (resp.status === HttpStatusCode.UnavailableForLegalReasons) { + await handleKycRequired(ws, withdrawalGroup, resp, 0, requestCoinIdxs); } + const r = await readSuccessResponseJsonOrThrow( + resp, + codecForWithdrawBatchResponse(), + ); + return { + coinIdxs: requestCoinIdxs, + batchResp: r, + }; + } catch (e) { + await storeCoinError(e, requestCoinIdxs[0]); + return { + batchResp: { ev_sigs: [] }, + coinIdxs: [], + }; + } } async function processPlanchetVerifyAndStoreCoin( @@ -1410,10 +1417,12 @@ async function processWithdrawalGroupPendingKyc( logger.info(`kyc status: ${j2s(kycStatus)}`); // FIXME: do we need to update the KYC url, or does it always stay constant? return { ready: false }; - } else if (kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons) { + } else if ( + kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons + ) { const kycStatus = await kycStatusRes.json(); logger.info(`aml status: ${j2s(kycStatus)}`); - return {ready : false} + return { ready: false }; } else { throw Error( `unexpected response from kyc-check (${kycStatusRes.status})`, @@ -1709,11 +1718,6 @@ export async function getExchangeWithdrawalInfo( exchangeWireAccounts.push(account.payto_uri); } - const { isTrusted, isAudited } = await ws.exchangeOps.getExchangeTrust( - ws, - exchange, - ); - let hasDenomWithAgeRestriction = false; logger.trace("computing earliest deposit expiration"); @@ -1792,8 +1796,6 @@ export async function getExchangeWithdrawalInfo( exchangePaytoUris: paytoUris, exchangeWireAccounts, exchangeVersion: exchangeDetails.protocolVersionRange || "unknown", - isAudited, - isTrusted, numOfferedDenoms: possibleDenoms.length, selectedDenoms, // FIXME: delete this field / replace by something we can display to the user @@ -2210,8 +2212,6 @@ export interface PrepareCreateWithdrawalGroupResult { withdrawalGroup: WithdrawalGroupRecord; transactionId: string; creationInfo?: { - isTrusted: boolean; - isAudited: boolean; amount: AmountJson; canonExchange: string; exchangeDetails: ExchangeDetailsRecord; @@ -2306,10 +2306,6 @@ export async function internalPrepareCreateWithdrawalGroup( logger.trace(exchangeDetails); throw Error("exchange not updated"); } - const { isAudited, isTrusted } = await getExchangeTrust( - ws, - exchangeInfo.exchange, - ); const transactionId = constructTransactionIdentifier({ tag: TransactionType.Withdrawal, withdrawalGroupId: withdrawalGroup.withdrawalGroupId, @@ -2319,8 +2315,6 @@ export async function internalPrepareCreateWithdrawalGroup( withdrawalGroup, transactionId, creationInfo: { - isAudited, - isTrusted, canonExchange, amount, exchangeDetails, @@ -2339,7 +2333,6 @@ export async function internalPerformCreateWithdrawalGroup( withdrawalGroups: typeof WalletStoresV1.withdrawalGroups; reserves: typeof WalletStoresV1.reserves; exchanges: typeof WalletStoresV1.exchanges; - exchangeTrust: typeof WalletStoresV1.exchangeTrust; }>, prep: PrepareCreateWithdrawalGroupResult, ): Promise { @@ -2347,7 +2340,7 @@ export async function internalPerformCreateWithdrawalGroup( if (!prep.creationInfo) { return { withdrawalGroup, transitionInfo: undefined }; } - const { isAudited, isTrusted, amount, canonExchange, exchangeDetails } = + const { amount, canonExchange, exchangeDetails } = prep.creationInfo; await tx.withdrawalGroups.add(withdrawalGroup); @@ -2363,15 +2356,6 @@ export async function internalPerformCreateWithdrawalGroup( await tx.exchanges.put(exchange); } - if (!isAudited && !isTrusted) { - await tx.exchangeTrust.put({ - currency: amount.currency, - exchangeBaseUrl: canonExchange, - exchangeMasterPub: exchangeDetails.masterPublicKey, - uids: [encodeCrock(getRandomBytes(32))], - }); - } - const oldTxState = { major: TransactionMajorState.None, minor: undefined, @@ -2417,7 +2401,6 @@ export async function internalCreateWithdrawalGroup( x.reserves, x.exchanges, x.exchangeDetails, - x.exchangeTrust, ]) .runReadWrite(async (tx) => { return await internalPerformCreateWithdrawalGroup(ws, tx, prep); @@ -2563,7 +2546,6 @@ export async function createManualWithdrawal( x.withdrawalGroups, x.exchanges, x.exchangeDetails, - x.exchangeTrust, ]) .runReadOnly(async (tx) => { return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId); diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 72cd37b10..d89ad257a 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -121,7 +121,7 @@ import { DeleteStoredBackupRequest, TestingSetTimetravelRequest, } from "@gnu-taler/taler-util"; -import { AuditorTrustRecord, WalletContractData } from "./db.js"; +import { WalletContractData } from "./db.js"; import { AddBackupProviderRequest, AddBackupProviderResponse, @@ -260,7 +260,6 @@ export interface WalletConfig { */ builtin: { exchanges: string[]; - auditors: AuditorTrustRecord[]; }; /** diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 9a3b8f235..7a1bd5a4f 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -199,7 +199,6 @@ import { downloadTosFromAcceptedFormat, getExchangeDetails, getExchangeRequestTimeout, - getExchangeTrust, provideExchangeRecordInTx, updateExchangeFromUrl, updateExchangeFromUrlHandler, @@ -527,7 +526,7 @@ async function runTaskLoop( */ async function fillDefaults(ws: InternalWalletState): Promise { await ws.db - .mktx((x) => [x.config, x.auditorTrust, x.exchanges, x.exchangeDetails]) + .mktx((x) => [x.config, x.exchanges, x.exchangeDetails]) .runReadWrite(async (tx) => { const appliedRec = await tx.config.get("currencyDefaultsApplied"); let alreadyApplied = appliedRec ? !!appliedRec.value : false; @@ -535,10 +534,6 @@ async function fillDefaults(ws: InternalWalletState): Promise { logger.trace("defaults already applied"); return; } - logger.info("importing default exchanges and auditors"); - for (const c of ws.config.builtin.auditors) { - await tx.auditorTrust.put(c); - } for (const baseUrl of ws.config.builtin.exchanges) { await addPresetExchangeEntry(tx, baseUrl); const now = AbsoluteTime.now(); @@ -1558,24 +1553,11 @@ async function dispatchRequestInternal( return {}; } case WalletApiOperation.ListCurrencies: { - return await ws.db - .mktx((x) => [x.auditorTrust, x.exchangeTrust]) - .runReadOnly(async (tx) => { - const trustedAuditors = await tx.auditorTrust.iter().toArray(); - const trustedExchanges = await tx.exchangeTrust.iter().toArray(); - return { - trustedAuditors: trustedAuditors.map((x) => ({ - currency: x.currency, - auditorBaseUrl: x.auditorBaseUrl, - auditorPub: x.auditorPub, - })), - trustedExchanges: trustedExchanges.map((x) => ({ - currency: x.currency, - exchangeBaseUrl: x.exchangeBaseUrl, - exchangeMasterPub: x.exchangeMasterPub, - })), - }; - }); + // FIXME: Remove / change to scoped currency approach. + return { + trustedAuditors: [], + trustedExchanges: [], + }; } case WalletApiOperation.WithdrawFakebank: { const req = codecForWithdrawFakebankRequest().decode(payload); @@ -1780,14 +1762,6 @@ export class Wallet { public static defaultConfig: Readonly = { builtin: { exchanges: ["https://exchange.demo.taler.net/"], - auditors: [ - { - currency: "KUDOS", - auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0", - auditorBaseUrl: "https://auditor.demo.taler.net/", - uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"], - }, - ], }, features: { allowHttp: false, @@ -1860,7 +1834,6 @@ class InternalWalletStateImpl implements InternalWalletState { exchangeOps: ExchangeOperations = { getExchangeDetails, - getExchangeTrust, updateExchangeFromUrl, }; -- cgit v1.2.3 From 1fcb55c84dc541e64ebbb2d16156bab275ff16c4 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 6 Sep 2023 18:43:37 +0200 Subject: remove ToS storage --- packages/taler-util/src/wallet-types.ts | 17 ----- packages/taler-wallet-core/src/db.ts | 7 -- .../taler-wallet-core/src/operations/exchanges.ts | 45 ----------- .../taler-wallet-core/src/operations/withdraw.ts | 1 - packages/taler-wallet-core/src/wallet.ts | 86 +++------------------- .../src/cta/Withdraw/state.ts | 1 - 6 files changed, 10 insertions(+), 147 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 353fb900d..0d78b405a 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1076,13 +1076,6 @@ export interface KnownBankAccounts { accounts: KnownBankAccountsInfo[]; } -export interface ExchangeTosStatusDetails { - acceptedVersion?: string; - currentVersion?: string; - contentType?: string; - content?: string; -} - /** * Wire fee for one wire method */ @@ -1253,7 +1246,6 @@ export interface ExchangeFullDetails { exchangeBaseUrl: string; currency: string; paytoUris: string[]; - tos: ExchangeTosStatusDetails; auditors: ExchangeAuditor[]; wireInfo: WireInfo; denomFees: DenomOperationMap; @@ -1317,14 +1309,6 @@ const codecForExchangeAuditor = (): Codec => .property("denomination_keys", codecForList(codecForAuditorDenomSig())) .build("codecForExchangeAuditor"); -const codecForExchangeTos = (): Codec => - buildCodecForObject() - .property("acceptedVersion", codecOptional(codecForString())) - .property("currentVersion", codecOptional(codecForString())) - .property("contentType", codecOptional(codecForString())) - .property("content", codecOptional(codecForString())) - .build("ExchangeTos"); - export const codecForFeeDescriptionPair = (): Codec => buildCodecForObject() .property("group", codecForString()) @@ -1357,7 +1341,6 @@ export const codecForExchangeFullDetails = (): Codec => .property("currency", codecForString()) .property("exchangeBaseUrl", codecForString()) .property("paytoUris", codecForList(codecForString())) - .property("tos", codecForExchangeTos()) .property("auditors", codecForList(codecForExchangeAuditor())) .property("wireInfo", codecForWireInfo()) .property("denomFees", codecForFeesByOperations()) diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 4c0a6168d..2c7673267 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -2382,13 +2382,6 @@ export const WalletStoresV1 = { byReservePub: describeIndex("byReservePub", "reservePub", {}), }, ), - exchangeTos: describeStore( - "exchangeTos", - describeContents({ - keyPath: ["exchangeBaseUrl", "etag"], - }), - {}, - ), config: describeStore( "config", describeContents({ keyPath: "key" }), diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 690bc3cec..13e89b16c 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -157,35 +157,6 @@ export async function getExchangeDetails( getExchangeDetails.makeContext = (db: DbAccess) => db.mktx((x) => [x.exchanges, x.exchangeDetails]); -/** - * Update the database based on the download of the terms of service. - */ -export async function updateExchangeTermsOfService( - ws: InternalWalletState, - exchangeBaseUrl: string, - tos: ExchangeTosDownloadResult, -): Promise { - await ws.db - .mktx((x) => [x.exchanges, x.exchangeTos, x.exchangeDetails]) - .runReadWrite(async (tx) => { - const d = await getExchangeDetails(tx, exchangeBaseUrl); - let tosRecord = await tx.exchangeTos.get([exchangeBaseUrl, tos.tosEtag]); - if (!tosRecord) { - tosRecord = { - etag: tos.tosEtag, - exchangeBaseUrl, - termsOfServiceContentType: tos.tosContentType, - termsOfServiceText: tos.tosText, - }; - await tx.exchangeTos.put(tosRecord); - } - if (d) { - d.tosCurrentEtag = tos.tosEtag; - await tx.exchangeDetails.put(d); - } - }); -} - /** * Mark a ToS version as accepted by the user. * @@ -740,7 +711,6 @@ export async function updateExchangeFromUrlHandler( const updated = await ws.db .mktx((x) => [ x.exchanges, - x.exchangeTos, x.exchangeDetails, x.exchangeSignKeys, x.denominations, @@ -801,21 +771,6 @@ export async function updateExchangeFromUrlHandler( const drRowId = await tx.exchangeDetails.put(newDetails); checkDbInvariant(typeof drRowId.key === "number"); - let tosRecord = await tx.exchangeTos.get([ - exchangeBaseUrl, - tosDownload.tosEtag, - ]); - - if (!tosRecord || tosRecord.etag !== existingTosAccepted?.etag) { - tosRecord = { - etag: tosDownload.tosEtag, - exchangeBaseUrl, - termsOfServiceContentType: tosDownload.tosContentType, - termsOfServiceText: tosDownload.tosText, - }; - await tx.exchangeTos.put(tosRecord); - } - for (const sk of keysInfo.signingKeys) { // FIXME: validate signing keys before inserting them await tx.exchangeSignKeys.put({ diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 2b76613e7..b2b25144d 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -1856,7 +1856,6 @@ export async function getWithdrawalDetailsForUri( .mktx((x) => [ x.exchanges, x.exchangeDetails, - x.exchangeTos, x.denominations, x.operationRetries, ]) diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 7a1bd5a4f..cb82a3a43 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -34,7 +34,6 @@ import { Duration, ExchangeDetailedResponse, ExchangeListItem, - ExchangeTosStatusDetails, ExchangesListResponse, FeeDescription, GetExchangeTosResult, @@ -202,7 +201,6 @@ import { provideExchangeRecordInTx, updateExchangeFromUrl, updateExchangeFromUrlHandler, - updateExchangeTermsOfService, } from "./operations/exchanges.js"; import { getMerchantInfo } from "./operations/merchants.js"; import { @@ -557,33 +555,6 @@ async function getExchangeTos( ): Promise { // FIXME: download ToS in acceptable format if passed! const { exchangeDetails } = await updateExchangeFromUrl(ws, exchangeBaseUrl); - const tosDetails = await ws.db - .mktx((x) => [x.exchangeTos]) - .runReadOnly(async (tx) => { - return await getExchangeTosStatusDetails(tx, exchangeDetails); - }); - const content = tosDetails.content; - const currentEtag = tosDetails.currentVersion; - const contentType = tosDetails.contentType; - if ( - content === undefined || - currentEtag === undefined || - contentType === undefined - ) { - throw Error("exchange is in invalid state"); - } - if ( - acceptedFormat && - acceptedFormat.findIndex((f) => f === contentType) !== -1 - ) { - return { - acceptedEtag: exchangeDetails.tosAccepted?.etag, - currentEtag, - content, - contentType, - tosStatus: getExchangeTosStatus(exchangeDetails), - }; - } const tosDownload = await downloadTosFromAcceptedFormat( ws, @@ -592,17 +563,15 @@ async function getExchangeTos( acceptedFormat, ); - if (tosDownload.tosContentType === contentType) { - return { - acceptedEtag: exchangeDetails.tosAccepted?.etag, - currentEtag, - content, - contentType, - tosStatus: getExchangeTosStatus(exchangeDetails), - }; - } - - await updateExchangeTermsOfService(ws, exchangeBaseUrl, tosDownload); + await ws.db + .mktx((x) => [x.exchanges, x.exchangeDetails]) + .runReadWrite(async (tx) => { + const d = await getExchangeDetails(tx, exchangeBaseUrl); + if (d) { + d.tosCurrentEtag = tosDownload.tosEtag; + await tx.exchangeDetails.put(d); + } + }); return { acceptedEtag: exchangeDetails.tosAccepted?.etag, @@ -683,32 +652,6 @@ async function forgetKnownBankAccounts( return; } -async function getExchangeTosStatusDetails( - tx: GetReadOnlyAccess<{ exchangeTos: typeof WalletStoresV1.exchangeTos }>, - exchangeDetails: ExchangeDetailsRecord, -): Promise { - let exchangeTos = await tx.exchangeTos.get([ - exchangeDetails.exchangeBaseUrl, - exchangeDetails.tosCurrentEtag, - ]); - - if (!exchangeTos) { - exchangeTos = { - etag: "not-available", - termsOfServiceContentType: "text/plain", - termsOfServiceText: "terms of service unavailable", - exchangeBaseUrl: exchangeDetails.exchangeBaseUrl, - }; - } - - return { - acceptedVersion: exchangeDetails.tosAccepted?.etag, - content: exchangeTos.termsOfServiceText, - contentType: exchangeTos.termsOfServiceContentType, - currentVersion: exchangeTos.etag, - }; -} - async function getExchanges( ws: InternalWalletState, ): Promise { @@ -717,7 +660,6 @@ async function getExchanges( .mktx((x) => [ x.exchanges, x.exchangeDetails, - x.exchangeTos, x.denominations, x.operationRetries, ]) @@ -742,12 +684,7 @@ async function getExchangeDetailedInfo( ): Promise { //TODO: should we use the forceUpdate parameter? const exchange = await ws.db - .mktx((x) => [ - x.exchanges, - x.exchangeTos, - x.exchangeDetails, - x.denominations, - ]) + .mktx((x) => [x.exchanges, x.exchangeDetails, x.denominations]) .runReadOnly(async (tx) => { const ex = await tx.exchanges.get(exchangeBaseurl); const dp = ex?.detailsPointer; @@ -769,8 +706,6 @@ async function getExchangeDetailedInfo( return; } - const tos = await getExchangeTosStatusDetails(tx, exchangeDetails); - const denominations: DenominationInfo[] = denominationRecords.map((x) => DenominationRecord.toDenomInfo(x), ); @@ -779,7 +714,6 @@ async function getExchangeDetailedInfo( info: { exchangeBaseUrl: ex.baseUrl, currency, - tos, paytoUris: exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri), auditors: exchangeDetails.auditors, wireInfo: exchangeDetails.wireInfo, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 72cabe5a4..a3855c2f4 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -23,7 +23,6 @@ import { ExchangeTosStatus, TalerError, parseWithdrawExchangeUri, - stringifyWithdrawUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; -- cgit v1.2.3 From c660db82c12e08020661828f1d8383baa7ef0e02 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 7 Sep 2023 20:35:46 +0200 Subject: wallet-core: address DB FIXMEs, systematic state numbering --- .../src/integrationtests/test-peer-repair.ts | 2 +- .../src/integrationtests/test-peer-to-peer-pull.ts | 2 +- .../src/integrationtests/test-peer-to-peer-push.ts | 2 +- packages/taler-util/src/wallet-types.ts | 12 +- packages/taler-wallet-cli/src/index.ts | 12 +- packages/taler-wallet-core/src/db.ts | 556 +++++++-------------- .../taler-wallet-core/src/operations/balance.ts | 2 +- .../taler-wallet-core/src/operations/common.ts | 28 +- .../src/operations/pay-merchant.ts | 10 +- .../src/operations/pay-peer-pull-credit.ts | 328 ++++++------ .../src/operations/pay-peer-pull-debit.ts | 178 +++---- .../src/operations/pay-peer-push-credit.ts | 314 ++++++------ .../src/operations/pay-peer-push-debit.ts | 294 +++++------ .../taler-wallet-core/src/operations/pending.ts | 80 +-- .../taler-wallet-core/src/operations/reward.ts | 14 +- .../taler-wallet-core/src/operations/testing.ts | 4 +- .../src/operations/transactions.ts | 122 ++--- .../taler-wallet-core/src/operations/withdraw.ts | 12 +- packages/taler-wallet-core/src/pending-types.ts | 4 +- .../taler-wallet-core/src/util/coinSelection.ts | 2 +- packages/taler-wallet-core/src/util/query.ts | 109 ++-- packages/taler-wallet-core/src/wallet.ts | 16 +- .../src/cta/InvoicePay/state.ts | 4 +- .../src/cta/TransferPickup/state.ts | 4 +- 24 files changed, 990 insertions(+), 1121 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-harness/src/integrationtests/test-peer-repair.ts b/packages/taler-harness/src/integrationtests/test-peer-repair.ts index b09bff2dc..d457ce1e5 100644 --- a/packages/taler-harness/src/integrationtests/test-peer-repair.ts +++ b/packages/taler-harness/src/integrationtests/test-peer-repair.ts @@ -130,7 +130,7 @@ export async function runPeerRepairTest(t: GlobalTestState) { ); await wallet2.client.call(WalletApiOperation.ConfirmPeerPushCredit, { - peerPushPaymentIncomingId: resp2.peerPushPaymentIncomingId, + peerPushCreditId: resp2.peerPushCreditId, }); await peerPushCreditDone1Cond; diff --git a/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts b/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts index 5b55b1de1..25c000808 100644 --- a/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts +++ b/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts @@ -123,7 +123,7 @@ export async function runPeerToPeerPullTest(t: GlobalTestState) { ); await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, { - peerPullPaymentIncomingId: checkResp.peerPullPaymentIncomingId, + peerPullDebitId: checkResp.peerPullDebitId, }); await peerPullCreditDoneCond; diff --git a/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts b/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts index 26f70a5cc..018fa2020 100644 --- a/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts +++ b/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts @@ -126,7 +126,7 @@ export async function runPeerToPeerPushTest(t: GlobalTestState) { const acceptResp = await w2.walletClient.call( WalletApiOperation.ConfirmPeerPushCredit, { - peerPushPaymentIncomingId: checkResp.peerPushPaymentIncomingId, + peerPushCreditId: checkResp.peerPushCreditId, }, ); diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 0d78b405a..c6f19c73f 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -2438,7 +2438,7 @@ export interface PreparePeerPushCreditResponse { amount: AmountString; amountRaw: AmountString; amountEffective: AmountString; - peerPushPaymentIncomingId: string; + peerPushCreditId: string; transactionId: string; } @@ -2453,7 +2453,7 @@ export interface PreparePeerPullDebitResponse { amountRaw: AmountString; amountEffective: AmountString; - peerPullPaymentIncomingId: string; + peerPullDebitId: string; transactionId: string; } @@ -2476,7 +2476,7 @@ export interface ConfirmPeerPushCreditRequest { * * @deprecated specify transactionId instead! */ - peerPushPaymentIncomingId?: string; + peerPushCreditId?: string; transactionId?: string; } @@ -2491,7 +2491,7 @@ export interface AcceptPeerPullPaymentResponse { export const codecForConfirmPeerPushPaymentRequest = (): Codec => buildCodecForObject() - .property("peerPushPaymentIncomingId", codecOptional(codecForString())) + .property("peerPushCreditId", codecOptional(codecForString())) .property("transactionId", codecOptional(codecForString())) .build("ConfirmPeerPushCreditRequest"); @@ -2501,7 +2501,7 @@ export interface ConfirmPeerPullDebitRequest { * * @deprecated use transactionId instead */ - peerPullPaymentIncomingId?: string; + peerPullDebitId?: string; transactionId?: string; } @@ -2519,7 +2519,7 @@ export const codecForApplyDevExperiment = export const codecForAcceptPeerPullPaymentRequest = (): Codec => buildCodecForObject() - .property("peerPullPaymentIncomingId", codecOptional(codecForString())) + .property("peerPullDebitId", codecOptional(codecForString())) .property("transactionId", codecOptional(codecForString())) .build("ConfirmPeerPullDebitRequest"); diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index 943283a36..3fc86d0b5 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -1024,14 +1024,14 @@ peerCli peerCli .subcommand("confirmIncomingPayPull", "confirm-pull-debit") - .requiredArgument("peerPullPaymentIncomingId", clk.STRING) + .requiredArgument("peerPullDebitId", clk.STRING) .action(async (args) => { await withWallet(args, async (wallet) => { const resp = await wallet.client.call( WalletApiOperation.ConfirmPeerPullDebit, { - peerPullPaymentIncomingId: - args.confirmIncomingPayPull.peerPullPaymentIncomingId, + peerPullDebitId: + args.confirmIncomingPayPull.peerPullDebitId, }, ); console.log(JSON.stringify(resp, undefined, 2)); @@ -1040,14 +1040,14 @@ peerCli peerCli .subcommand("confirmIncomingPayPush", "confirm-push-credit") - .requiredArgument("peerPushPaymentIncomingId", clk.STRING) + .requiredArgument("peerPushCreditId", clk.STRING) .action(async (args) => { await withWallet(args, async (wallet) => { const resp = await wallet.client.call( WalletApiOperation.ConfirmPeerPushCredit, { - peerPushPaymentIncomingId: - args.confirmIncomingPayPush.peerPushPaymentIncomingId, + peerPushCreditId: + args.confirmIncomingPayPush.peerPushCreditId, }, ); console.log(JSON.stringify(resp, undefined, 2)); diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 2c7673267..9aedb888b 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -60,7 +60,8 @@ import { Logger, CoinPublicKeyString, TalerPreciseTimestamp, - j2s, + codecForAny, + Codec, } from "@gnu-taler/taler-util"; import { DbAccess, @@ -106,7 +107,7 @@ import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; * for all previous versions must be written, which should be * avoided. */ -export const TALER_WALLET_MAIN_DB_NAME = "taler-wallet-main-v9"; +export const TALER_WALLET_MAIN_DB_NAME = "taler-wallet-main-v10"; /** * Name of the metadata database. This database is used @@ -137,50 +138,26 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName"; * backwards-compatible way or object stores and indices * are added. */ -export const WALLET_DB_MINOR_VERSION = 10; +export const WALLET_DB_MINOR_VERSION = 1; /** - * Format of the operation status code: xyznnn - * - * x=1: active - * yz=00: pending - * yz=02: dialog - * yz=03: aborting - * yz=10: suspended - * yz=13: suspended-aborting - * x=2: final - * yz=00: done - * yz=01: failed - * yz=02: expired - * yz=03: aborted - */ -// export const OperationStatusRange = { -// ActiveStart: 10000, -// ActiveEnd: 10999, -// SuspendedStart: 10999, -// SuspendedEnd: 10999, -// FinalStart: 20000, -// FinalEnd: 29999, -//} as const; - -/** - * Ranges for operation status fields. - * - * All individual enums should make sure that the values they - * defined are in the right range. + * Format of the operation status code: 0x0abc_nnnn + + * a=1: active + * 0x0100_nnnn: pending + * 0x0101_nnnn: dialog + * 0x0102_nnnn: (reserved) + * 0x0103_nnnn: aborting + * 0x0110_nnnn: suspended + * 0x0113_nnnn: suspended-aborting + * a=5: final + * 0x0500_nnnn: done + * 0x0501_nnnn: failed + * 0x0502_nnnn: expired + * 0x0503_nnnn: aborted + * + * nnnn=0000 should always be the most generic minor state for the major state */ -export enum OperationStatusRange { - // Operations that need to be actively processed. - ACTIVE_START = 10, - ACTIVE_END = 29, - // Operations that are suspended and might - // expire, but nothing else can be done. - SUSPENDED_START = 30, - SUSPENDED_END = 49, - // Operations that don't need any attention or processing. - DORMANT_START = 50, - DORMANT_END = 69, -} /** * Status of a withdrawal. @@ -189,71 +166,70 @@ export enum WithdrawalGroupStatus { /** * Reserve must be registered with the bank. */ - PendingRegisteringBank = 10, + PendingRegisteringBank = 0x0100_0000, + SuspendedRegisteringBank = 0x0110_0000, /** * We've registered reserve's information with the bank * and are now waiting for the user to confirm the withdraw * with the bank (typically 2nd factor auth). */ - PendingWaitConfirmBank = 11, + PendingWaitConfirmBank = 0x0100_0001, + SuspendedWaitConfirmBank = 0x0110_0001, /** * Querying reserve status with the exchange. */ - PendingQueryingStatus = 12, + PendingQueryingStatus = 0x0100_0002, + SuspendedQueryingStatus = 0x0110_0002, /** * Ready for withdrawal. */ - PendingReady = 13, + PendingReady = 0x0100_0003, + SuspendedReady = 0x0110_0003, /** * We are telling the bank that we don't want to complete * the withdrawal! */ - AbortingBank = 14, + AbortingBank = 0x0103_0000, + SuspendedAbortingBank = 0x0113_0000, /** * Exchange wants KYC info from the user. */ - PendingKyc = 16, + PendingKyc = 0x0100_0004, + SuspendedKyc = 0x0110_004, /** * Exchange is doing AML checks. */ - PendingAml = 17, - - SuspendedRegisteringBank = 30, - SuspendedWaitConfirmBank = 31, - SuspendedQueryingStatus = 32, - SuspendedReady = 33, - SuspendedAbortingBank = 34, - SuspendedKyc = 35, - SuspendedAml = 36, + PendingAml = 0x0100_0005, + SuspendedAml = 0x0100_0005, /** * The corresponding withdraw record has been created. * No further processing is done, unless explicitly requested * by the user. */ - Finished = 50, + Done = 0x0500_0000, /** * The bank aborted the withdrawal. */ - FailedBankAborted = 51, + FailedBankAborted = 0x0501_0000, - FailedAbortingBank = 59, + FailedAbortingBank = 0x0501_0001, /** * Aborted in a state where we were supposed to * talk to the exchange. Money might have been * wired or not. */ - AbortedExchange = 60, + AbortedExchange = 0x0503_0001, - AbortedBank = 61, + AbortedBank = 0x0503_0002, } /** @@ -298,17 +274,17 @@ export enum DenominationVerificationStatus { /** * Verification was delayed. */ - Unverified = OperationStatusRange.ACTIVE_START, + Unverified = 0x0500_0000, /** * Verified as valid. */ - VerifiedGood = OperationStatusRange.DORMANT_START, + VerifiedGood = 0x0500_0000, /** * Verified as invalid. */ - VerifiedBad = OperationStatusRange.DORMANT_START + 1, + VerifiedBad = 0x0501_0000, } export interface DenomFees { @@ -904,50 +880,42 @@ export interface RewardRecord { } export enum RewardRecordStatus { - PendingPickup = 10, - - SuspendidPickup = 20, - - DialogAccept = 30, - - Done = 50, - Aborted = 51, + PendingPickup = 0x0100_0000, + SuspendedPickup = 0x0110_0000, + DialogAccept = 0x0101_0000, + Done = 0x0500_0000, + Aborted = 0x0500_0000, } export enum RefreshCoinStatus { - Pending = OperationStatusRange.ACTIVE_START, - Finished = OperationStatusRange.DORMANT_START, + Pending = 0x0100_0000, + Finished = 0x0500_0000, /** * The refresh for this coin has been frozen, because of a permanent error. * More info in lastErrorPerCoin. */ - Failed = OperationStatusRange.DORMANT_START + 1, -} - -export enum OperationStatus { - Finished = OperationStatusRange.DORMANT_START, - Pending = OperationStatusRange.ACTIVE_START, + Failed = 0x0501_000, } export enum RefreshOperationStatus { - Pending = 10 /* ACTIVE_START */, - Suspended = 20 /* DORMANT_START + 2 */, + Pending = 0x0100_0000, + Suspended = 0x0110_0000, - Finished = 50 /* DORMANT_START */, - Failed = 51 /* DORMANT_START + 1 */, + Finished = 0x0500_000, + Failed = 0x0501_000, } /** * Status of a single element of a deposit group. */ export enum DepositElementStatus { - Unknown = 10, - Accepted = 20, - KycRequired = 30, - Wired = 40, - RefundSuccess = 50, - RefundFailed = 51, + Unknown = 0x0100_0000, + Accepted = 0x0100_0001, + KycRequired = 0x0100_0002, + Wired = 0x0500_0000, + RefundSuccess = 0x0503_0000, + RefundFailed = 0x0501_0000, } /** @@ -962,9 +930,6 @@ export interface RefreshReasonDetails { * Group of refresh operations. The refreshed coins do not * have to belong to the same exchange, but must have the same * currency. - * - * FIXME: Should include the currency as a top-level field, - * but we need to write a migration for that. */ export interface RefreshGroupRecord { operationStatus: RefreshOperationStatus; @@ -980,8 +945,6 @@ export interface RefreshGroupRecord { /** * Currency of this refresh group. - * - * FIXME: Write a migration to add this to earlier DB versions. */ currency: string; @@ -1116,81 +1079,84 @@ export enum PurchaseStatus { /** * Not downloaded yet. */ - PendingDownloadingProposal = 10, + PendingDownloadingProposal = 0x0100_0000, + SuspendedDownloadingProposal = 0x0110_0000, /** * The user has accepted the proposal. */ - PendingPaying = 11, + PendingPaying = 0x0100_0001, + SuspendedPaying = 0x0110_0001, /** * Currently in the process of aborting with a refund. */ - AbortingWithRefund = 12, + AbortingWithRefund = 0x0103_0000, + SuspendedAbortingWithRefund = 0x0113_0000, /** * Paying a second time, likely with different session ID */ - PendingPayingReplay = 13, + PendingPayingReplay = 0x0100_0002, + SuspendedPayingReplay = 0x0110_0002, /** * Query for refunds (until query succeeds). */ - PendingQueryingRefund = 14, + PendingQueryingRefund = 0x0100_0003, + SuspendedQueryingRefund = 0x0110_0003, /** * Query for refund (until auto-refund deadline is reached). */ - PendingQueryingAutoRefund = 15, + PendingQueryingAutoRefund = 0x0100_0004, + SuspendedQueryingAutoRefund = 0x0110_0004, - PendingAcceptRefund = 16, - - SuspendedDownloadingProposal = 20, - SuspendedPaying = 21, - SuspendedAbortingWithRefund = 22, - SuspendedPayingReplay = 23, - SuspendedQueryingRefund = 24, - SuspendedQueryingAutoRefund = 25, - SuspendedPendingAcceptRefund = 26, + PendingAcceptRefund = 0x0100_0005, + SuspendedPendingAcceptRefund = 0x0100_0005, /** * Proposal downloaded, but the user needs to accept/reject it. */ - DialogProposed = 30, + DialogProposed = 0x0101_0000, + /** * Proposal shared to other wallet or read from other wallet * the user needs to accept/reject it. */ - DialogShared = 31, + DialogShared = 0x0101_0001, /** * The user has rejected the proposal. */ - AbortedProposalRefused = 50, + AbortedProposalRefused = 0x0503_0000, /** * Downloading or processing the proposal has failed permanently. */ - FailedClaim = 51, + FailedClaim = 0x0501_0000, + + /** + * Payment was successful. + */ + Done = 0x0500_0000, /** * Downloaded proposal was detected as a re-purchase. */ - RepurchaseDetected = 52, + DoneRepurchaseDetected = 0x0500_0001, /** * The payment has been aborted. */ - AbortedIncompletePayment = 53, + AbortedIncompletePayment = 0x0503_0000, /** - * Payment was successful. + * Tried to abort, but aborting failed or was cancelled. */ - Done = 54, - - FailedAbort = 55, + FailedAbort = 0x0501_0001, - AbortedRefunded = 56, + AbortedRefunded = 0x0503_0000, } /** @@ -1304,14 +1270,6 @@ export interface PurchaseRecord { */ timestampAccept: TalerPreciseTimestamp | undefined; - /** - * Pending refunds for the purchase. A refund is pending - * when the merchant reports a transient error from the exchange. - * - * FIXME: Put this into a separate object store? - */ - // refunds: { [refundKey: string]: WalletRefundItem }; - /** * When was the last refund made? * Set to 0 if no refund was made on the purchase. @@ -1375,6 +1333,7 @@ export interface WalletBackupConfState { lastBackupNonce?: string; } +// FIXME: Should these be numeric codes? export const enum WithdrawalRecordType { BankManual = "bank-manual", BankIntegrated = "bank-integrated", @@ -1684,19 +1643,21 @@ export interface BackupProviderRecord { } export enum DepositOperationStatus { - PendingDeposit = 10, - Aborting = 11, - PendingTrack = 12, - PendingKyc = 13, + PendingDeposit = 0x0100_0000, + PendingTrack = 0x0100_0001, + PendingKyc = 0x0100_0002, + + Aborting = 0x0103_0000, - SuspendedDeposit = 20, - SuspendedAborting = 21, - SuspendedTrack = 22, - SuspendedKyc = 23, + SuspendedDeposit = 0x0110_0000, + SuspendedTrack = 0x0110_0001, + SuspendedKyc = 0x0110_0002, - Finished = 50, - Failed = 51, - Aborted = 52, + SuspendedAborting = 0x0113_0000, + + Finished = 0x0500_0000, + Failed = 0x0501_0000, + Aborted = 0x0503_0000, } export interface DepositTrackingInfo { @@ -1787,31 +1748,6 @@ export interface DepositKycInfo { exchangeBaseUrl: string; } -/** - * Record for a deposits that the wallet observed - * as a result of double spending, but which is not - * present in the wallet's own database otherwise. - */ -export interface GhostDepositGroupRecord { - /** - * When multiple deposits for the same contract terms hash - * have a different timestamp, we choose the earliest one. - */ - timestamp: TalerPreciseTimestamp; - - contractTermsHash: string; - - deposits: { - coinPub: string; - amount: AmountString; - timestamp: TalerProtocolTimestamp; - depositFee: AmountString; - merchantPub: string; - coinSig: string; - wireHash: string; - }[]; -} - export interface TombstoneRecord { /** * Tombstone ID, with the syntax "tmb::". @@ -1819,24 +1755,24 @@ export interface TombstoneRecord { id: string; } -export enum PeerPushPaymentInitiationStatus { +export enum PeerPushDebitStatus { /** * Initiated, but no purse created yet. */ - PendingCreatePurse = 10 /* ACTIVE_START */, - PendingReady = 11, - AbortingDeletePurse = 12, - AbortingRefresh = 13, + PendingCreatePurse = 0x0100_0000 /* ACTIVE_START */, + PendingReady = 0x0100_0001, + AbortingDeletePurse = 0x0103_0000, + AbortingRefresh = 0x0103_0001, - SuspendedCreatePurse = 30, - SuspendedReady = 31, - SuspendedAbortingDeletePurse = 32, - SuspendedAbortingRefresh = 33, + SuspendedCreatePurse = 0x0110_0000, + SuspendedReady = 0x0110_0001, + SuspendedAbortingDeletePurse = 0x0113_0000, + SuspendedAbortingRefresh = 0x0113_0001, - Done = 50 /* DORMANT_START */, - Aborted = 51, - Failed = 52, - Expired = 53, + Done = 0x0500_0000, + Aborted = 0x0503_0000, + Failed = 0x0501_0000, + Expired = 0x0502_0000, } export interface PeerPushPaymentCoinSelection { @@ -1847,7 +1783,7 @@ export interface PeerPushPaymentCoinSelection { /** * Record for a push P2P payment that this wallet initiated. */ -export interface PeerPushPaymentInitiationRecord { +export interface PeerPushDebitRecord { /** * What exchange are funds coming from? */ @@ -1907,32 +1843,34 @@ export interface PeerPushPaymentInitiationRecord { /** * Status of the peer push payment initiation. */ - status: PeerPushPaymentInitiationStatus; + status: PeerPushDebitStatus; } -export enum PeerPullPaymentInitiationStatus { - PendingCreatePurse = 10 /* ACTIVE_START */, +export enum PeerPullPaymentCreditStatus { + PendingCreatePurse = 0x0100_0000, /** * Purse created, waiting for the other party to accept the * invoice and deposit money into it. */ - PendingReady = 11 /* ACTIVE_START + 1 */, - PendingMergeKycRequired = 12 /* ACTIVE_START + 2 */, - PendingWithdrawing = 13, - AbortingDeletePurse = 14, + PendingReady = 0x0100_0001, + PendingMergeKycRequired = 0x0100_0002, + PendingWithdrawing = 0x0100_0003, - SuspendedCreatePurse = 30, - SuspendedReady = 31, - SuspendedMergeKycRequired = 32, - SuspendedWithdrawing = 33, - SuspendedAbortingDeletePurse = 34, + AbortingDeletePurse = 0x0103_0000, - Done = 50 /* DORMANT_START */, - Failed = 51, - Aborted = 52, + SuspendedCreatePurse = 0x0110_0000, + SuspendedReady = 0x0110_0001, + SuspendedMergeKycRequired = 0x0110_0002, + SuspendedWithdrawing = 0x0113_0000, + + SuspendedAbortingDeletePurse = 0x0113_0000, + + Done = 0x0500_0000, + Failed = 0x0501_0000, + Aborted = 0x0503_0000, } -export interface PeerPullPaymentInitiationRecord { +export interface PeerPullCreditRecord { /** * What exchange are we using for the payment request? */ @@ -1982,7 +1920,7 @@ export interface PeerPullPaymentInitiationRecord { /** * Status of the peer pull payment initiation. */ - status: PeerPullPaymentInitiationStatus; + status: PeerPullPaymentCreditStatus; kycInfo?: KycPendingInfo; @@ -1991,24 +1929,24 @@ export interface PeerPullPaymentInitiationRecord { withdrawalGroupId: string | undefined; } -export enum PeerPushPaymentIncomingStatus { - PendingMerge = 10 /* ACTIVE_START */, - PendingMergeKycRequired = 11 /* ACTIVE_START + 1 */, +export enum PeerPushCreditStatus { + PendingMerge = 0x0100_0000, + PendingMergeKycRequired = 0x0100_0001, /** * Merge was successful and withdrawal group has been created, now * everything is in the hand of the withdrawal group. */ - PendingWithdrawing = 12, + PendingWithdrawing = 0x0100_0002, - SuspendedMerge = 20, - SuspendedMergeKycRequired = 21, - SuspendedWithdrawing = 22, + SuspendedMerge = 0x0110_0000, + SuspendedMergeKycRequired = 0x0110_0001, + SuspendedWithdrawing = 0x0110_0002, - DialogProposed = 30 /* USER_ATTENTION_START */, + DialogProposed = 0x0101_0000, - Done = 50 /* DORMANT_START */, - Aborted = 51, - Failed = 52, + Done = 0x0500_0000, + Aborted = 0x0503_0000, + Failed = 0x0501_0000, } /** @@ -2017,7 +1955,7 @@ export enum PeerPushPaymentIncomingStatus { * Unique: (exchangeBaseUrl, pursePub) */ export interface PeerPushPaymentIncomingRecord { - peerPushPaymentIncomingId: string; + peerPushCreditId: string; exchangeBaseUrl: string; @@ -2040,7 +1978,7 @@ export interface PeerPushPaymentIncomingRecord { /** * Status of the peer push payment incoming initiation. */ - status: PeerPushPaymentIncomingStatus; + status: PeerPushCreditStatus; /** * Associated withdrawal group. @@ -2061,17 +1999,17 @@ export interface PeerPushPaymentIncomingRecord { } export enum PeerPullDebitRecordStatus { - PendingDeposit = 10 /* ACTIVE_START */, - AbortingRefresh = 11, + PendingDeposit = 0x0100_0001, + AbortingRefresh = 0x0103_0001, - SuspendedDeposit = 20, - SuspendedAbortingRefresh = 21, + SuspendedDeposit = 0x0110_0001, + SuspendedAbortingRefresh = 0x0113_0001, - DialogProposed = 30 /* USER_ATTENTION_START */, + DialogProposed = 0x0101_0001, - DonePaid = 50 /* DORMANT_START */, - Aborted = 51, - Failed = 52, + Done = 0x0500_0000, + Aborted = 0x0503_0000, + Failed = 0x0501_0000, } export interface PeerPullPaymentCoinSelection { @@ -2089,7 +2027,7 @@ export interface PeerPullPaymentCoinSelection { * AKA PeerPullDebit. */ export interface PeerPullPaymentIncomingRecord { - peerPullPaymentIncomingId: string; + peerPullDebitId: string; pursePub: string; @@ -2234,10 +2172,10 @@ export interface CurrencySettingsRecord { } export enum RefundGroupStatus { - Pending = 10, - Done = 50, - Failed = 51, - Aborted = 52, + Pending = 0x0100_0000, + Done = 0x0500_0000, + Failed = 0x0501_0000, + Aborted = 0x0503_0000, } /** @@ -2273,16 +2211,16 @@ export enum RefundItemStatus { * * We'll try again! */ - Pending = 10, + Pending = 0x0100_0000, /** * Refund was obtained successfully. */ - Done = 50, + Done = 0x0500_0000, /** * Permanent error reported by the exchange * for the refund. */ - Failed = 51, + Failed = 0x0501_0000, } /** @@ -2298,7 +2236,9 @@ export interface RefundItemRecord { refundGroupId: string; - // Execution time as claimed by the merchant + /** + * Execution time as claimed by the merchant + */ executionTime: TalerProtocolTimestamp; /** @@ -2308,22 +2248,15 @@ export interface RefundItemRecord { refundAmount: AmountString; - //refundFee: AmountString; - - /** - * Upper bound on the refresh cost incurred by - * applying this refund. - * - * Might be lower in practice when two refunds on the same - * coin are refreshed in the same refresh operation. - */ - //totalRefreshCostBound: AmountString; - coinPub: string; rtxid: number; } +export function passthroughCodec(): Codec { + return codecForAny(); +} + /** * Schema definition for the IndexedDB * wallet database. @@ -2333,7 +2266,6 @@ export const WalletStoresV1 = { "currencySettings", describeContents({ keyPath: ["currency"], - versionAdded: 3, }), {}, ), @@ -2542,17 +2474,10 @@ export const WalletStoresV1 = { }), {}, ), - ghostDepositGroups: describeStore( - "ghostDepositGroups", - describeContents({ - keyPath: "contractTermsHash", - }), - {}, - ), - peerPushPaymentIncoming: describeStore( - "peerPushPaymentIncoming", + peerPushCredit: describeStore( + "peerPushCredit", describeContents({ - keyPath: "peerPushPaymentIncomingId", + keyPath: "peerPushCreditId", }), { byExchangeAndPurse: describeIndex("byExchangeAndPurse", [ @@ -2563,24 +2488,21 @@ export const WalletStoresV1 = { "byExchangeAndContractPriv", ["exchangeBaseUrl", "contractPriv"], { - versionAdded: 5, unique: true, }, ), byWithdrawalGroupId: describeIndex( "byWithdrawalGroupId", "withdrawalGroupId", - { - versionAdded: 5, - }, + {}, ), byStatus: describeIndex("byStatus", "status"), }, ), - peerPullPaymentIncoming: describeStore( - "peerPullPaymentIncoming", + peerPullDebit: describeStore( + "peerPullDebit", describeContents({ - keyPath: "peerPullPaymentIncomingId", + keyPath: "peerPullDebitId", }), { byExchangeAndPurse: describeIndex("byExchangeAndPurse", [ @@ -2591,16 +2513,15 @@ export const WalletStoresV1 = { "byExchangeAndContractPriv", ["exchangeBaseUrl", "contractPriv"], { - versionAdded: 5, unique: true, }, ), byStatus: describeIndex("byStatus", "status"), }, ), - peerPullPaymentInitiations: describeStore( - "peerPullPaymentInitiations", - describeContents({ + peerPullCredit: describeStore( + "peerPullCredit", + describeContents({ keyPath: "pursePub", }), { @@ -2609,14 +2530,13 @@ export const WalletStoresV1 = { "byWithdrawalGroupId", "withdrawalGroupId", { - versionAdded: 5, }, ), }, ), - peerPushPaymentInitiations: describeStore( - "peerPushPaymentInitiations", - describeContents({ + peerPushDebit: describeStore( + "peerPushDebit", + describeContents({ keyPath: "pursePub", }), { @@ -2641,7 +2561,6 @@ export const WalletStoresV1 = { "userAttention", describeContents({ keyPath: ["entityId", "info.type"], - versionAdded: 2, }), {}, ), @@ -2649,12 +2568,10 @@ export const WalletStoresV1 = { "refundGroups", describeContents({ keyPath: "refundGroupId", - versionAdded: 7, }), { byProposalId: describeIndex("byProposalId", "proposalId"), byStatus: describeIndex("byStatus", "status", { - versionAdded: 10, }), }, ), @@ -2662,7 +2579,6 @@ export const WalletStoresV1 = { "refundItems", describeContents({ keyPath: "id", - versionAdded: 7, autoIncrement: true, }), { @@ -2677,7 +2593,6 @@ export const WalletStoresV1 = { "fixups", describeContents({ keyPath: "fixupName", - versionAdded: 2, }), {}, ), @@ -2905,106 +2820,7 @@ export interface FixupDescription { /** * Manual migrations between minor versions of the DB schema. */ -export const walletDbFixups: FixupDescription[] = [ - { - name: "RefreshGroupRecord_currency", - async fn(tx): Promise { - await tx.refreshGroups.iter().forEachAsync(async (rg) => { - if (rg.currency) { - return; - } - // Empty refresh group without input coin, delete it! - if (rg.inputPerCoin.length === 0) { - await tx.refreshGroups.delete(rg.refreshGroupId); - return; - } - rg.currency = Amounts.parseOrThrow(rg.inputPerCoin[0]).currency; - await tx.refreshGroups.put(rg); - }); - }, - }, - { - name: "DepositGroupRecord_transactionPerCoin", - async fn(tx): Promise { - await tx.depositGroups.iter().forEachAsync(async (dg) => { - if (dg.transactionPerCoin) { - return; - } - dg.transactionPerCoin = dg.depositedPerCoin.map( - (c) => DepositElementStatus.Unknown, - ); - await tx.depositGroups.put(dg); - }); - }, - }, - { - name: "PeerPullPaymentIncomingRecord_totalCostEstimated_add", - async fn(tx): Promise { - await tx.peerPullPaymentIncoming.iter().forEachAsync(async (pi) => { - if (pi.totalCostEstimated) { - return; - } - // Not really the cost, but a good substitute for older transactions - // that don't sture the effective cost of the transaction. - pi.totalCostEstimated = pi.contractTerms.amount; - await tx.peerPullPaymentIncoming.put(pi); - }); - }, - }, - { - name: "PeerPushPaymentIncomingRecord_totalCostEstimated_add", - async fn(tx): Promise { - await tx.peerPushPaymentIncoming.iter().forEachAsync(async (pi) => { - if (pi.estimatedAmountEffective) { - return; - } - const contractTerms = await tx.contractTerms.get(pi.contractTermsHash); - if (!contractTerms) { - // Not sure what we can do here! - } else { - // Not really the cost, but a good substitute for older transactions - // that don't sture the effective cost of the transaction. - pi.estimatedAmountEffective = contractTerms.contractTermsRaw.amount; - await tx.peerPushPaymentIncoming.put(pi); - } - }); - }, - }, - { - name: "PeerPullPaymentInitiationRecord_estimatedAmountEffective_add", - async fn(tx): Promise { - await tx.peerPullPaymentInitiations.iter().forEachAsync(async (pi) => { - if (pi.estimatedAmountEffective) { - return; - } - pi.estimatedAmountEffective = pi.amount; - await tx.peerPullPaymentInitiations.put(pi); - }); - }, - }, - { - name: "PeerPushPaymentInitiationRecord_ALL_removeLegacyTx", - async fn(tx): Promise { - await tx.peerPushPaymentInitiations.iter().forEachAsync(async (pi) => { - // Remove legacy transactions that don't have the totalCost field yet. - if (!pi.totalCost) { - await tx.peerPushPaymentInitiations.delete(pi.pursePub); - } - }); - }, - }, - { - name: "CoinAvailabilityRecord_visibleCoinCount_add", - async fn(tx): Promise { - await tx.coinAvailability.iter().forEachAsync(async (r) => { - if (r.visibleCoinCount == null) { - r.visibleCoinCount = r.freshCoinCount; - await tx.coinAvailability.put(r); - } - }); - }, - }, -]; +export const walletDbFixups: FixupDescription[] = []; const logger = new Logger("db.ts"); diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 9c08a57bf..287ac94fb 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -163,7 +163,7 @@ export async function getBalancesInsideTransaction( case WithdrawalGroupStatus.AbortedExchange: case WithdrawalGroupStatus.FailedAbortingBank: case WithdrawalGroupStatus.FailedBankAborted: - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: // Does not count as pendingIncoming return; case WithdrawalGroupStatus.PendingReady: diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index e96beb5b2..680874dfa 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -52,9 +52,9 @@ import { BackupProviderRecord, DepositGroupRecord, PeerPullPaymentIncomingRecord, - PeerPullPaymentInitiationRecord, + PeerPullCreditRecord, PeerPushPaymentIncomingRecord, - PeerPushPaymentInitiationRecord, + PeerPushDebitRecord, PurchaseRecord, RecoupGroupRecord, RefreshGroupRecord, @@ -271,7 +271,7 @@ function convertTaskToTransactionId( case PendingTaskType.PeerPullDebit: return constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId: parsedTaskId.peerPullPaymentIncomingId, + peerPullDebitId: parsedTaskId.peerPullDebitId, }); // FIXME: This doesn't distinguish internal-withdrawal. // Maybe we should have a different task type for that as well? @@ -284,7 +284,7 @@ function convertTaskToTransactionId( case PendingTaskType.PeerPushCredit: return constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: parsedTaskId.peerPushPaymentIncomingId, + peerPushCreditId: parsedTaskId.peerPushCreditId, }); case PendingTaskType.Deposit: return constructTransactionIdentifier({ @@ -836,9 +836,9 @@ export type ParsedTaskIdentifier = | { tag: PendingTaskType.Deposit; depositGroupId: string } | { tag: PendingTaskType.ExchangeCheckRefresh; exchangeBaseUrl: string } | { tag: PendingTaskType.ExchangeUpdate; exchangeBaseUrl: string } - | { tag: PendingTaskType.PeerPullDebit; peerPullPaymentIncomingId: string } + | { tag: PendingTaskType.PeerPullDebit; peerPullDebitId: string } | { tag: PendingTaskType.PeerPullCredit; pursePub: string } - | { tag: PendingTaskType.PeerPushCredit; peerPushPaymentIncomingId: string } + | { tag: PendingTaskType.PeerPushCredit; peerPushCreditId: string } | { tag: PendingTaskType.PeerPushDebit; pursePub: string } | { tag: PendingTaskType.Purchase; proposalId: string } | { tag: PendingTaskType.Recoup; recoupGroupId: string } @@ -865,9 +865,9 @@ export function parseTaskIdentifier(x: string): ParsedTaskIdentifier { case PendingTaskType.PeerPullCredit: return { tag: type, pursePub: rest[0] }; case PendingTaskType.PeerPullDebit: - return { tag: type, peerPullPaymentIncomingId: rest[0] }; + return { tag: type, peerPullDebitId: rest[0] }; case PendingTaskType.PeerPushCredit: - return { tag: type, peerPushPaymentIncomingId: rest[0] }; + return { tag: type, peerPushCreditId: rest[0] }; case PendingTaskType.PeerPushDebit: return { tag: type, pursePub: rest[0] }; case PendingTaskType.Purchase: @@ -896,9 +896,9 @@ export function constructTaskIdentifier(p: ParsedTaskIdentifier): TaskId { case PendingTaskType.ExchangeUpdate: return `${p.tag}:${p.exchangeBaseUrl}` as TaskId; case PendingTaskType.PeerPullDebit: - return `${p.tag}:${p.peerPullPaymentIncomingId}` as TaskId; + return `${p.tag}:${p.peerPullDebitId}` as TaskId; case PendingTaskType.PeerPushCredit: - return `${p.tag}:${p.peerPushPaymentIncomingId}` as TaskId; + return `${p.tag}:${p.peerPushCreditId}` as TaskId; case PendingTaskType.PeerPullCredit: return `${p.tag}:${p.pursePub}` as TaskId; case PendingTaskType.PeerPushDebit: @@ -950,23 +950,23 @@ export namespace TaskIdentifiers { return `${PendingTaskType.Backup}:${backupRecord.baseUrl}` as TaskId; } export function forPeerPushPaymentInitiation( - ppi: PeerPushPaymentInitiationRecord, + ppi: PeerPushDebitRecord, ): TaskId { return `${PendingTaskType.PeerPushDebit}:${ppi.pursePub}` as TaskId; } export function forPeerPullPaymentInitiation( - ppi: PeerPullPaymentInitiationRecord, + ppi: PeerPullCreditRecord, ): TaskId { return `${PendingTaskType.PeerPullCredit}:${ppi.pursePub}` as TaskId; } export function forPeerPullPaymentDebit( ppi: PeerPullPaymentIncomingRecord, ): TaskId { - return `${PendingTaskType.PeerPullDebit}:${ppi.peerPullPaymentIncomingId}` as TaskId; + return `${PendingTaskType.PeerPullDebit}:${ppi.peerPullDebitId}` as TaskId; } export function forPeerPushCredit( ppi: PeerPushPaymentIncomingRecord, ): TaskId { - return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushPaymentIncomingId}` as TaskId; + return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushCreditId}` as TaskId; } } diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 2580c97f5..1b3248f49 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -541,7 +541,7 @@ async function processDownloadProposal( // if original order is refunded. if (otherPurchase && otherPurchase.refundAmountAwaiting === undefined) { logger.warn("repurchase detected"); - p.purchaseStatus = PurchaseStatus.RepurchaseDetected; + p.purchaseStatus = PurchaseStatus.DoneRepurchaseDetected; p.repurchaseProposalId = otherPurchase.proposalId; await tx.purchases.put(p); } else { @@ -974,7 +974,7 @@ export async function checkPaymentByProposalId( if (!proposal) { throw Error(`could not get proposal ${proposalId}`); } - if (proposal.purchaseStatus === PurchaseStatus.RepurchaseDetected) { + if (proposal.purchaseStatus === PurchaseStatus.DoneRepurchaseDetected) { const existingProposalId = proposal.repurchaseProposalId; if (existingProposalId) { logger.trace("using existing purchase for same product"); @@ -1527,7 +1527,7 @@ export async function processPurchase( return processPurchaseDialogShared(ws, purchase); case PurchaseStatus.FailedClaim: case PurchaseStatus.Done: - case PurchaseStatus.RepurchaseDetected: + case PurchaseStatus.DoneRepurchaseDetected: case PurchaseStatus.DialogProposed: case PurchaseStatus.AbortedProposalRefused: case PurchaseStatus.AbortedIncompletePayment: @@ -2099,7 +2099,7 @@ export function computePayMerchantTransactionState( return { major: TransactionMajorState.Done, }; - case PurchaseStatus.RepurchaseDetected: + case PurchaseStatus.DoneRepurchaseDetected: return { major: TransactionMajorState.Failed, minor: TransactionMinorState.Repurchase, @@ -2176,7 +2176,7 @@ export function computePayMerchantTransactionActions( return [TransactionAction.Delete]; case PurchaseStatus.Done: return [TransactionAction.Delete]; - case PurchaseStatus.RepurchaseDetected: + case PurchaseStatus.DoneRepurchaseDetected: return [TransactionAction.Delete]; case PurchaseStatus.AbortedIncompletePayment: return [TransactionAction.Delete]; diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts index 29c0fff9e..edadad1fc 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts @@ -55,8 +55,8 @@ import { import { KycPendingInfo, KycUserType, - PeerPullPaymentInitiationRecord, - PeerPullPaymentInitiationStatus, + PeerPullCreditRecord, + PeerPullPaymentCreditStatus, WithdrawalGroupStatus, WithdrawalRecordType, updateExchangeFromUrl, @@ -90,7 +90,7 @@ const logger = new Logger("pay-peer-pull-credit.ts"); async function queryPurseForPeerPullCredit( ws: InternalWalletState, - pullIni: PeerPullPaymentInitiationRecord, + pullIni: PeerPullCreditRecord, cancellationToken: CancellationToken, ): Promise { const purseDepositUrl = new URL( @@ -159,18 +159,18 @@ async function queryPurseForPeerPullCredit( pursePub: pullIni.pursePub, }); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const finPi = await tx.peerPullPaymentInitiations.get(pullIni.pursePub); + const finPi = await tx.peerPullCredit.get(pullIni.pursePub); if (!finPi) { - logger.warn("peerPullPaymentInitiation not found anymore"); + logger.warn("peerPullCredit not found anymore"); return; } const oldTxState = computePeerPullCreditTransactionState(finPi); - if (finPi.status === PeerPullPaymentInitiationStatus.PendingReady) { - finPi.status = PeerPullPaymentInitiationStatus.PendingWithdrawing; + if (finPi.status === PeerPullPaymentCreditStatus.PendingReady) { + finPi.status = PeerPullPaymentCreditStatus.PendingWithdrawing; } - await tx.peerPullPaymentInitiations.put(finPi); + await tx.peerPullCredit.put(finPi); const newTxState = computePeerPullCreditTransactionState(finPi); return { oldTxState, newTxState }; }); @@ -214,22 +214,22 @@ async function longpollKycStatus( kycStatusRes.status === HttpStatusCode.NoContent ) { const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const peerIni = await tx.peerPullPaymentInitiations.get(pursePub); + const peerIni = await tx.peerPullCredit.get(pursePub); if (!peerIni) { return; } if ( peerIni.status !== - PeerPullPaymentInitiationStatus.PendingMergeKycRequired + PeerPullPaymentCreditStatus.PendingMergeKycRequired ) { return; } const oldTxState = computePeerPullCreditTransactionState(peerIni); - peerIni.status = PeerPullPaymentInitiationStatus.PendingCreatePurse; + peerIni.status = PeerPullPaymentCreditStatus.PendingCreatePurse; const newTxState = computePeerPullCreditTransactionState(peerIni); - await tx.peerPullPaymentInitiations.put(peerIni); + await tx.peerPullCredit.put(peerIni); return { oldTxState, newTxState }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -250,7 +250,7 @@ async function longpollKycStatus( async function processPeerPullCreditAbortingDeletePurse( ws: InternalWalletState, - peerPullIni: PeerPullPaymentInitiationRecord, + peerPullIni: PeerPullCreditRecord, ): Promise { const { pursePub, pursePriv } = peerPullIni; const transactionId = constructTransactionIdentifier({ @@ -272,24 +272,24 @@ async function processPeerPullCreditAbortingDeletePurse( const transitionInfo = await ws.db .mktx((x) => [ - x.peerPullPaymentInitiations, + x.peerPullCredit, x.refreshGroups, x.denominations, x.coinAvailability, x.coins, ]) .runReadWrite(async (tx) => { - const ppiRec = await tx.peerPullPaymentInitiations.get(pursePub); + const ppiRec = await tx.peerPullCredit.get(pursePub); if (!ppiRec) { return undefined; } if ( - ppiRec.status !== PeerPullPaymentInitiationStatus.AbortingDeletePurse + ppiRec.status !== PeerPullPaymentCreditStatus.AbortingDeletePurse ) { return undefined; } const oldTxState = computePeerPullCreditTransactionState(ppiRec); - ppiRec.status = PeerPullPaymentInitiationStatus.Aborted; + ppiRec.status = PeerPullPaymentCreditStatus.Aborted; const newTxState = computePeerPullCreditTransactionState(ppiRec); return { oldTxState, @@ -303,7 +303,7 @@ async function processPeerPullCreditAbortingDeletePurse( async function handlePeerPullCreditWithdrawing( ws: InternalWalletState, - pullIni: PeerPullPaymentInitiationRecord, + pullIni: PeerPullCreditRecord, ): Promise { if (!pullIni.withdrawalGroupId) { throw Error("invalid db state (withdrawing, but no withdrawal group ID"); @@ -315,14 +315,14 @@ async function handlePeerPullCreditWithdrawing( const wgId = pullIni.withdrawalGroupId; let finished: boolean = false; const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations, x.withdrawalGroups]) + .mktx((x) => [x.peerPullCredit, x.withdrawalGroups]) .runReadWrite(async (tx) => { - const ppi = await tx.peerPullPaymentInitiations.get(pullIni.pursePub); + const ppi = await tx.peerPullCredit.get(pullIni.pursePub); if (!ppi) { finished = true; return; } - if (ppi.status !== PeerPullPaymentInitiationStatus.PendingWithdrawing) { + if (ppi.status !== PeerPullPaymentCreditStatus.PendingWithdrawing) { finished = true; return; } @@ -333,13 +333,13 @@ async function handlePeerPullCreditWithdrawing( return undefined; } switch (wg.status) { - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: finished = true; - ppi.status = PeerPullPaymentInitiationStatus.Done; + ppi.status = PeerPullPaymentCreditStatus.Done; break; // FIXME: Also handle other final states! } - await tx.peerPullPaymentInitiations.put(ppi); + await tx.peerPullCredit.put(ppi); const newTxState = computePeerPullCreditTransactionState(ppi); return { oldTxState, @@ -357,7 +357,7 @@ async function handlePeerPullCreditWithdrawing( async function handlePeerPullCreditCreatePurse( ws: InternalWalletState, - pullIni: PeerPullPaymentInitiationRecord, + pullIni: PeerPullCreditRecord, ): Promise { const purseFee = Amounts.stringify(Amounts.zeroOfAmount(pullIni.amount)); const pursePub = pullIni.pursePub; @@ -444,15 +444,15 @@ async function handlePeerPullCreditCreatePurse( }); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const pi2 = await tx.peerPullPaymentInitiations.get(pursePub); + const pi2 = await tx.peerPullCredit.get(pursePub); if (!pi2) { return; } const oldTxState = computePeerPullCreditTransactionState(pi2); - pi2.status = PeerPullPaymentInitiationStatus.PendingReady; - await tx.peerPullPaymentInitiations.put(pi2); + pi2.status = PeerPullPaymentCreditStatus.PendingReady; + await tx.peerPullCredit.put(pi2); const newTxState = computePeerPullCreditTransactionState(pi2); return { oldTxState, newTxState }; }); @@ -466,9 +466,9 @@ export async function processPeerPullCredit( pursePub: string, ): Promise { const pullIni = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadOnly(async (tx) => { - return tx.peerPullPaymentInitiations.get(pursePub); + return tx.peerPullCredit.get(pursePub); }); if (!pullIni) { throw Error("peer pull payment initiation not found in database"); @@ -490,10 +490,10 @@ export async function processPeerPullCredit( logger.trace(`processing ${retryTag}, status=${pullIni.status}`); switch (pullIni.status) { - case PeerPullPaymentInitiationStatus.Done: { + case PeerPullPaymentCreditStatus.Done: { return TaskRunResult.finished(); } - case PeerPullPaymentInitiationStatus.PendingReady: + case PeerPullPaymentCreditStatus.PendingReady: runLongpollAsync(ws, retryTag, async (cancellationToken) => queryPurseForPeerPullCredit(ws, pullIni, cancellationToken), ); @@ -503,7 +503,7 @@ export async function processPeerPullCredit( return { type: TaskRunResultType.Longpoll, }; - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: { + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: { if (!pullIni.kycInfo) { throw Error("invalid state, kycInfo required"); } @@ -515,19 +515,19 @@ export async function processPeerPullCredit( "individual", ); } - case PeerPullPaymentInitiationStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingCreatePurse: return handlePeerPullCreditCreatePurse(ws, pullIni); - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: return await processPeerPullCreditAbortingDeletePurse(ws, pullIni); - case PeerPullPaymentInitiationStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingWithdrawing: return handlePeerPullCreditWithdrawing(ws, pullIni); - case PeerPullPaymentInitiationStatus.Aborted: - case PeerPullPaymentInitiationStatus.Failed: - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: - case PeerPullPaymentInitiationStatus.SuspendedReady: - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.Aborted: + case PeerPullPaymentCreditStatus.Failed: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: break; default: assertUnreachable(pullIni.status); @@ -538,7 +538,7 @@ export async function processPeerPullCredit( async function processPeerPullCreditKycRequired( ws: InternalWalletState, - peerIni: PeerPullPaymentInitiationRecord, + peerIni: PeerPullCreditRecord, kycPending: WalletKycUuid, ): Promise { const transactionId = constructTransactionIdentifier({ @@ -570,9 +570,9 @@ async function processPeerPullCreditKycRequired( const kycStatus = await kycStatusRes.json(); logger.info(`kyc status: ${j2s(kycStatus)}`); const { transitionInfo, result } = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPullPaymentInitiations.get(pursePub); + const peerInc = await tx.peerPullCredit.get(pursePub); if (!peerInc) { return { transitionInfo: undefined, @@ -586,9 +586,9 @@ async function processPeerPullCreditKycRequired( }; peerInc.kycUrl = kycStatus.kyc_url; peerInc.status = - PeerPullPaymentInitiationStatus.PendingMergeKycRequired; + PeerPullPaymentCreditStatus.PendingMergeKycRequired; const newTxState = computePeerPullCreditTransactionState(peerInc); - await tx.peerPullPaymentInitiations.put(peerInc); + await tx.peerPullCredit.put(peerInc); // We'll remove this eventually! New clients should rely on the // kycUrl field of the transaction, not the error code. const res: TaskRunResult = { @@ -758,9 +758,9 @@ export async function initiatePeerPullPayment( ); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations, x.contractTerms]) + .mktx((x) => [x.peerPullCredit, x.contractTerms]) .runReadWrite(async (tx) => { - const ppi: PeerPullPaymentInitiationRecord = { + const ppi: PeerPullCreditRecord = { amount: req.partialContractTerms.amount, contractTermsHash: hContractTerms, exchangeBaseUrl: exchangeBaseUrl, @@ -768,7 +768,7 @@ export async function initiatePeerPullPayment( pursePub: pursePair.pub, mergePriv: mergePair.priv, mergePub: mergePair.pub, - status: PeerPullPaymentInitiationStatus.PendingCreatePurse, + status: PeerPullPaymentCreditStatus.PendingCreatePurse, contractTerms: contractTerms, mergeTimestamp, contractEncNonce, @@ -778,7 +778,7 @@ export async function initiatePeerPullPayment( withdrawalGroupId, estimatedAmountEffective: wi.withdrawalAmountEffective, }; - await tx.peerPullPaymentInitiations.put(ppi); + await tx.peerPullCredit.put(ppi); const oldTxState: TransactionState = { major: TransactionMajorState.None, }; @@ -826,39 +826,39 @@ export async function suspendPeerPullCreditTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const pullCreditRec = await tx.peerPullPaymentInitiations.get(pursePub); + const pullCreditRec = await tx.peerPullCredit.get(pursePub); if (!pullCreditRec) { logger.warn(`peer pull credit ${pursePub} not found`); return; } - let newStatus: PeerPullPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPullPaymentCreditStatus | undefined = undefined; switch (pullCreditRec.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: - newStatus = PeerPullPaymentInitiationStatus.SuspendedCreatePurse; + case PeerPullPaymentCreditStatus.PendingCreatePurse: + newStatus = PeerPullPaymentCreditStatus.SuspendedCreatePurse; break; - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: - newStatus = PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired; + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: + newStatus = PeerPullPaymentCreditStatus.SuspendedMergeKycRequired; break; - case PeerPullPaymentInitiationStatus.PendingWithdrawing: - newStatus = PeerPullPaymentInitiationStatus.SuspendedWithdrawing; + case PeerPullPaymentCreditStatus.PendingWithdrawing: + newStatus = PeerPullPaymentCreditStatus.SuspendedWithdrawing; break; - case PeerPullPaymentInitiationStatus.PendingReady: - newStatus = PeerPullPaymentInitiationStatus.SuspendedReady; + case PeerPullPaymentCreditStatus.PendingReady: + newStatus = PeerPullPaymentCreditStatus.SuspendedReady; break; - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: newStatus = - PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse; + PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse; break; - case PeerPullPaymentInitiationStatus.Done: - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: - case PeerPullPaymentInitiationStatus.SuspendedReady: - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: - case PeerPullPaymentInitiationStatus.Aborted: - case PeerPullPaymentInitiationStatus.Failed: - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPullPaymentCreditStatus.Done: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.Aborted: + case PeerPullPaymentCreditStatus.Failed: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: break; default: assertUnreachable(pullCreditRec.status); @@ -867,7 +867,7 @@ export async function suspendPeerPullCreditTransaction( const oldTxState = computePeerPullCreditTransactionState(pullCreditRec); pullCreditRec.status = newStatus; const newTxState = computePeerPullCreditTransactionState(pullCreditRec); - await tx.peerPullPaymentInitiations.put(pullCreditRec); + await tx.peerPullCredit.put(pullCreditRec); return { oldTxState, newTxState, @@ -892,33 +892,33 @@ export async function abortPeerPullCreditTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const pullCreditRec = await tx.peerPullPaymentInitiations.get(pursePub); + const pullCreditRec = await tx.peerPullCredit.get(pursePub); if (!pullCreditRec) { logger.warn(`peer pull credit ${pursePub} not found`); return; } - let newStatus: PeerPullPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPullPaymentCreditStatus | undefined = undefined; switch (pullCreditRec.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: - newStatus = PeerPullPaymentInitiationStatus.AbortingDeletePurse; + case PeerPullPaymentCreditStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: + newStatus = PeerPullPaymentCreditStatus.AbortingDeletePurse; break; - case PeerPullPaymentInitiationStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingWithdrawing: throw Error("can't abort anymore"); - case PeerPullPaymentInitiationStatus.PendingReady: - newStatus = PeerPullPaymentInitiationStatus.AbortingDeletePurse; + case PeerPullPaymentCreditStatus.PendingReady: + newStatus = PeerPullPaymentCreditStatus.AbortingDeletePurse; break; - case PeerPullPaymentInitiationStatus.Done: - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: - case PeerPullPaymentInitiationStatus.SuspendedReady: - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: - case PeerPullPaymentInitiationStatus.Aborted: - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: - case PeerPullPaymentInitiationStatus.Failed: - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPullPaymentCreditStatus.Done: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.Aborted: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.Failed: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: break; default: assertUnreachable(pullCreditRec.status); @@ -927,7 +927,7 @@ export async function abortPeerPullCreditTransaction( const oldTxState = computePeerPullCreditTransactionState(pullCreditRec); pullCreditRec.status = newStatus; const newTxState = computePeerPullCreditTransactionState(pullCreditRec); - await tx.peerPullPaymentInitiations.put(pullCreditRec); + await tx.peerPullCredit.put(pullCreditRec); return { oldTxState, newTxState, @@ -952,30 +952,30 @@ export async function failPeerPullCreditTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const pullCreditRec = await tx.peerPullPaymentInitiations.get(pursePub); + const pullCreditRec = await tx.peerPullCredit.get(pursePub); if (!pullCreditRec) { logger.warn(`peer pull credit ${pursePub} not found`); return; } - let newStatus: PeerPullPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPullPaymentCreditStatus | undefined = undefined; switch (pullCreditRec.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: - case PeerPullPaymentInitiationStatus.PendingWithdrawing: - case PeerPullPaymentInitiationStatus.PendingReady: - case PeerPullPaymentInitiationStatus.Done: - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: - case PeerPullPaymentInitiationStatus.SuspendedReady: - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: - case PeerPullPaymentInitiationStatus.Aborted: - case PeerPullPaymentInitiationStatus.Failed: + case PeerPullPaymentCreditStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: + case PeerPullPaymentCreditStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingReady: + case PeerPullPaymentCreditStatus.Done: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.Aborted: + case PeerPullPaymentCreditStatus.Failed: break; - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: - newStatus = PeerPullPaymentInitiationStatus.Failed; + case PeerPullPaymentCreditStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: + newStatus = PeerPullPaymentCreditStatus.Failed; break; default: assertUnreachable(pullCreditRec.status); @@ -984,7 +984,7 @@ export async function failPeerPullCreditTransaction( const oldTxState = computePeerPullCreditTransactionState(pullCreditRec); pullCreditRec.status = newStatus; const newTxState = computePeerPullCreditTransactionState(pullCreditRec); - await tx.peerPullPaymentInitiations.put(pullCreditRec); + await tx.peerPullCredit.put(pullCreditRec); return { oldTxState, newTxState, @@ -1009,38 +1009,38 @@ export async function resumePeerPullCreditTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentInitiations]) + .mktx((x) => [x.peerPullCredit]) .runReadWrite(async (tx) => { - const pullCreditRec = await tx.peerPullPaymentInitiations.get(pursePub); + const pullCreditRec = await tx.peerPullCredit.get(pursePub); if (!pullCreditRec) { logger.warn(`peer pull credit ${pursePub} not found`); return; } - let newStatus: PeerPullPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPullPaymentCreditStatus | undefined = undefined; switch (pullCreditRec.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: - case PeerPullPaymentInitiationStatus.PendingWithdrawing: - case PeerPullPaymentInitiationStatus.PendingReady: - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: - case PeerPullPaymentInitiationStatus.Done: - case PeerPullPaymentInitiationStatus.Failed: - case PeerPullPaymentInitiationStatus.Aborted: + case PeerPullPaymentCreditStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: + case PeerPullPaymentCreditStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingReady: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.Done: + case PeerPullPaymentCreditStatus.Failed: + case PeerPullPaymentCreditStatus.Aborted: break; - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: - newStatus = PeerPullPaymentInitiationStatus.PendingCreatePurse; + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: + newStatus = PeerPullPaymentCreditStatus.PendingCreatePurse; break; - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: - newStatus = PeerPullPaymentInitiationStatus.PendingMergeKycRequired; + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: + newStatus = PeerPullPaymentCreditStatus.PendingMergeKycRequired; break; - case PeerPullPaymentInitiationStatus.SuspendedReady: - newStatus = PeerPullPaymentInitiationStatus.PendingReady; + case PeerPullPaymentCreditStatus.SuspendedReady: + newStatus = PeerPullPaymentCreditStatus.PendingReady; break; - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: - newStatus = PeerPullPaymentInitiationStatus.PendingWithdrawing; + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: + newStatus = PeerPullPaymentCreditStatus.PendingWithdrawing; break; - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: - newStatus = PeerPullPaymentInitiationStatus.AbortingDeletePurse; + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: + newStatus = PeerPullPaymentCreditStatus.AbortingDeletePurse; break; default: assertUnreachable(pullCreditRec.status); @@ -1049,7 +1049,7 @@ export async function resumePeerPullCreditTransaction( const oldTxState = computePeerPullCreditTransactionState(pullCreditRec); pullCreditRec.status = newStatus; const newTxState = computePeerPullCreditTransactionState(pullCreditRec); - await tx.peerPullPaymentInitiations.put(pullCreditRec); + await tx.peerPullCredit.put(pullCreditRec); return { oldTxState, newTxState, @@ -1062,67 +1062,67 @@ export async function resumePeerPullCreditTransaction( } export function computePeerPullCreditTransactionState( - pullCreditRecord: PeerPullPaymentInitiationRecord, + pullCreditRecord: PeerPullCreditRecord, ): TransactionState { switch (pullCreditRecord.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingCreatePurse: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.CreatePurse, }; - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.MergeKycRequired, }; - case PeerPullPaymentInitiationStatus.PendingReady: + case PeerPullPaymentCreditStatus.PendingReady: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Ready, }; - case PeerPullPaymentInitiationStatus.Done: + case PeerPullPaymentCreditStatus.Done: return { major: TransactionMajorState.Done, }; - case PeerPullPaymentInitiationStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingWithdrawing: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Withdraw, }; - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.CreatePurse, }; - case PeerPullPaymentInitiationStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedReady: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.Ready, }; - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Withdraw, }; - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.MergeKycRequired, }; - case PeerPullPaymentInitiationStatus.Aborted: + case PeerPullPaymentCreditStatus.Aborted: return { major: TransactionMajorState.Aborted, }; - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: return { major: TransactionMajorState.Aborting, minor: TransactionMinorState.DeletePurse, }; - case PeerPullPaymentInitiationStatus.Failed: + case PeerPullPaymentCreditStatus.Failed: return { major: TransactionMajorState.Failed, }; - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: return { major: TransactionMajorState.Aborting, minor: TransactionMinorState.DeletePurse, @@ -1131,34 +1131,34 @@ export function computePeerPullCreditTransactionState( } export function computePeerPullCreditTransactionActions( - pullCreditRecord: PeerPullPaymentInitiationRecord, + pullCreditRecord: PeerPullCreditRecord, ): TransactionAction[] { switch (pullCreditRecord.status) { - case PeerPullPaymentInitiationStatus.PendingCreatePurse: + case PeerPullPaymentCreditStatus.PendingCreatePurse: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: + case PeerPullPaymentCreditStatus.PendingMergeKycRequired: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPullPaymentInitiationStatus.PendingReady: + case PeerPullPaymentCreditStatus.PendingReady: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPullPaymentInitiationStatus.Done: + case PeerPullPaymentCreditStatus.Done: return [TransactionAction.Delete]; - case PeerPullPaymentInitiationStatus.PendingWithdrawing: + case PeerPullPaymentCreditStatus.PendingWithdrawing: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPullPaymentInitiationStatus.SuspendedCreatePurse: + case PeerPullPaymentCreditStatus.SuspendedCreatePurse: return [TransactionAction.Resume, TransactionAction.Abort]; - case PeerPullPaymentInitiationStatus.SuspendedReady: + case PeerPullPaymentCreditStatus.SuspendedReady: return [TransactionAction.Abort, TransactionAction.Resume]; - case PeerPullPaymentInitiationStatus.SuspendedWithdrawing: + case PeerPullPaymentCreditStatus.SuspendedWithdrawing: return [TransactionAction.Resume, TransactionAction.Fail]; - case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired: + case PeerPullPaymentCreditStatus.SuspendedMergeKycRequired: return [TransactionAction.Resume, TransactionAction.Fail]; - case PeerPullPaymentInitiationStatus.Aborted: + case PeerPullPaymentCreditStatus.Aborted: return [TransactionAction.Delete]; - case PeerPullPaymentInitiationStatus.AbortingDeletePurse: + case PeerPullPaymentCreditStatus.AbortingDeletePurse: return [TransactionAction.Suspend, TransactionAction.Fail]; - case PeerPullPaymentInitiationStatus.Failed: + case PeerPullPaymentCreditStatus.Failed: return [TransactionAction.Delete]; - case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse: return [TransactionAction.Resume, TransactionAction.Fail]; } } diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts index 0de91bf97..f357c41d5 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts @@ -140,10 +140,10 @@ async function handlePurseCreationConflict( ); await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const myPpi = await tx.peerPullPaymentIncoming.get( - peerPullInc.peerPullPaymentIncomingId, + const myPpi = await tx.peerPullDebit.get( + peerPullInc.peerPullDebitId, ); if (!myPpi) { return; @@ -162,7 +162,7 @@ async function handlePurseCreationConflict( default: return; } - await tx.peerPullPaymentIncoming.put(myPpi); + await tx.peerPullDebit.put(myPpi); }); return TaskRunResult.finished(); } @@ -171,7 +171,7 @@ async function processPeerPullDebitPendingDeposit( ws: InternalWalletState, peerPullInc: PeerPullPaymentIncomingRecord, ): Promise { - const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId; + const peerPullDebitId = peerPullInc.peerPullDebitId; const pursePub = peerPullInc.pursePub; const coinSel = peerPullInc.coinSel; @@ -202,7 +202,7 @@ async function processPeerPullDebitPendingDeposit( const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const httpResp = await ws.http.fetch(purseDepositUrl.href, { @@ -218,10 +218,10 @@ async function processPeerPullDebitPendingDeposit( logger.trace(`purse deposit response: ${j2s(resp)}`); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const pi = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pi = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pi) { throw Error("peer pull payment not found anymore"); @@ -230,9 +230,9 @@ async function processPeerPullDebitPendingDeposit( return; } const oldTxState = computePeerPullDebitTransactionState(pi); - pi.status = PeerPullDebitRecordStatus.DonePaid; + pi.status = PeerPullDebitRecordStatus.Done; const newTxState = computePeerPullDebitTransactionState(pi); - await tx.peerPullPaymentIncoming.put(pi); + await tx.peerPullDebit.put(pi); return { oldTxState, newTxState }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -241,15 +241,15 @@ async function processPeerPullDebitPendingDeposit( case HttpStatusCode.Gone: { const transitionInfo = await ws.db .mktx((x) => [ - x.peerPullPaymentIncoming, + x.peerPullDebit, x.refreshGroups, x.denominations, x.coinAvailability, x.coins, ]) .runReadWrite(async (tx) => { - const pi = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pi = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pi) { throw Error("peer pull payment not found anymore"); @@ -284,7 +284,7 @@ async function processPeerPullDebitPendingDeposit( pi.status = PeerPullDebitRecordStatus.AbortingRefresh; pi.abortRefreshGroupId = refresh.refreshGroupId; const newTxState = computePeerPullDebitTransactionState(pi); - await tx.peerPullPaymentIncoming.put(pi); + await tx.peerPullDebit.put(pi); return { oldTxState, newTxState }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -308,15 +308,15 @@ async function processPeerPullDebitAbortingRefresh( ws: InternalWalletState, peerPullInc: PeerPullPaymentIncomingRecord, ): Promise { - const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId; + const peerPullDebitId = peerPullInc.peerPullDebitId; const abortRefreshGroupId = peerPullInc.abortRefreshGroupId; checkLogicInvariant(!!abortRefreshGroupId); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const transitionInfo = await ws.db - .mktx((x) => [x.refreshGroups, x.peerPullPaymentIncoming]) + .mktx((x) => [x.refreshGroups, x.peerPullDebit]) .runReadWrite(async (tx) => { const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId); let newOpState: PeerPullDebitRecordStatus | undefined; @@ -335,8 +335,8 @@ async function processPeerPullDebitAbortingRefresh( } } if (newOpState) { - const newDg = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const newDg = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!newDg) { return; @@ -344,7 +344,7 @@ async function processPeerPullDebitAbortingRefresh( const oldTxState = computePeerPullDebitTransactionState(newDg); newDg.status = newOpState; const newTxState = computePeerPullDebitTransactionState(newDg); - await tx.peerPullPaymentIncoming.put(newDg); + await tx.peerPullDebit.put(newDg); return { oldTxState, newTxState }; } return undefined; @@ -356,12 +356,12 @@ async function processPeerPullDebitAbortingRefresh( export async function processPeerPullDebit( ws: InternalWalletState, - peerPullPaymentIncomingId: string, + peerPullDebitId: string, ): Promise { const peerPullInc = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadOnly(async (tx) => { - return tx.peerPullPaymentIncoming.get(peerPullPaymentIncomingId); + return tx.peerPullDebit.get(peerPullDebitId); }); if (!peerPullInc) { throw Error("peer pull debit not found"); @@ -380,31 +380,31 @@ export async function confirmPeerPullDebit( ws: InternalWalletState, req: ConfirmPeerPullDebitRequest, ): Promise { - let peerPullPaymentIncomingId: string; + let peerPullDebitId: string; if (req.transactionId) { const parsedTx = parseTransactionIdentifier(req.transactionId); if (!parsedTx || parsedTx.tag !== TransactionType.PeerPullDebit) { throw Error("invalid peer-pull-debit transaction identifier"); } - peerPullPaymentIncomingId = parsedTx.peerPullPaymentIncomingId; - } else if (req.peerPullPaymentIncomingId) { - peerPullPaymentIncomingId = req.peerPullPaymentIncomingId; + peerPullDebitId = parsedTx.peerPullDebitId; + } else if (req.peerPullDebitId) { + peerPullDebitId = req.peerPullDebitId; } else { throw Error( - "invalid request, transactionId or peerPullPaymentIncomingId required", + "invalid request, transactionId or peerPullDebitId required", ); } const peerPullInc = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadOnly(async (tx) => { - return tx.peerPullPaymentIncoming.get(peerPullPaymentIncomingId); + return tx.peerPullDebit.get(peerPullDebitId); }); if (!peerPullInc) { throw Error( - `can't accept unknown incoming p2p pull payment (${req.peerPullPaymentIncomingId})`, + `can't accept unknown incoming p2p pull payment (${req.peerPullDebitId})`, ); } @@ -437,15 +437,15 @@ export async function confirmPeerPullDebit( x.coins, x.denominations, x.refreshGroups, - x.peerPullPaymentIncoming, + x.peerPullDebit, x.coinAvailability, ]) .runReadWrite(async (tx) => { await spendCoins(ws, tx, { - // allocationId: `txn:peer-pull-debit:${req.peerPullPaymentIncomingId}`, + // allocationId: `txn:peer-pull-debit:${req.peerPullDebitId}`, allocationId: constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }), coinPubs: sel.coins.map((x) => x.coinPub), contributions: sel.coins.map((x) => @@ -454,8 +454,8 @@ export async function confirmPeerPullDebit( refreshReason: RefreshReason.PayPeerPull, }); - const pi = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pi = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pi) { throw Error(); @@ -468,7 +468,7 @@ export async function confirmPeerPullDebit( totalCost: Amounts.stringify(totalAmount), }; } - await tx.peerPullPaymentIncoming.put(pi); + await tx.peerPullDebit.put(pi); return pi; }); @@ -476,7 +476,7 @@ export async function confirmPeerPullDebit( const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); return { @@ -499,9 +499,9 @@ export async function preparePeerPullDebit( } const existingPullIncomingRecord = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadOnly(async (tx) => { - return tx.peerPullPaymentIncoming.indexes.byExchangeAndContractPriv.get([ + return tx.peerPullDebit.indexes.byExchangeAndContractPriv.get([ uri.exchangeBaseUrl, uri.contractPriv, ]); @@ -513,12 +513,12 @@ export async function preparePeerPullDebit( amountRaw: existingPullIncomingRecord.contractTerms.amount, amountEffective: existingPullIncomingRecord.totalCostEstimated, contractTerms: existingPullIncomingRecord.contractTerms, - peerPullPaymentIncomingId: - existingPullIncomingRecord.peerPullPaymentIncomingId, + peerPullDebitId: + existingPullIncomingRecord.peerPullDebitId, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId: - existingPullIncomingRecord.peerPullPaymentIncomingId, + peerPullDebitId: + existingPullIncomingRecord.peerPullDebitId, }), }; } @@ -553,7 +553,7 @@ export async function preparePeerPullDebit( codecForExchangePurseStatus(), ); - const peerPullPaymentIncomingId = encodeCrock(getRandomBytes(32)); + const peerPullDebitId = encodeCrock(getRandomBytes(32)); let contractTerms: PeerContractTerms; @@ -588,10 +588,10 @@ export async function preparePeerPullDebit( ); await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - await tx.peerPullPaymentIncoming.add({ - peerPullPaymentIncomingId, + await tx.peerPullDebit.add({ + peerPullDebitId, contractPriv: contractPriv, exchangeBaseUrl: exchangeBaseUrl, pursePub: pursePub, @@ -607,42 +607,42 @@ export async function preparePeerPullDebit( amountEffective: Amounts.stringify(totalAmount), amountRaw: contractTerms.amount, contractTerms: contractTerms, - peerPullPaymentIncomingId, + peerPullDebitId, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId: peerPullPaymentIncomingId, + peerPullDebitId: peerPullDebitId, }), }; } export async function suspendPeerPullDebitTransaction( ws: InternalWalletState, - peerPullPaymentIncomingId: string, + peerPullDebitId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const pullDebitRec = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pullDebitRec = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pullDebitRec) { - logger.warn(`peer pull debit ${peerPullPaymentIncomingId} not found`); + logger.warn(`peer pull debit ${peerPullDebitId} not found`); return; } let newStatus: PeerPullDebitRecordStatus | undefined = undefined; switch (pullDebitRec.status) { case PeerPullDebitRecordStatus.DialogProposed: break; - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: break; case PeerPullDebitRecordStatus.PendingDeposit: newStatus = PeerPullDebitRecordStatus.SuspendedDeposit; @@ -665,7 +665,7 @@ export async function suspendPeerPullDebitTransaction( const oldTxState = computePeerPullDebitTransactionState(pullDebitRec); pullDebitRec.status = newStatus; const newTxState = computePeerPullDebitTransactionState(pullDebitRec); - await tx.peerPullPaymentIncoming.put(pullDebitRec); + await tx.peerPullDebit.put(pullDebitRec); return { oldTxState, newTxState, @@ -678,25 +678,25 @@ export async function suspendPeerPullDebitTransaction( export async function abortPeerPullDebitTransaction( ws: InternalWalletState, - peerPullPaymentIncomingId: string, + peerPullDebitId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const pullDebitRec = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pullDebitRec = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pullDebitRec) { - logger.warn(`peer pull debit ${peerPullPaymentIncomingId} not found`); + logger.warn(`peer pull debit ${peerPullDebitId} not found`); return; } let newStatus: PeerPullDebitRecordStatus | undefined = undefined; @@ -704,7 +704,7 @@ export async function abortPeerPullDebitTransaction( case PeerPullDebitRecordStatus.DialogProposed: newStatus = PeerPullDebitRecordStatus.Aborted; break; - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: break; case PeerPullDebitRecordStatus.PendingDeposit: newStatus = PeerPullDebitRecordStatus.AbortingRefresh; @@ -726,7 +726,7 @@ export async function abortPeerPullDebitTransaction( const oldTxState = computePeerPullDebitTransactionState(pullDebitRec); pullDebitRec.status = newStatus; const newTxState = computePeerPullDebitTransactionState(pullDebitRec); - await tx.peerPullPaymentIncoming.put(pullDebitRec); + await tx.peerPullDebit.put(pullDebitRec); return { oldTxState, newTxState, @@ -739,25 +739,25 @@ export async function abortPeerPullDebitTransaction( export async function failPeerPullDebitTransaction( ws: InternalWalletState, - peerPullPaymentIncomingId: string, + peerPullDebitId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const pullDebitRec = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pullDebitRec = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pullDebitRec) { - logger.warn(`peer pull debit ${peerPullPaymentIncomingId} not found`); + logger.warn(`peer pull debit ${peerPullDebitId} not found`); return; } let newStatus: PeerPullDebitRecordStatus | undefined = undefined; @@ -765,7 +765,7 @@ export async function failPeerPullDebitTransaction( case PeerPullDebitRecordStatus.DialogProposed: newStatus = PeerPullDebitRecordStatus.Aborted; break; - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: break; case PeerPullDebitRecordStatus.PendingDeposit: break; @@ -787,7 +787,7 @@ export async function failPeerPullDebitTransaction( const oldTxState = computePeerPullDebitTransactionState(pullDebitRec); pullDebitRec.status = newStatus; const newTxState = computePeerPullDebitTransactionState(pullDebitRec); - await tx.peerPullPaymentIncoming.put(pullDebitRec); + await tx.peerPullDebit.put(pullDebitRec); return { oldTxState, newTxState, @@ -800,31 +800,31 @@ export async function failPeerPullDebitTransaction( export async function resumePeerPullDebitTransaction( ws: InternalWalletState, - peerPullPaymentIncomingId: string, + peerPullDebitId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId, + peerPullDebitId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const pullDebitRec = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const pullDebitRec = await tx.peerPullDebit.get( + peerPullDebitId, ); if (!pullDebitRec) { - logger.warn(`peer pull debit ${peerPullPaymentIncomingId} not found`); + logger.warn(`peer pull debit ${peerPullDebitId} not found`); return; } let newStatus: PeerPullDebitRecordStatus | undefined = undefined; switch (pullDebitRec.status) { case PeerPullDebitRecordStatus.DialogProposed: - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: case PeerPullDebitRecordStatus.PendingDeposit: break; case PeerPullDebitRecordStatus.SuspendedDeposit: @@ -846,7 +846,7 @@ export async function resumePeerPullDebitTransaction( const oldTxState = computePeerPullDebitTransactionState(pullDebitRec); pullDebitRec.status = newStatus; const newTxState = computePeerPullDebitTransactionState(pullDebitRec); - await tx.peerPullPaymentIncoming.put(pullDebitRec); + await tx.peerPullDebit.put(pullDebitRec); return { oldTxState, newTxState, @@ -872,7 +872,7 @@ export function computePeerPullDebitTransactionState( major: TransactionMajorState.Pending, minor: TransactionMinorState.Deposit, }; - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: return { major: TransactionMajorState.Done, }; @@ -910,7 +910,7 @@ export function computePeerPullDebitTransactionActions( return []; case PeerPullDebitRecordStatus.PendingDeposit: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPullDebitRecordStatus.DonePaid: + case PeerPullDebitRecordStatus.Done: return [TransactionAction.Delete]; case PeerPullDebitRecordStatus.SuspendedDeposit: return [TransactionAction.Resume, TransactionAction.Abort]; diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts index afeeb2c6b..f0f659aa3 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts @@ -55,7 +55,7 @@ import { KycPendingInfo, KycUserType, PeerPushPaymentIncomingRecord, - PeerPushPaymentIncomingStatus, + PeerPushCreditStatus, PendingTaskType, WithdrawalGroupStatus, WithdrawalRecordType, @@ -99,10 +99,10 @@ export async function preparePeerPushCredit( } const existing = await ws.db - .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) + .mktx((x) => [x.contractTerms, x.peerPushCredit]) .runReadOnly(async (tx) => { const existingPushInc = - await tx.peerPushPaymentIncoming.indexes.byExchangeAndContractPriv.get([ + await tx.peerPushCredit.indexes.byExchangeAndContractPriv.get([ uri.exchangeBaseUrl, uri.contractPriv, ]); @@ -129,12 +129,12 @@ export async function preparePeerPushCredit( amountEffective: existing.existingPushInc.estimatedAmountEffective, amountRaw: existing.existingContractTerms.amount, contractTerms: existing.existingContractTerms, - peerPushPaymentIncomingId: - existing.existingPushInc.peerPushPaymentIncomingId, + peerPushCreditId: + existing.existingPushInc.peerPushCreditId, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: - existing.existingPushInc.peerPushPaymentIncomingId, + peerPushCreditId: + existing.existingPushInc.peerPushCreditId, }), }; } @@ -172,7 +172,7 @@ export async function preparePeerPushCredit( codecForExchangePurseStatus(), ); - const peerPushPaymentIncomingId = encodeCrock(getRandomBytes(32)); + const peerPushCreditId = encodeCrock(getRandomBytes(32)); const contractTermsHash = ContractTermsUtil.hashContractTerms( dec.contractTerms, @@ -188,17 +188,17 @@ export async function preparePeerPushCredit( ); await ws.db - .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) + .mktx((x) => [x.contractTerms, x.peerPushCredit]) .runReadWrite(async (tx) => { - await tx.peerPushPaymentIncoming.add({ - peerPushPaymentIncomingId, + await tx.peerPushCredit.add({ + peerPushCreditId, contractPriv: contractPriv, exchangeBaseUrl: exchangeBaseUrl, mergePriv: dec.mergePriv, pursePub: pursePub, timestamp: TalerPreciseTimestamp.now(), contractTermsHash, - status: PeerPushPaymentIncomingStatus.DialogProposed, + status: PeerPushCreditStatus.DialogProposed, withdrawalGroupId, currency: Amounts.currencyOf(purseStatus.balance), estimatedAmountEffective: Amounts.stringify( @@ -219,28 +219,28 @@ export async function preparePeerPushCredit( amountEffective: wi.withdrawalAmountEffective, amountRaw: purseStatus.balance, contractTerms: dec.contractTerms, - peerPushPaymentIncomingId, + peerPushCreditId, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }), }; } async function longpollKycStatus( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, exchangeUrl: string, kycInfo: KycPendingInfo, userType: KycUserType, ): Promise { const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); const retryTag = constructTaskIdentifier({ tag: PendingTaskType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); runLongpollAsync(ws, retryTag, async (ct) => { @@ -261,24 +261,24 @@ async function longpollKycStatus( kycStatusRes.status === HttpStatusCode.NoContent ) { const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming]) + .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const peerInc = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!peerInc) { return; } if ( peerInc.status !== - PeerPushPaymentIncomingStatus.PendingMergeKycRequired + PeerPushCreditStatus.PendingMergeKycRequired ) { return; } const oldTxState = computePeerPushCreditTransactionState(peerInc); - peerInc.status = PeerPushPaymentIncomingStatus.PendingMerge; + peerInc.status = PeerPushCreditStatus.PendingMerge; const newTxState = computePeerPushCreditTransactionState(peerInc); - await tx.peerPushPaymentIncoming.put(peerInc); + await tx.peerPushCredit.put(peerInc); return { oldTxState, newTxState }; }); notifyTransition(ws, transactionId, transitionInfo); @@ -304,9 +304,9 @@ async function processPeerPushCreditKycRequired( ): Promise { const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId, + peerPushCreditId: peerInc.peerPushCreditId, }); - const { peerPushPaymentIncomingId } = peerInc; + const { peerPushCreditId } = peerInc; const userType = "individual"; const url = new URL( @@ -331,10 +331,10 @@ async function processPeerPushCreditKycRequired( const kycStatus = await kycStatusRes.json(); logger.info(`kyc status: ${j2s(kycStatus)}`); const { transitionInfo, result } = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming]) + .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const peerInc = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!peerInc) { return { @@ -348,9 +348,9 @@ async function processPeerPushCreditKycRequired( requirementRow: kycPending.requirement_row, }; peerInc.kycUrl = kycStatus.kyc_url; - peerInc.status = PeerPushPaymentIncomingStatus.PendingMergeKycRequired; + peerInc.status = PeerPushCreditStatus.PendingMergeKycRequired; const newTxState = computePeerPushCreditTransactionState(peerInc); - await tx.peerPushPaymentIncoming.put(peerInc); + await tx.peerPushCredit.put(peerInc); // We'll remove this eventually! New clients should rely on the // kycUrl field of the transaction, not the error code. const res: TaskRunResult = { @@ -379,10 +379,10 @@ async function handlePendingMerge( peerInc: PeerPushPaymentIncomingRecord, contractTerms: PeerContractTerms, ): Promise { - const { peerPushPaymentIncomingId } = peerInc; + const { peerPushCreditId } = peerInc; const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); const amount = Amounts.parseOrThrow(contractTerms.amount); @@ -460,15 +460,15 @@ async function handlePendingMerge( const txRes = await ws.db .mktx((x) => [ x.contractTerms, - x.peerPushPaymentIncoming, + x.peerPushCredit, x.withdrawalGroups, x.reserves, x.exchanges, x.exchangeDetails, ]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const peerInc = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!peerInc) { return undefined; @@ -476,9 +476,9 @@ async function handlePendingMerge( let withdrawalTransition: TransitionInfo | undefined; const oldTxState = computePeerPushCreditTransactionState(peerInc); switch (peerInc.status) { - case PeerPushPaymentIncomingStatus.PendingMerge: - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: { - peerInc.status = PeerPushPaymentIncomingStatus.PendingWithdrawing; + case PeerPushCreditStatus.PendingMerge: + case PeerPushCreditStatus.PendingMergeKycRequired: { + peerInc.status = PeerPushCreditStatus.PendingWithdrawing; const wgRes = await internalPerformCreateWithdrawalGroup( ws, tx, @@ -488,7 +488,7 @@ async function handlePendingMerge( break; } } - await tx.peerPushPaymentIncoming.put(peerInc); + await tx.peerPushCredit.put(peerInc); const newTxState = computePeerPushCreditTransactionState(peerInc); return { peerPushCreditTransition: { oldTxState, newTxState }, @@ -514,21 +514,21 @@ async function handlePendingWithdrawing( } const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId, + peerPushCreditId: peerInc.peerPushCreditId, }); const wgId = peerInc.withdrawalGroupId; let finished: boolean = false; const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming, x.withdrawalGroups]) + .mktx((x) => [x.peerPushCredit, x.withdrawalGroups]) .runReadWrite(async (tx) => { - const ppi = await tx.peerPushPaymentIncoming.get( - peerInc.peerPushPaymentIncomingId, + const ppi = await tx.peerPushCredit.get( + peerInc.peerPushCreditId, ); if (!ppi) { finished = true; return; } - if (ppi.status !== PeerPushPaymentIncomingStatus.PendingWithdrawing) { + if (ppi.status !== PeerPushCreditStatus.PendingWithdrawing) { finished = true; return; } @@ -539,13 +539,13 @@ async function handlePendingWithdrawing( return undefined; } switch (wg.status) { - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: finished = true; - ppi.status = PeerPushPaymentIncomingStatus.Done; + ppi.status = PeerPushCreditStatus.Done; break; // FIXME: Also handle other final states! } - await tx.peerPushPaymentIncoming.put(ppi); + await tx.peerPushCredit.put(ppi); const newTxState = computePeerPushCreditTransactionState(ppi); return { oldTxState, @@ -563,14 +563,14 @@ async function handlePendingWithdrawing( export async function processPeerPushCredit( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, ): Promise { let peerInc: PeerPushPaymentIncomingRecord | undefined; let contractTerms: PeerContractTerms | undefined; await ws.db - .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) + .mktx((x) => [x.contractTerms, x.peerPushCredit]) .runReadWrite(async (tx) => { - peerInc = await tx.peerPushPaymentIncoming.get(peerPushPaymentIncomingId); + peerInc = await tx.peerPushCredit.get(peerPushCreditId); if (!peerInc) { return; } @@ -578,35 +578,35 @@ export async function processPeerPushCredit( if (ctRec) { contractTerms = ctRec.contractTermsRaw; } - await tx.peerPushPaymentIncoming.put(peerInc); + await tx.peerPushCredit.put(peerInc); }); checkDbInvariant(!!contractTerms); if (!peerInc) { throw Error( - `can't accept unknown incoming p2p push payment (${peerPushPaymentIncomingId})`, + `can't accept unknown incoming p2p push payment (${peerPushCreditId})`, ); } switch (peerInc.status) { - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: { + case PeerPushCreditStatus.PendingMergeKycRequired: { if (!peerInc.kycInfo) { throw Error("invalid state, kycInfo required"); } return await longpollKycStatus( ws, - peerPushPaymentIncomingId, + peerPushCreditId, peerInc.exchangeBaseUrl, peerInc.kycInfo, "individual", ); } - case PeerPushPaymentIncomingStatus.PendingMerge: + case PeerPushCreditStatus.PendingMerge: return handlePendingMerge(ws, peerInc, contractTerms); - case PeerPushPaymentIncomingStatus.PendingWithdrawing: + case PeerPushCreditStatus.PendingWithdrawing: return handlePendingWithdrawing(ws, peerInc); default: @@ -619,9 +619,9 @@ export async function confirmPeerPushCredit( req: ConfirmPeerPushCreditRequest, ): Promise { let peerInc: PeerPushPaymentIncomingRecord | undefined; - let peerPushPaymentIncomingId: string; - if (req.peerPushPaymentIncomingId) { - peerPushPaymentIncomingId = req.peerPushPaymentIncomingId; + let peerPushCreditId: string; + if (req.peerPushCreditId) { + peerPushCreditId = req.peerPushCreditId; } else if (req.transactionId) { const parsedTx = parseTransactionIdentifier(req.transactionId); if (!parsedTx) { @@ -630,29 +630,29 @@ export async function confirmPeerPushCredit( if (parsedTx.tag !== TransactionType.PeerPushCredit) { throw Error("invalid transaction ID type"); } - peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId; + peerPushCreditId = parsedTx.peerPushCreditId; } else { throw Error( - "no transaction ID (or deprecated peerPushPaymentIncomingId) provided", + "no transaction ID (or deprecated peerPushCreditId) provided", ); } await ws.db - .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) + .mktx((x) => [x.contractTerms, x.peerPushCredit]) .runReadWrite(async (tx) => { - peerInc = await tx.peerPushPaymentIncoming.get(peerPushPaymentIncomingId); + peerInc = await tx.peerPushCredit.get(peerPushCreditId); if (!peerInc) { return; } - if (peerInc.status === PeerPushPaymentIncomingStatus.DialogProposed) { - peerInc.status = PeerPushPaymentIncomingStatus.PendingMerge; + if (peerInc.status === PeerPushCreditStatus.DialogProposed) { + peerInc.status = PeerPushCreditStatus.PendingMerge; } - await tx.peerPushPaymentIncoming.put(peerInc); + await tx.peerPushCredit.put(peerInc); }); if (!peerInc) { throw Error( - `can't accept unknown incoming p2p push payment (${req.peerPushPaymentIncomingId})`, + `can't accept unknown incoming p2p push payment (${req.peerPushCreditId})`, ); } @@ -660,7 +660,7 @@ export async function confirmPeerPushCredit( const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); return { @@ -670,48 +670,48 @@ export async function confirmPeerPushCredit( export async function suspendPeerPushCreditTransaction( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming]) + .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const pushCreditRec = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!pushCreditRec) { - logger.warn(`peer push credit ${peerPushPaymentIncomingId} not found`); + logger.warn(`peer push credit ${peerPushCreditId} not found`); return; } - let newStatus: PeerPushPaymentIncomingStatus | undefined = undefined; + let newStatus: PeerPushCreditStatus | undefined = undefined; switch (pushCreditRec.status) { - case PeerPushPaymentIncomingStatus.DialogProposed: - case PeerPushPaymentIncomingStatus.Done: - case PeerPushPaymentIncomingStatus.SuspendedMerge: - case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired: - case PeerPushPaymentIncomingStatus.SuspendedWithdrawing: + case PeerPushCreditStatus.DialogProposed: + case PeerPushCreditStatus.Done: + case PeerPushCreditStatus.SuspendedMerge: + case PeerPushCreditStatus.SuspendedMergeKycRequired: + case PeerPushCreditStatus.SuspendedWithdrawing: break; - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: - newStatus = PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired; + case PeerPushCreditStatus.PendingMergeKycRequired: + newStatus = PeerPushCreditStatus.SuspendedMergeKycRequired; break; - case PeerPushPaymentIncomingStatus.PendingMerge: - newStatus = PeerPushPaymentIncomingStatus.SuspendedMerge; + case PeerPushCreditStatus.PendingMerge: + newStatus = PeerPushCreditStatus.SuspendedMerge; break; - case PeerPushPaymentIncomingStatus.PendingWithdrawing: + case PeerPushCreditStatus.PendingWithdrawing: // FIXME: Suspend internal withdrawal transaction! - newStatus = PeerPushPaymentIncomingStatus.SuspendedWithdrawing; + newStatus = PeerPushCreditStatus.SuspendedWithdrawing; break; - case PeerPushPaymentIncomingStatus.Aborted: + case PeerPushCreditStatus.Aborted: break; - case PeerPushPaymentIncomingStatus.Failed: + case PeerPushCreditStatus.Failed: break; default: assertUnreachable(pushCreditRec.status); @@ -720,7 +720,7 @@ export async function suspendPeerPushCreditTransaction( const oldTxState = computePeerPushCreditTransactionState(pushCreditRec); pushCreditRec.status = newStatus; const newTxState = computePeerPushCreditTransactionState(pushCreditRec); - await tx.peerPushPaymentIncoming.put(pushCreditRec); + await tx.peerPushCredit.put(pushCreditRec); return { oldTxState, newTxState, @@ -733,51 +733,51 @@ export async function suspendPeerPushCreditTransaction( export async function abortPeerPushCreditTransaction( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming]) + .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const pushCreditRec = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!pushCreditRec) { - logger.warn(`peer push credit ${peerPushPaymentIncomingId} not found`); + logger.warn(`peer push credit ${peerPushCreditId} not found`); return; } - let newStatus: PeerPushPaymentIncomingStatus | undefined = undefined; + let newStatus: PeerPushCreditStatus | undefined = undefined; switch (pushCreditRec.status) { - case PeerPushPaymentIncomingStatus.DialogProposed: - newStatus = PeerPushPaymentIncomingStatus.Aborted; + case PeerPushCreditStatus.DialogProposed: + newStatus = PeerPushCreditStatus.Aborted; break; - case PeerPushPaymentIncomingStatus.Done: + case PeerPushCreditStatus.Done: break; - case PeerPushPaymentIncomingStatus.SuspendedMerge: - case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired: - case PeerPushPaymentIncomingStatus.SuspendedWithdrawing: - newStatus = PeerPushPaymentIncomingStatus.Aborted; + case PeerPushCreditStatus.SuspendedMerge: + case PeerPushCreditStatus.SuspendedMergeKycRequired: + case PeerPushCreditStatus.SuspendedWithdrawing: + newStatus = PeerPushCreditStatus.Aborted; break; - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: - newStatus = PeerPushPaymentIncomingStatus.Aborted; + case PeerPushCreditStatus.PendingMergeKycRequired: + newStatus = PeerPushCreditStatus.Aborted; break; - case PeerPushPaymentIncomingStatus.PendingMerge: - newStatus = PeerPushPaymentIncomingStatus.Aborted; + case PeerPushCreditStatus.PendingMerge: + newStatus = PeerPushCreditStatus.Aborted; break; - case PeerPushPaymentIncomingStatus.PendingWithdrawing: - newStatus = PeerPushPaymentIncomingStatus.Aborted; + case PeerPushCreditStatus.PendingWithdrawing: + newStatus = PeerPushCreditStatus.Aborted; break; - case PeerPushPaymentIncomingStatus.Aborted: + case PeerPushCreditStatus.Aborted: break; - case PeerPushPaymentIncomingStatus.Failed: + case PeerPushCreditStatus.Failed: break; default: assertUnreachable(pushCreditRec.status); @@ -786,7 +786,7 @@ export async function abortPeerPushCreditTransaction( const oldTxState = computePeerPushCreditTransactionState(pushCreditRec); pushCreditRec.status = newStatus; const newTxState = computePeerPushCreditTransactionState(pushCreditRec); - await tx.peerPushPaymentIncoming.put(pushCreditRec); + await tx.peerPushCredit.put(pushCreditRec); return { oldTxState, newTxState, @@ -799,7 +799,7 @@ export async function abortPeerPushCreditTransaction( export async function failPeerPushCreditTransaction( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, ) { // We don't have any "aborting" states! throw Error("can't run cancel-aborting on peer-push-credit transaction"); @@ -807,47 +807,47 @@ export async function failPeerPushCreditTransaction( export async function resumePeerPushCreditTransaction( ws: InternalWalletState, - peerPushPaymentIncomingId: string, + peerPushCreditId: string, ) { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId, + peerPushCreditId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentIncoming]) + .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const pushCreditRec = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!pushCreditRec) { - logger.warn(`peer push credit ${peerPushPaymentIncomingId} not found`); + logger.warn(`peer push credit ${peerPushCreditId} not found`); return; } - let newStatus: PeerPushPaymentIncomingStatus | undefined = undefined; + let newStatus: PeerPushCreditStatus | undefined = undefined; switch (pushCreditRec.status) { - case PeerPushPaymentIncomingStatus.DialogProposed: - case PeerPushPaymentIncomingStatus.Done: - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: - case PeerPushPaymentIncomingStatus.PendingMerge: - case PeerPushPaymentIncomingStatus.PendingWithdrawing: - case PeerPushPaymentIncomingStatus.SuspendedMerge: - newStatus = PeerPushPaymentIncomingStatus.PendingMerge; + case PeerPushCreditStatus.DialogProposed: + case PeerPushCreditStatus.Done: + case PeerPushCreditStatus.PendingMergeKycRequired: + case PeerPushCreditStatus.PendingMerge: + case PeerPushCreditStatus.PendingWithdrawing: + case PeerPushCreditStatus.SuspendedMerge: + newStatus = PeerPushCreditStatus.PendingMerge; break; - case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired: - newStatus = PeerPushPaymentIncomingStatus.PendingMergeKycRequired; + case PeerPushCreditStatus.SuspendedMergeKycRequired: + newStatus = PeerPushCreditStatus.PendingMergeKycRequired; break; - case PeerPushPaymentIncomingStatus.SuspendedWithdrawing: + case PeerPushCreditStatus.SuspendedWithdrawing: // FIXME: resume underlying "internal-withdrawal" transaction. - newStatus = PeerPushPaymentIncomingStatus.PendingWithdrawing; + newStatus = PeerPushCreditStatus.PendingWithdrawing; break; - case PeerPushPaymentIncomingStatus.Aborted: + case PeerPushCreditStatus.Aborted: break; - case PeerPushPaymentIncomingStatus.Failed: + case PeerPushCreditStatus.Failed: break; default: assertUnreachable(pushCreditRec.status); @@ -856,7 +856,7 @@ export async function resumePeerPushCreditTransaction( const oldTxState = computePeerPushCreditTransactionState(pushCreditRec); pushCreditRec.status = newStatus; const newTxState = computePeerPushCreditTransactionState(pushCreditRec); - await tx.peerPushPaymentIncoming.put(pushCreditRec); + await tx.peerPushCredit.put(pushCreditRec); return { oldTxState, newTxState, @@ -872,50 +872,50 @@ export function computePeerPushCreditTransactionState( pushCreditRecord: PeerPushPaymentIncomingRecord, ): TransactionState { switch (pushCreditRecord.status) { - case PeerPushPaymentIncomingStatus.DialogProposed: + case PeerPushCreditStatus.DialogProposed: return { major: TransactionMajorState.Dialog, minor: TransactionMinorState.Proposed, }; - case PeerPushPaymentIncomingStatus.PendingMerge: + case PeerPushCreditStatus.PendingMerge: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Merge, }; - case PeerPushPaymentIncomingStatus.Done: + case PeerPushCreditStatus.Done: return { major: TransactionMajorState.Done, }; - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: + case PeerPushCreditStatus.PendingMergeKycRequired: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.KycRequired, }; - case PeerPushPaymentIncomingStatus.PendingWithdrawing: + case PeerPushCreditStatus.PendingWithdrawing: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Withdraw, }; - case PeerPushPaymentIncomingStatus.SuspendedMerge: + case PeerPushCreditStatus.SuspendedMerge: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.Merge, }; - case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired: + case PeerPushCreditStatus.SuspendedMergeKycRequired: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.MergeKycRequired, }; - case PeerPushPaymentIncomingStatus.SuspendedWithdrawing: + case PeerPushCreditStatus.SuspendedWithdrawing: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.Withdraw, }; - case PeerPushPaymentIncomingStatus.Aborted: + case PeerPushCreditStatus.Aborted: return { major: TransactionMajorState.Aborted, }; - case PeerPushPaymentIncomingStatus.Failed: + case PeerPushCreditStatus.Failed: return { major: TransactionMajorState.Failed, }; @@ -928,25 +928,25 @@ export function computePeerPushCreditTransactionActions( pushCreditRecord: PeerPushPaymentIncomingRecord, ): TransactionAction[] { switch (pushCreditRecord.status) { - case PeerPushPaymentIncomingStatus.DialogProposed: + case PeerPushCreditStatus.DialogProposed: return [TransactionAction.Delete]; - case PeerPushPaymentIncomingStatus.PendingMerge: + case PeerPushCreditStatus.PendingMerge: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPushPaymentIncomingStatus.Done: + case PeerPushCreditStatus.Done: return [TransactionAction.Delete]; - case PeerPushPaymentIncomingStatus.PendingMergeKycRequired: + case PeerPushCreditStatus.PendingMergeKycRequired: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPushPaymentIncomingStatus.PendingWithdrawing: + case PeerPushCreditStatus.PendingWithdrawing: return [TransactionAction.Suspend, TransactionAction.Fail]; - case PeerPushPaymentIncomingStatus.SuspendedMerge: + case PeerPushCreditStatus.SuspendedMerge: return [TransactionAction.Resume, TransactionAction.Abort]; - case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired: + case PeerPushCreditStatus.SuspendedMergeKycRequired: return [TransactionAction.Resume, TransactionAction.Abort]; - case PeerPushPaymentIncomingStatus.SuspendedWithdrawing: + case PeerPushCreditStatus.SuspendedWithdrawing: return [TransactionAction.Resume, TransactionAction.Fail]; - case PeerPushPaymentIncomingStatus.Aborted: + case PeerPushCreditStatus.Aborted: return [TransactionAction.Delete]; - case PeerPushPaymentIncomingStatus.Failed: + case PeerPushCreditStatus.Failed: return [TransactionAction.Delete]; default: assertUnreachable(pushCreditRecord.status); diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts index 2349e5c4a..a2e7a6891 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts @@ -51,8 +51,8 @@ import { } from "@gnu-taler/taler-util/http"; import { EncryptContractRequest } from "../crypto/cryptoTypes.js"; import { - PeerPushPaymentInitiationRecord, - PeerPushPaymentInitiationStatus, + PeerPushDebitRecord, + PeerPushDebitStatus, RefreshOperationStatus, createRefreshGroup, } from "../index.js"; @@ -107,7 +107,7 @@ export async function checkPeerPushDebit( async function handlePurseCreationConflict( ws: InternalWalletState, - peerPushInitiation: PeerPushPaymentInitiationRecord, + peerPushInitiation: PeerPushDebitRecord, resp: HttpResponse, ): Promise { const pursePub = peerPushInitiation.pursePub; @@ -152,17 +152,17 @@ async function handlePurseCreationConflict( } await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const myPpi = await tx.peerPushPaymentInitiations.get( + const myPpi = await tx.peerPushDebit.get( peerPushInitiation.pursePub, ); if (!myPpi) { return; } switch (myPpi.status) { - case PeerPushPaymentInitiationStatus.PendingCreatePurse: - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: { + case PeerPushDebitStatus.PendingCreatePurse: + case PeerPushDebitStatus.SuspendedCreatePurse: { const sel = coinSelRes.result; myPpi.coinSel = { coinPubs: sel.coins.map((x) => x.coinPub), @@ -173,14 +173,14 @@ async function handlePurseCreationConflict( default: return; } - await tx.peerPushPaymentInitiations.put(myPpi); + await tx.peerPushDebit.put(myPpi); }); return TaskRunResult.finished(); } async function processPeerPushDebitCreateReserve( ws: InternalWalletState, - peerPushInitiation: PeerPushPaymentInitiationRecord, + peerPushInitiation: PeerPushDebitRecord, ): Promise { logger.info("processing peer-push-debit pending(create-reserve)"); const pursePub = peerPushInitiation.pursePub; @@ -284,8 +284,8 @@ async function processPeerPushDebitCreateReserve( } await transitionPeerPushDebitTransaction(ws, pursePub, { - stFrom: PeerPushPaymentInitiationStatus.PendingCreatePurse, - stTo: PeerPushPaymentInitiationStatus.PendingReady, + stFrom: PeerPushDebitStatus.PendingCreatePurse, + stTo: PeerPushDebitStatus.PendingReady, }); return TaskRunResult.finished(); @@ -293,7 +293,7 @@ async function processPeerPushDebitCreateReserve( async function processPeerPushDebitAbortingDeletePurse( ws: InternalWalletState, - peerPushInitiation: PeerPushPaymentInitiationRecord, + peerPushInitiation: PeerPushDebitRecord, ): Promise { const { pursePub, pursePriv } = peerPushInitiation; const transactionId = constructTransactionIdentifier({ @@ -318,19 +318,19 @@ async function processPeerPushDebitAbortingDeletePurse( const transitionInfo = await ws.db .mktx((x) => [ - x.peerPushPaymentInitiations, + x.peerPushDebit, x.refreshGroups, x.denominations, x.coinAvailability, x.coins, ]) .runReadWrite(async (tx) => { - const ppiRec = await tx.peerPushPaymentInitiations.get(pursePub); + const ppiRec = await tx.peerPushDebit.get(pursePub); if (!ppiRec) { return undefined; } if ( - ppiRec.status !== PeerPushPaymentInitiationStatus.AbortingDeletePurse + ppiRec.status !== PeerPushDebitStatus.AbortingDeletePurse ) { return undefined; } @@ -352,9 +352,9 @@ async function processPeerPushDebitAbortingDeletePurse( coinPubs, RefreshReason.AbortPeerPushDebit, ); - ppiRec.status = PeerPushPaymentInitiationStatus.AbortingRefresh; + ppiRec.status = PeerPushDebitStatus.AbortingRefresh; ppiRec.abortRefreshGroupId = refresh.refreshGroupId; - await tx.peerPushPaymentInitiations.put(ppiRec); + await tx.peerPushDebit.put(ppiRec); const newTxState = computePeerPushDebitTransactionState(ppiRec); return { oldTxState, @@ -367,8 +367,8 @@ async function processPeerPushDebitAbortingDeletePurse( } interface SimpleTransition { - stFrom: PeerPushPaymentInitiationStatus; - stTo: PeerPushPaymentInitiationStatus; + stFrom: PeerPushDebitStatus; + stTo: PeerPushDebitStatus; } async function transitionPeerPushDebitTransaction( @@ -381,9 +381,9 @@ async function transitionPeerPushDebitTransaction( pursePub, }); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const ppiRec = await tx.peerPushPaymentInitiations.get(pursePub); + const ppiRec = await tx.peerPushDebit.get(pursePub); if (!ppiRec) { return undefined; } @@ -392,7 +392,7 @@ async function transitionPeerPushDebitTransaction( } const oldTxState = computePeerPushDebitTransactionState(ppiRec); ppiRec.status = transitionSpec.stTo; - await tx.peerPushPaymentInitiations.put(ppiRec); + await tx.peerPushDebit.put(ppiRec); const newTxState = computePeerPushDebitTransactionState(ppiRec); return { oldTxState, @@ -404,7 +404,7 @@ async function transitionPeerPushDebitTransaction( async function processPeerPushDebitAbortingRefresh( ws: InternalWalletState, - peerPushInitiation: PeerPushPaymentInitiationRecord, + peerPushInitiation: PeerPushDebitRecord, ): Promise { const pursePub = peerPushInitiation.pursePub; const abortRefreshGroupId = peerPushInitiation.abortRefreshGroupId; @@ -414,33 +414,33 @@ async function processPeerPushDebitAbortingRefresh( pursePub: peerPushInitiation.pursePub, }); const transitionInfo = await ws.db - .mktx((x) => [x.refreshGroups, x.peerPushPaymentInitiations]) + .mktx((x) => [x.refreshGroups, x.peerPushDebit]) .runReadWrite(async (tx) => { const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId); - let newOpState: PeerPushPaymentInitiationStatus | undefined; + let newOpState: PeerPushDebitStatus | undefined; if (!refreshGroup) { // Maybe it got manually deleted? Means that we should // just go into failed. logger.warn("no aborting refresh group found for deposit group"); - newOpState = PeerPushPaymentInitiationStatus.Failed; + newOpState = PeerPushDebitStatus.Failed; } else { if (refreshGroup.operationStatus === RefreshOperationStatus.Finished) { - newOpState = PeerPushPaymentInitiationStatus.Aborted; + newOpState = PeerPushDebitStatus.Aborted; } else if ( refreshGroup.operationStatus === RefreshOperationStatus.Failed ) { - newOpState = PeerPushPaymentInitiationStatus.Failed; + newOpState = PeerPushDebitStatus.Failed; } } if (newOpState) { - const newDg = await tx.peerPushPaymentInitiations.get(pursePub); + const newDg = await tx.peerPushDebit.get(pursePub); if (!newDg) { return; } const oldTxState = computePeerPushDebitTransactionState(newDg); newDg.status = newOpState; const newTxState = computePeerPushDebitTransactionState(newDg); - await tx.peerPushPaymentInitiations.put(newDg); + await tx.peerPushDebit.put(newDg); return { oldTxState, newTxState }; } return undefined; @@ -455,7 +455,7 @@ async function processPeerPushDebitAbortingRefresh( */ async function processPeerPushDebitReady( ws: InternalWalletState, - peerPushInitiation: PeerPushPaymentInitiationRecord, + peerPushInitiation: PeerPushDebitRecord, ): Promise { logger.info("processing peer-push-debit pending(ready)"); const pursePub = peerPushInitiation.pursePub; @@ -488,8 +488,8 @@ async function processPeerPushDebitReady( ws, peerPushInitiation.pursePub, { - stFrom: PeerPushPaymentInitiationStatus.PendingReady, - stTo: PeerPushPaymentInitiationStatus.Done, + stFrom: PeerPushDebitStatus.PendingReady, + stTo: PeerPushDebitStatus.Done, }, ); return { @@ -501,8 +501,8 @@ async function processPeerPushDebitReady( ws, peerPushInitiation.pursePub, { - stFrom: PeerPushPaymentInitiationStatus.PendingReady, - stTo: PeerPushPaymentInitiationStatus.Expired, + stFrom: PeerPushDebitStatus.PendingReady, + stTo: PeerPushDebitStatus.Expired, }, ); return { @@ -528,9 +528,9 @@ export async function processPeerPushDebit( pursePub: string, ): Promise { const peerPushInitiation = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadOnly(async (tx) => { - return tx.peerPushPaymentInitiations.get(pursePub); + return tx.peerPushDebit.get(pursePub); }); if (!peerPushInitiation) { throw Error("peer push payment not found"); @@ -550,13 +550,13 @@ export async function processPeerPushDebit( } switch (peerPushInitiation.status) { - case PeerPushPaymentInitiationStatus.PendingCreatePurse: + case PeerPushDebitStatus.PendingCreatePurse: return processPeerPushDebitCreateReserve(ws, peerPushInitiation); - case PeerPushPaymentInitiationStatus.PendingReady: + case PeerPushDebitStatus.PendingReady: return processPeerPushDebitReady(ws, peerPushInitiation); - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: + case PeerPushDebitStatus.AbortingDeletePurse: return processPeerPushDebitAbortingDeletePurse(ws, peerPushInitiation); - case PeerPushPaymentInitiationStatus.AbortingRefresh: + case PeerPushDebitStatus.AbortingRefresh: return processPeerPushDebitAbortingRefresh(ws, peerPushInitiation); default: { const txState = computePeerPushDebitTransactionState(peerPushInitiation); @@ -626,7 +626,7 @@ export async function initiatePeerPushDebit( x.coinAvailability, x.denominations, x.refreshGroups, - x.peerPushPaymentInitiations, + x.peerPushDebit, ]) .runReadWrite(async (tx) => { // FIXME: Instead of directly doing a spendCoin here, @@ -645,7 +645,7 @@ export async function initiatePeerPushDebit( refreshReason: RefreshReason.PayPeerPush, }); - const ppi: PeerPushPaymentInitiationRecord = { + const ppi: PeerPushDebitRecord = { amount: Amounts.stringify(instructedAmount), contractPriv: contractKeyPair.priv, contractPub: contractKeyPair.pub, @@ -657,7 +657,7 @@ export async function initiatePeerPushDebit( pursePriv: pursePair.priv, pursePub: pursePair.pub, timestampCreated: TalerPreciseTimestamp.now(), - status: PeerPushPaymentInitiationStatus.PendingCreatePurse, + status: PeerPushDebitStatus.PendingCreatePurse, contractTerms: contractTerms, contractEncNonce, coinSel: { @@ -667,7 +667,7 @@ export async function initiatePeerPushDebit( totalCost: Amounts.stringify(totalAmount), }; - await tx.peerPushPaymentInitiations.add(ppi); + await tx.peerPushDebit.add(ppi); await tx.contractTerms.put({ h: hContractTerms, @@ -701,32 +701,32 @@ export async function initiatePeerPushDebit( } export function computePeerPushDebitTransactionActions( - ppiRecord: PeerPushPaymentInitiationRecord, + ppiRecord: PeerPushDebitRecord, ): TransactionAction[] { switch (ppiRecord.status) { - case PeerPushPaymentInitiationStatus.PendingCreatePurse: + case PeerPushDebitStatus.PendingCreatePurse: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPushPaymentInitiationStatus.PendingReady: + case PeerPushDebitStatus.PendingReady: return [TransactionAction.Abort, TransactionAction.Suspend]; - case PeerPushPaymentInitiationStatus.Aborted: + case PeerPushDebitStatus.Aborted: return [TransactionAction.Delete]; - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: + case PeerPushDebitStatus.AbortingDeletePurse: return [TransactionAction.Suspend, TransactionAction.Fail]; - case PeerPushPaymentInitiationStatus.AbortingRefresh: + case PeerPushDebitStatus.AbortingRefresh: return [TransactionAction.Suspend, TransactionAction.Fail]; - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: return [TransactionAction.Resume, TransactionAction.Fail]; - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: + case PeerPushDebitStatus.SuspendedAbortingRefresh: return [TransactionAction.Resume, TransactionAction.Fail]; - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: + case PeerPushDebitStatus.SuspendedCreatePurse: return [TransactionAction.Resume, TransactionAction.Abort]; - case PeerPushPaymentInitiationStatus.SuspendedReady: + case PeerPushDebitStatus.SuspendedReady: return [TransactionAction.Suspend, TransactionAction.Abort]; - case PeerPushPaymentInitiationStatus.Done: + case PeerPushDebitStatus.Done: return [TransactionAction.Delete]; - case PeerPushPaymentInitiationStatus.Expired: + case PeerPushDebitStatus.Expired: return [TransactionAction.Delete]; - case PeerPushPaymentInitiationStatus.Failed: + case PeerPushDebitStatus.Failed: return [TransactionAction.Delete]; } } @@ -745,32 +745,32 @@ export async function abortPeerPushDebitTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub); + const pushDebitRec = await tx.peerPushDebit.get(pursePub); if (!pushDebitRec) { logger.warn(`peer push debit ${pursePub} not found`); return; } - let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPushDebitStatus | undefined = undefined; switch (pushDebitRec.status) { - case PeerPushPaymentInitiationStatus.PendingReady: - case PeerPushPaymentInitiationStatus.SuspendedReady: - newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse; + case PeerPushDebitStatus.PendingReady: + case PeerPushDebitStatus.SuspendedReady: + newStatus = PeerPushDebitStatus.AbortingDeletePurse; break; - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPushPaymentInitiationStatus.PendingCreatePurse: + case PeerPushDebitStatus.SuspendedCreatePurse: + case PeerPushDebitStatus.PendingCreatePurse: // Network request might already be in-flight! - newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse; + newStatus = PeerPushDebitStatus.AbortingDeletePurse; break; - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: - case PeerPushPaymentInitiationStatus.AbortingRefresh: - case PeerPushPaymentInitiationStatus.Done: - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: - case PeerPushPaymentInitiationStatus.Aborted: - case PeerPushPaymentInitiationStatus.Expired: - case PeerPushPaymentInitiationStatus.Failed: + case PeerPushDebitStatus.SuspendedAbortingRefresh: + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: + case PeerPushDebitStatus.AbortingRefresh: + case PeerPushDebitStatus.Done: + case PeerPushDebitStatus.AbortingDeletePurse: + case PeerPushDebitStatus.Aborted: + case PeerPushDebitStatus.Expired: + case PeerPushDebitStatus.Failed: // Do nothing break; default: @@ -780,7 +780,7 @@ export async function abortPeerPushDebitTransaction( const oldTxState = computePeerPushDebitTransactionState(pushDebitRec); pushDebitRec.status = newStatus; const newTxState = computePeerPushDebitTransactionState(pushDebitRec); - await tx.peerPushPaymentInitiations.put(pushDebitRec); + await tx.peerPushDebit.put(pushDebitRec); return { oldTxState, newTxState, @@ -805,32 +805,32 @@ export async function failPeerPushDebitTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub); + const pushDebitRec = await tx.peerPushDebit.get(pursePub); if (!pushDebitRec) { logger.warn(`peer push debit ${pursePub} not found`); return; } - let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPushDebitStatus | undefined = undefined; switch (pushDebitRec.status) { - case PeerPushPaymentInitiationStatus.AbortingRefresh: - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: + case PeerPushDebitStatus.AbortingRefresh: + case PeerPushDebitStatus.SuspendedAbortingRefresh: // FIXME: What to do about the refresh group? - newStatus = PeerPushPaymentInitiationStatus.Failed; + newStatus = PeerPushDebitStatus.Failed; break; - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: - case PeerPushPaymentInitiationStatus.PendingReady: - case PeerPushPaymentInitiationStatus.SuspendedReady: - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPushPaymentInitiationStatus.PendingCreatePurse: - newStatus = PeerPushPaymentInitiationStatus.Failed; + case PeerPushDebitStatus.AbortingDeletePurse: + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: + case PeerPushDebitStatus.PendingReady: + case PeerPushDebitStatus.SuspendedReady: + case PeerPushDebitStatus.SuspendedCreatePurse: + case PeerPushDebitStatus.PendingCreatePurse: + newStatus = PeerPushDebitStatus.Failed; break; - case PeerPushPaymentInitiationStatus.Done: - case PeerPushPaymentInitiationStatus.Aborted: - case PeerPushPaymentInitiationStatus.Failed: - case PeerPushPaymentInitiationStatus.Expired: + case PeerPushDebitStatus.Done: + case PeerPushDebitStatus.Aborted: + case PeerPushDebitStatus.Failed: + case PeerPushDebitStatus.Expired: // Do nothing break; default: @@ -840,7 +840,7 @@ export async function failPeerPushDebitTransaction( const oldTxState = computePeerPushDebitTransactionState(pushDebitRec); pushDebitRec.status = newStatus; const newTxState = computePeerPushDebitTransactionState(pushDebitRec); - await tx.peerPushPaymentInitiations.put(pushDebitRec); + await tx.peerPushDebit.put(pushDebitRec); return { oldTxState, newTxState, @@ -865,36 +865,36 @@ export async function suspendPeerPushDebitTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub); + const pushDebitRec = await tx.peerPushDebit.get(pursePub); if (!pushDebitRec) { logger.warn(`peer push debit ${pursePub} not found`); return; } - let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPushDebitStatus | undefined = undefined; switch (pushDebitRec.status) { - case PeerPushPaymentInitiationStatus.PendingCreatePurse: - newStatus = PeerPushPaymentInitiationStatus.SuspendedCreatePurse; + case PeerPushDebitStatus.PendingCreatePurse: + newStatus = PeerPushDebitStatus.SuspendedCreatePurse; break; - case PeerPushPaymentInitiationStatus.AbortingRefresh: - newStatus = PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh; + case PeerPushDebitStatus.AbortingRefresh: + newStatus = PeerPushDebitStatus.SuspendedAbortingRefresh; break; - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: + case PeerPushDebitStatus.AbortingDeletePurse: newStatus = - PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse; + PeerPushDebitStatus.SuspendedAbortingDeletePurse; break; - case PeerPushPaymentInitiationStatus.PendingReady: - newStatus = PeerPushPaymentInitiationStatus.SuspendedReady; + case PeerPushDebitStatus.PendingReady: + newStatus = PeerPushDebitStatus.SuspendedReady; break; - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: - case PeerPushPaymentInitiationStatus.SuspendedReady: - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: - case PeerPushPaymentInitiationStatus.Done: - case PeerPushPaymentInitiationStatus.Aborted: - case PeerPushPaymentInitiationStatus.Failed: - case PeerPushPaymentInitiationStatus.Expired: + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: + case PeerPushDebitStatus.SuspendedAbortingRefresh: + case PeerPushDebitStatus.SuspendedReady: + case PeerPushDebitStatus.SuspendedCreatePurse: + case PeerPushDebitStatus.Done: + case PeerPushDebitStatus.Aborted: + case PeerPushDebitStatus.Failed: + case PeerPushDebitStatus.Expired: // Do nothing break; default: @@ -904,7 +904,7 @@ export async function suspendPeerPushDebitTransaction( const oldTxState = computePeerPushDebitTransactionState(pushDebitRec); pushDebitRec.status = newStatus; const newTxState = computePeerPushDebitTransactionState(pushDebitRec); - await tx.peerPushPaymentInitiations.put(pushDebitRec); + await tx.peerPushDebit.put(pushDebitRec); return { oldTxState, newTxState, @@ -929,35 +929,35 @@ export async function resumePeerPushDebitTransaction( }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.peerPushPaymentInitiations]) + .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub); + const pushDebitRec = await tx.peerPushDebit.get(pursePub); if (!pushDebitRec) { logger.warn(`peer push debit ${pursePub} not found`); return; } - let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined; + let newStatus: PeerPushDebitStatus | undefined = undefined; switch (pushDebitRec.status) { - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: - newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse; + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: + newStatus = PeerPushDebitStatus.AbortingDeletePurse; break; - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: - newStatus = PeerPushPaymentInitiationStatus.AbortingRefresh; + case PeerPushDebitStatus.SuspendedAbortingRefresh: + newStatus = PeerPushDebitStatus.AbortingRefresh; break; - case PeerPushPaymentInitiationStatus.SuspendedReady: - newStatus = PeerPushPaymentInitiationStatus.PendingReady; + case PeerPushDebitStatus.SuspendedReady: + newStatus = PeerPushDebitStatus.PendingReady; break; - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: - newStatus = PeerPushPaymentInitiationStatus.PendingCreatePurse; + case PeerPushDebitStatus.SuspendedCreatePurse: + newStatus = PeerPushDebitStatus.PendingCreatePurse; break; - case PeerPushPaymentInitiationStatus.PendingCreatePurse: - case PeerPushPaymentInitiationStatus.AbortingRefresh: - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: - case PeerPushPaymentInitiationStatus.PendingReady: - case PeerPushPaymentInitiationStatus.Done: - case PeerPushPaymentInitiationStatus.Aborted: - case PeerPushPaymentInitiationStatus.Failed: - case PeerPushPaymentInitiationStatus.Expired: + case PeerPushDebitStatus.PendingCreatePurse: + case PeerPushDebitStatus.AbortingRefresh: + case PeerPushDebitStatus.AbortingDeletePurse: + case PeerPushDebitStatus.PendingReady: + case PeerPushDebitStatus.Done: + case PeerPushDebitStatus.Aborted: + case PeerPushDebitStatus.Failed: + case PeerPushDebitStatus.Expired: // Do nothing break; default: @@ -967,7 +967,7 @@ export async function resumePeerPushDebitTransaction( const oldTxState = computePeerPushDebitTransactionState(pushDebitRec); pushDebitRec.status = newStatus; const newTxState = computePeerPushDebitTransactionState(pushDebitRec); - await tx.peerPushPaymentInitiations.put(pushDebitRec); + await tx.peerPushDebit.put(pushDebitRec); return { oldTxState, newTxState, @@ -980,62 +980,62 @@ export async function resumePeerPushDebitTransaction( } export function computePeerPushDebitTransactionState( - ppiRecord: PeerPushPaymentInitiationRecord, + ppiRecord: PeerPushDebitRecord, ): TransactionState { switch (ppiRecord.status) { - case PeerPushPaymentInitiationStatus.PendingCreatePurse: + case PeerPushDebitStatus.PendingCreatePurse: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.CreatePurse, }; - case PeerPushPaymentInitiationStatus.PendingReady: + case PeerPushDebitStatus.PendingReady: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Ready, }; - case PeerPushPaymentInitiationStatus.Aborted: + case PeerPushDebitStatus.Aborted: return { major: TransactionMajorState.Aborted, }; - case PeerPushPaymentInitiationStatus.AbortingDeletePurse: + case PeerPushDebitStatus.AbortingDeletePurse: return { major: TransactionMajorState.Aborting, minor: TransactionMinorState.DeletePurse, }; - case PeerPushPaymentInitiationStatus.AbortingRefresh: + case PeerPushDebitStatus.AbortingRefresh: return { major: TransactionMajorState.Aborting, minor: TransactionMinorState.Refresh, }; - case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse: + case PeerPushDebitStatus.SuspendedAbortingDeletePurse: return { major: TransactionMajorState.SuspendedAborting, minor: TransactionMinorState.DeletePurse, }; - case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh: + case PeerPushDebitStatus.SuspendedAbortingRefresh: return { major: TransactionMajorState.SuspendedAborting, minor: TransactionMinorState.Refresh, }; - case PeerPushPaymentInitiationStatus.SuspendedCreatePurse: + case PeerPushDebitStatus.SuspendedCreatePurse: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.CreatePurse, }; - case PeerPushPaymentInitiationStatus.SuspendedReady: + case PeerPushDebitStatus.SuspendedReady: return { major: TransactionMajorState.Suspended, minor: TransactionMinorState.Ready, }; - case PeerPushPaymentInitiationStatus.Done: + case PeerPushDebitStatus.Done: return { major: TransactionMajorState.Done, }; - case PeerPushPaymentInitiationStatus.Failed: + case PeerPushDebitStatus.Failed: return { major: TransactionMajorState.Failed, }; - case PeerPushPaymentInitiationStatus.Expired: + case PeerPushDebitStatus.Expired: return { major: TransactionMajorState.Expired, }; diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index e37e45c16..207e6ffda 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -26,11 +26,10 @@ import { WalletStoresV1, BackupProviderStateTag, RefreshCoinStatus, - OperationStatusRange, - PeerPushPaymentInitiationStatus, + PeerPushDebitStatus, PeerPullDebitRecordStatus, - PeerPushPaymentIncomingStatus, - PeerPullPaymentInitiationStatus, + PeerPushCreditStatus, + PeerPullPaymentCreditStatus, WithdrawalGroupStatus, RewardRecordStatus, DepositOperationStatus, @@ -39,13 +38,14 @@ import { DepositGroupRecord, RewardRecord, PurchaseRecord, - PeerPullPaymentInitiationRecord, + PeerPullCreditRecord, PeerPullPaymentIncomingRecord, - PeerPushPaymentInitiationRecord, + PeerPushDebitRecord, PeerPushPaymentIncomingRecord, RefundGroupRecord, RefundGroupStatus, ExchangeEntryDbUpdateStatus, + RefreshOperationStatus, } from "../db.js"; import { PendingOperationsResponse, @@ -136,8 +136,8 @@ export async function iterRecordsForRefresh( let refreshGroups: RefreshGroupRecord[]; if (filter.onlyState === "nonfinal") { const keyRange = GlobalIDB.KeyRange.bound( - OperationStatusRange.ACTIVE_START, - OperationStatusRange.ACTIVE_END, + RefreshOperationStatus.Pending, + RefreshOperationStatus.Suspended, ); refreshGroups = await tx.refreshGroups.indexes.byStatus.getAll(keyRange); } else { @@ -470,28 +470,28 @@ async function gatherBackupPending( export async function iterRecordsForPeerPullInitiation( tx: GetReadOnlyAccess<{ - peerPullPaymentInitiations: typeof WalletStoresV1.peerPullPaymentInitiations; + peerPullCredit: typeof WalletStoresV1.peerPullCredit; }>, filter: TransactionRecordFilter, - f: (r: PeerPullPaymentInitiationRecord) => Promise, + f: (r: PeerPullCreditRecord) => Promise, ): Promise { if (filter.onlyState === "nonfinal") { const keyRange = GlobalIDB.KeyRange.bound( - PeerPullPaymentInitiationStatus.PendingCreatePurse, - PeerPullPaymentInitiationStatus.AbortingDeletePurse, + PeerPullPaymentCreditStatus.PendingCreatePurse, + PeerPullPaymentCreditStatus.AbortingDeletePurse, ); - await tx.peerPullPaymentInitiations.indexes.byStatus + await tx.peerPullCredit.indexes.byStatus .iter(keyRange) .forEachAsync(f); } else { - await tx.peerPullPaymentInitiations.indexes.byStatus.iter().forEachAsync(f); + await tx.peerPullCredit.indexes.byStatus.iter().forEachAsync(f); } } async function gatherPeerPullInitiationPending( ws: InternalWalletState, tx: GetReadOnlyAccess<{ - peerPullPaymentInitiations: typeof WalletStoresV1.peerPullPaymentInitiations; + peerPullCredit: typeof WalletStoresV1.peerPullCredit; operationRetries: typeof WalletStoresV1.operationRetries; }>, now: AbsoluteTime, @@ -518,7 +518,7 @@ async function gatherPeerPullInitiationPending( export async function iterRecordsForPeerPullDebit( tx: GetReadOnlyAccess<{ - peerPullPaymentIncoming: typeof WalletStoresV1.peerPullPaymentIncoming; + peerPullDebit: typeof WalletStoresV1.peerPullDebit; }>, filter: TransactionRecordFilter, f: (r: PeerPullPaymentIncomingRecord) => Promise, @@ -528,18 +528,18 @@ export async function iterRecordsForPeerPullDebit( PeerPullDebitRecordStatus.PendingDeposit, PeerPullDebitRecordStatus.AbortingRefresh, ); - await tx.peerPullPaymentIncoming.indexes.byStatus + await tx.peerPullDebit.indexes.byStatus .iter(keyRange) .forEachAsync(f); } else { - await tx.peerPullPaymentIncoming.indexes.byStatus.iter().forEachAsync(f); + await tx.peerPullDebit.indexes.byStatus.iter().forEachAsync(f); } } async function gatherPeerPullDebitPending( ws: InternalWalletState, tx: GetReadOnlyAccess<{ - peerPullPaymentIncoming: typeof WalletStoresV1.peerPullPaymentIncoming; + peerPullDebit: typeof WalletStoresV1.peerPullDebit; operationRetries: typeof WalletStoresV1.operationRetries; }>, now: AbsoluteTime, @@ -558,7 +558,7 @@ async function gatherPeerPullDebitPending( ...getPendingCommon(ws, opId, timestampDue), givesLifeness: true, retryInfo: retryRecord?.retryInfo, - peerPullPaymentIncomingId: pi.peerPullPaymentIncomingId, + peerPullDebitId: pi.peerPullDebitId, }); }, ); @@ -566,28 +566,28 @@ async function gatherPeerPullDebitPending( export async function iterRecordsForPeerPushInitiation( tx: GetReadOnlyAccess<{ - peerPushPaymentInitiations: typeof WalletStoresV1.peerPushPaymentInitiations; + peerPushDebit: typeof WalletStoresV1.peerPushDebit; }>, filter: TransactionRecordFilter, - f: (r: PeerPushPaymentInitiationRecord) => Promise, + f: (r: PeerPushDebitRecord) => Promise, ): Promise { if (filter.onlyState === "nonfinal") { const keyRange = GlobalIDB.KeyRange.bound( - PeerPushPaymentInitiationStatus.PendingCreatePurse, - PeerPushPaymentInitiationStatus.AbortingRefresh, + PeerPushDebitStatus.PendingCreatePurse, + PeerPushDebitStatus.AbortingRefresh, ); - await tx.peerPushPaymentInitiations.indexes.byStatus + await tx.peerPushDebit.indexes.byStatus .iter(keyRange) .forEachAsync(f); } else { - await tx.peerPushPaymentInitiations.indexes.byStatus.iter().forEachAsync(f); + await tx.peerPushDebit.indexes.byStatus.iter().forEachAsync(f); } } async function gatherPeerPushInitiationPending( ws: InternalWalletState, tx: GetReadOnlyAccess<{ - peerPushPaymentInitiations: typeof WalletStoresV1.peerPushPaymentInitiations; + peerPushDebit: typeof WalletStoresV1.peerPushDebit; operationRetries: typeof WalletStoresV1.operationRetries; }>, now: AbsoluteTime, @@ -614,36 +614,36 @@ async function gatherPeerPushInitiationPending( export async function iterRecordsForPeerPushCredit( tx: GetReadOnlyAccess<{ - peerPushPaymentIncoming: typeof WalletStoresV1.peerPushPaymentIncoming; + peerPushCredit: typeof WalletStoresV1.peerPushCredit; }>, filter: TransactionRecordFilter, f: (r: PeerPushPaymentIncomingRecord) => Promise, ): Promise { if (filter.onlyState === "nonfinal") { const keyRange = GlobalIDB.KeyRange.bound( - PeerPushPaymentIncomingStatus.PendingMerge, - PeerPushPaymentIncomingStatus.PendingWithdrawing, + PeerPushCreditStatus.PendingMerge, + PeerPushCreditStatus.PendingWithdrawing, ); - await tx.peerPushPaymentIncoming.indexes.byStatus + await tx.peerPushCredit.indexes.byStatus .iter(keyRange) .forEachAsync(f); } else { - await tx.peerPushPaymentIncoming.indexes.byStatus.iter().forEachAsync(f); + await tx.peerPushCredit.indexes.byStatus.iter().forEachAsync(f); } } async function gatherPeerPushCreditPending( ws: InternalWalletState, tx: GetReadOnlyAccess<{ - peerPushPaymentIncoming: typeof WalletStoresV1.peerPushPaymentIncoming; + peerPushCredit: typeof WalletStoresV1.peerPushCredit; operationRetries: typeof WalletStoresV1.operationRetries; }>, now: AbsoluteTime, resp: PendingOperationsResponse, ): Promise { const keyRange = GlobalIDB.KeyRange.bound( - PeerPushPaymentIncomingStatus.PendingMerge, - PeerPushPaymentIncomingStatus.PendingWithdrawing, + PeerPushCreditStatus.PendingMerge, + PeerPushCreditStatus.PendingWithdrawing, ); await iterRecordsForPeerPushCredit( tx, @@ -658,7 +658,7 @@ async function gatherPeerPushCreditPending( ...getPendingCommon(ws, opId, timestampDue), givesLifeness: true, retryInfo: retryRecord?.retryInfo, - peerPushPaymentIncomingId: pi.peerPushPaymentIncomingId, + peerPushCreditId: pi.peerPushCreditId, }); }, ); @@ -682,10 +682,10 @@ export async function getPendingOperations( x.depositGroups, x.recoupGroups, x.operationRetries, - x.peerPullPaymentInitiations, - x.peerPushPaymentInitiations, - x.peerPullPaymentIncoming, - x.peerPushPaymentIncoming, + x.peerPullCredit, + x.peerPushDebit, + x.peerPullDebit, + x.peerPushCredit, ]) .runReadWrite(async (tx) => { const resp: PendingOperationsResponse = { diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts index 6f9d3ce85..6ae021174 100644 --- a/packages/taler-wallet-core/src/operations/reward.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -108,7 +108,7 @@ export function computeRewardTransactionStatus( major: TransactionMajorState.Dialog, minor: TransactionMinorState.Proposed, }; - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Pickup, @@ -128,7 +128,7 @@ export function computeTipTransactionActions( return [TransactionAction.Delete]; case RewardRecordStatus.PendingPickup: return [TransactionAction.Suspend, TransactionAction.Fail]; - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: return [TransactionAction.Resume, TransactionAction.Fail]; case RewardRecordStatus.DialogAccept: return [TransactionAction.Abort]; @@ -255,7 +255,7 @@ export async function processTip( case RewardRecordStatus.Aborted: case RewardRecordStatus.DialogAccept: case RewardRecordStatus.Done: - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: return TaskRunResult.finished(); } @@ -496,12 +496,12 @@ export async function suspendRewardTransaction( let newStatus: RewardRecordStatus | undefined = undefined; switch (tipRec.status) { case RewardRecordStatus.Done: - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: case RewardRecordStatus.Aborted: case RewardRecordStatus.DialogAccept: break; case RewardRecordStatus.PendingPickup: - newStatus = RewardRecordStatus.SuspendidPickup; + newStatus = RewardRecordStatus.SuspendedPickup; break; default: @@ -551,7 +551,7 @@ export async function resumeTipTransaction( case RewardRecordStatus.Aborted: case RewardRecordStatus.DialogAccept: break; - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: newStatus = RewardRecordStatus.PendingPickup; break; default: @@ -608,7 +608,7 @@ export async function abortTipTransaction( case RewardRecordStatus.PendingPickup: case RewardRecordStatus.DialogAccept: break; - case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendedPickup: newStatus = RewardRecordStatus.Aborted; break; default: diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index 1962c965c..f71d842c7 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -700,7 +700,7 @@ export async function runIntegrationTest2( }); await confirmPeerPushCredit(ws, { - peerPushPaymentIncomingId: peerPushCredit.peerPushPaymentIncomingId, + peerPushCreditId: peerPushCredit.peerPushCreditId, }); const peerPullInit = await initiatePeerPullPayment(ws, { @@ -723,7 +723,7 @@ export async function runIntegrationTest2( }); await confirmPeerPullDebit(ws, { - peerPullPaymentIncomingId: peerPullInc.peerPullPaymentIncomingId, + peerPullDebitId: peerPullInc.peerPullDebitId, }); await waitUntilDone(ws); diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 7f5302b25..5c57195c1 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -50,10 +50,10 @@ import { OperationRetryRecord, PeerPullPaymentIncomingRecord, PeerPullDebitRecordStatus, - PeerPullPaymentInitiationRecord, + PeerPullCreditRecord, PeerPushPaymentIncomingRecord, - PeerPushPaymentIncomingStatus, - PeerPushPaymentInitiationRecord, + PeerPushCreditStatus, + PeerPushDebitRecord, PurchaseRecord, PurchaseStatus, RefreshGroupRecord, @@ -335,10 +335,10 @@ export async function getTransactionById( } case TransactionType.PeerPullDebit: { return await ws.db - .mktx((x) => [x.peerPullPaymentIncoming]) + .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const debit = await tx.peerPullPaymentIncoming.get( - parsedTx.peerPullPaymentIncomingId, + const debit = await tx.peerPullDebit.get( + parsedTx.peerPullDebitId, ); if (!debit) throw Error("not found"); return buildTransactionForPullPaymentDebit(debit); @@ -347,9 +347,9 @@ export async function getTransactionById( case TransactionType.PeerPushDebit: { return await ws.db - .mktx((x) => [x.peerPushPaymentInitiations, x.contractTerms]) + .mktx((x) => [x.peerPushDebit, x.contractTerms]) .runReadWrite(async (tx) => { - const debit = await tx.peerPushPaymentInitiations.get( + const debit = await tx.peerPushDebit.get( parsedTx.pursePub, ); if (!debit) throw Error("not found"); @@ -363,17 +363,17 @@ export async function getTransactionById( } case TransactionType.PeerPushCredit: { - const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId; + const peerPushCreditId = parsedTx.peerPushCreditId; return await ws.db .mktx((x) => [ - x.peerPushPaymentIncoming, + x.peerPushCredit, x.contractTerms, x.withdrawalGroups, x.operationRetries, ]) .runReadWrite(async (tx) => { - const pushInc = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const pushInc = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!pushInc) throw Error("not found"); const ct = await tx.contractTerms.get(pushInc.contractTermsHash); @@ -405,13 +405,13 @@ export async function getTransactionById( const pursePub = parsedTx.pursePub; return await ws.db .mktx((x) => [ - x.peerPullPaymentInitiations, + x.peerPullCredit, x.contractTerms, x.withdrawalGroups, x.operationRetries, ]) .runReadWrite(async (tx) => { - const pushInc = await tx.peerPullPaymentInitiations.get(pursePub); + const pushInc = await tx.peerPullCredit.get(pursePub); if (!pushInc) throw Error("not found"); const ct = await tx.contractTerms.get(pushInc.contractTermsHash); checkDbInvariant(!!ct); @@ -442,7 +442,7 @@ export async function getTransactionById( } function buildTransactionForPushPaymentDebit( - pi: PeerPushPaymentInitiationRecord, + pi: PeerPushDebitRecord, contractTerms: PeerContractTerms, ort?: OperationRetryRecord, ): Transaction { @@ -490,14 +490,14 @@ function buildTransactionForPullPaymentDebit( timestamp: pi.timestampCreated, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId: pi.peerPullPaymentIncomingId, + peerPullDebitId: pi.peerPullDebitId, }), ...(ort?.lastError ? { error: ort.lastError } : {}), }; } function buildTransactionForPeerPullCredit( - pullCredit: PeerPullPaymentInitiationRecord, + pullCredit: PeerPullCreditRecord, pullCreditOrt: OperationRetryRecord | undefined, peerContractTerms: PeerContractTerms, wsr: WithdrawalGroupRecord | undefined, @@ -606,7 +606,7 @@ function buildTransactionForPeerPushCredit( timestamp: wsr.timestampStart, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: pushInc.peerPushPaymentIncomingId, + peerPushCreditId: pushInc.peerPushCreditId, }), kycUrl: pushInc.kycUrl, ...(wsrOrt?.lastError ? { error: wsrOrt.lastError } : {}), @@ -629,7 +629,7 @@ function buildTransactionForPeerPushCredit( timestamp: pushInc.timestamp, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: pushInc.peerPushPaymentIncomingId, + peerPushCreditId: pushInc.peerPushCreditId, }), ...(pushOrt?.lastError ? { error: pushOrt.lastError } : {}), }; @@ -654,7 +654,7 @@ function buildTransactionForBankIntegratedWithdraw( reservePub: wgRecord.reservePub, bankConfirmationUrl: wgRecord.wgInfo.bankInfo.confirmUrl, reserveIsReady: - wgRecord.status === WithdrawalGroupStatus.Finished || + wgRecord.status === WithdrawalGroupStatus.Done || wgRecord.status === WithdrawalGroupStatus.PendingReady, }, kycUrl: wgRecord.kycUrl, @@ -698,7 +698,7 @@ function buildTransactionForManualWithdraw( reservePub: withdrawalGroup.reservePub, exchangePaytoUris, reserveIsReady: - withdrawalGroup.status === WithdrawalGroupStatus.Finished || + withdrawalGroup.status === WithdrawalGroupStatus.Done || withdrawalGroup.status === WithdrawalGroupStatus.PendingReady, }, kycUrl: withdrawalGroup.kycUrl, @@ -944,10 +944,10 @@ export async function getTransactions( x.exchangeDetails, x.exchanges, x.operationRetries, - x.peerPullPaymentIncoming, - x.peerPushPaymentInitiations, - x.peerPushPaymentIncoming, - x.peerPullPaymentInitiations, + x.peerPullDebit, + x.peerPushDebit, + x.peerPushCredit, + x.peerPullCredit, x.planchets, x.purchases, x.contractTerms, @@ -985,7 +985,7 @@ export async function getTransactions( } if ( pi.status !== PeerPullDebitRecordStatus.PendingDeposit && - pi.status !== PeerPullDebitRecordStatus.DonePaid + pi.status !== PeerPullDebitRecordStatus.Done ) { return; } @@ -1004,7 +1004,7 @@ export async function getTransactions( if (shouldSkipSearch(transactionsRequest, [])) { return; } - if (pi.status === PeerPushPaymentIncomingStatus.DialogProposed) { + if (pi.status === PeerPushCreditStatus.DialogProposed) { // We don't report proposed push credit transactions, user needs // to scan URI again and confirm to see it. return; @@ -1268,9 +1268,9 @@ export async function getTransactions( export type ParsedTransactionIdentifier = | { tag: TransactionType.Deposit; depositGroupId: string } | { tag: TransactionType.Payment; proposalId: string } - | { tag: TransactionType.PeerPullDebit; peerPullPaymentIncomingId: string } + | { tag: TransactionType.PeerPullDebit; peerPullDebitId: string } | { tag: TransactionType.PeerPullCredit; pursePub: string } - | { tag: TransactionType.PeerPushCredit; peerPushPaymentIncomingId: string } + | { tag: TransactionType.PeerPushCredit; peerPushCreditId: string } | { tag: TransactionType.PeerPushDebit; pursePub: string } | { tag: TransactionType.Refresh; refreshGroupId: string } | { tag: TransactionType.Refund; refundGroupId: string } @@ -1289,9 +1289,9 @@ export function constructTransactionIdentifier( case TransactionType.PeerPullCredit: return `txn:${pTxId.tag}:${pTxId.pursePub}` as TransactionIdStr; case TransactionType.PeerPullDebit: - return `txn:${pTxId.tag}:${pTxId.peerPullPaymentIncomingId}` as TransactionIdStr; + return `txn:${pTxId.tag}:${pTxId.peerPullDebitId}` as TransactionIdStr; case TransactionType.PeerPushCredit: - return `txn:${pTxId.tag}:${pTxId.peerPushPaymentIncomingId}` as TransactionIdStr; + return `txn:${pTxId.tag}:${pTxId.peerPushCreditId}` as TransactionIdStr; case TransactionType.PeerPushDebit: return `txn:${pTxId.tag}:${pTxId.pursePub}` as TransactionIdStr; case TransactionType.Refresh: @@ -1337,12 +1337,12 @@ export function parseTransactionIdentifier( case TransactionType.PeerPullDebit: return { tag: TransactionType.PeerPullDebit, - peerPullPaymentIncomingId: rest[0], + peerPullDebitId: rest[0], }; case TransactionType.PeerPushCredit: return { tag: TransactionType.PeerPushCredit, - peerPushPaymentIncomingId: rest[0], + peerPushCreditId: rest[0], }; case TransactionType.PeerPushDebit: return { tag: TransactionType.PeerPushDebit, pursePub: rest[0] }; @@ -1455,7 +1455,7 @@ export async function retryTransaction( case TransactionType.PeerPullDebit: { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPullDebit, - peerPullPaymentIncomingId: parsedTx.peerPullPaymentIncomingId, + peerPullDebitId: parsedTx.peerPullDebitId, }); await resetPendingTaskTimeout(ws, taskId); stopLongpolling(ws, taskId); @@ -1464,7 +1464,7 @@ export async function retryTransaction( case TransactionType.PeerPushCredit: { const taskId = constructTaskIdentifier({ tag: PendingTaskType.PeerPushCredit, - peerPushPaymentIncomingId: parsedTx.peerPushPaymentIncomingId, + peerPushCreditId: parsedTx.peerPushCreditId, }); await resetPendingTaskTimeout(ws, taskId); stopLongpolling(ws, taskId); @@ -1522,10 +1522,10 @@ export async function suspendTransaction( await suspendPeerPushDebitTransaction(ws, tx.pursePub); break; case TransactionType.PeerPullDebit: - await suspendPeerPullDebitTransaction(ws, tx.peerPullPaymentIncomingId); + await suspendPeerPullDebitTransaction(ws, tx.peerPullDebitId); break; case TransactionType.PeerPushCredit: - await suspendPeerPushCreditTransaction(ws, tx.peerPushPaymentIncomingId); + await suspendPeerPushCreditTransaction(ws, tx.peerPushCreditId); break; case TransactionType.Refund: throw Error("refund transactions can't be suspended or resumed"); @@ -1568,10 +1568,10 @@ export async function failTransaction( await failPeerPullCreditTransaction(ws, tx.pursePub); return; case TransactionType.PeerPullDebit: - await failPeerPullDebitTransaction(ws, tx.peerPullPaymentIncomingId); + await failPeerPullDebitTransaction(ws, tx.peerPullDebitId); return; case TransactionType.PeerPushCredit: - await failPeerPushCreditTransaction(ws, tx.peerPushPaymentIncomingId); + await failPeerPushCreditTransaction(ws, tx.peerPushCreditId); return; case TransactionType.PeerPushDebit: await failPeerPushDebitTransaction(ws, tx.pursePub); @@ -1613,10 +1613,10 @@ export async function resumeTransaction( await resumePeerPushDebitTransaction(ws, tx.pursePub); break; case TransactionType.PeerPullDebit: - await resumePeerPullDebitTransaction(ws, tx.peerPullPaymentIncomingId); + await resumePeerPullDebitTransaction(ws, tx.peerPullDebitId); break; case TransactionType.PeerPushCredit: - await resumePeerPushCreditTransaction(ws, tx.peerPushPaymentIncomingId); + await resumePeerPushCreditTransaction(ws, tx.peerPushCreditId); break; case TransactionType.Refund: throw Error("refund transactions can't be suspended or resumed"); @@ -1641,16 +1641,16 @@ export async function deleteTransaction( switch (parsedTx.tag) { case TransactionType.PeerPushCredit: { - const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId; + const peerPushCreditId = parsedTx.peerPushCreditId; await ws.db .mktx((x) => [ x.withdrawalGroups, - x.peerPushPaymentIncoming, + x.peerPushCredit, x.tombstones, ]) .runReadWrite(async (tx) => { - const pushInc = await tx.peerPushPaymentIncoming.get( - peerPushPaymentIncomingId, + const pushInc = await tx.peerPushCredit.get( + peerPushCreditId, ); if (!pushInc) { return; @@ -1668,12 +1668,12 @@ export async function deleteTransaction( }); } } - await tx.peerPushPaymentIncoming.delete(peerPushPaymentIncomingId); + await tx.peerPushCredit.delete(peerPushCreditId); await tx.tombstones.put({ id: TombstoneTag.DeletePeerPushCredit + ":" + - peerPushPaymentIncomingId, + peerPushCreditId, }); }); return; @@ -1684,11 +1684,11 @@ export async function deleteTransaction( await ws.db .mktx((x) => [ x.withdrawalGroups, - x.peerPullPaymentInitiations, + x.peerPullCredit, x.tombstones, ]) .runReadWrite(async (tx) => { - const pullIni = await tx.peerPullPaymentInitiations.get(pursePub); + const pullIni = await tx.peerPullCredit.get(pursePub); if (!pullIni) { return; } @@ -1705,7 +1705,7 @@ export async function deleteTransaction( }); } } - await tx.peerPullPaymentInitiations.delete(pursePub); + await tx.peerPullCredit.delete(pursePub); await tx.tombstones.put({ id: TombstoneTag.DeletePeerPullCredit + ":" + pursePub, }); @@ -1795,7 +1795,7 @@ export async function deleteTransaction( case TransactionType.Refund: { const refundGroupId = parsedTx.refundGroupId; await ws.db - .mktx((x) => [x.refundGroups, x.tombstones, x.refundItems]) + .mktx((x) => [x.refundGroups, x.tombstones]) .runReadWrite(async (tx) => { const refundRecord = await tx.refundGroups.get(refundGroupId); if (!refundRecord) { @@ -1809,15 +1809,15 @@ export async function deleteTransaction( } case TransactionType.PeerPullDebit: { - const peerPullPaymentIncomingId = parsedTx.peerPullPaymentIncomingId; + const peerPullDebitId = parsedTx.peerPullDebitId; await ws.db - .mktx((x) => [x.peerPullPaymentIncoming, x.tombstones]) + .mktx((x) => [x.peerPullDebit, x.tombstones]) .runReadWrite(async (tx) => { - const debit = await tx.peerPullPaymentIncoming.get( - peerPullPaymentIncomingId, + const debit = await tx.peerPullDebit.get( + peerPullDebitId, ); if (debit) { - await tx.peerPullPaymentIncoming.delete(peerPullPaymentIncomingId); + await tx.peerPullDebit.delete(peerPullDebitId); await tx.tombstones.put({ id: transactionId }); } }); @@ -1828,11 +1828,11 @@ export async function deleteTransaction( case TransactionType.PeerPushDebit: { const pursePub = parsedTx.pursePub; await ws.db - .mktx((x) => [x.peerPushPaymentInitiations, x.tombstones]) + .mktx((x) => [x.peerPushDebit, x.tombstones]) .runReadWrite(async (tx) => { - const debit = await tx.peerPushPaymentInitiations.get(pursePub); + const debit = await tx.peerPushDebit.get(pursePub); if (debit) { - await tx.peerPushPaymentInitiations.delete(pursePub); + await tx.peerPushDebit.delete(pursePub); await tx.tombstones.put({ id: transactionId }); } }); @@ -1875,10 +1875,10 @@ export async function abortTransaction( await abortPeerPullCreditTransaction(ws, txId.pursePub); break; case TransactionType.PeerPullDebit: - await abortPeerPullDebitTransaction(ws, txId.peerPullPaymentIncomingId); + await abortPeerPullDebitTransaction(ws, txId.peerPullDebitId); break; case TransactionType.PeerPushCredit: - await abortPeerPushCreditTransaction(ws, txId.peerPushPaymentIncomingId); + await abortPeerPushCreditTransaction(ws, txId.peerPushCreditId); break; case TransactionType.PeerPushDebit: await abortPeerPushDebitTransaction(ws, txId.pursePub); diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index b2b25144d..32e63f4f6 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -315,7 +315,7 @@ export async function abortWithdrawalTransaction( case WithdrawalGroupStatus.AbortingBank: // No transition needed, but not an error break; - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: case WithdrawalGroupStatus.FailedBankAborted: case WithdrawalGroupStatus.AbortedExchange: case WithdrawalGroupStatus.AbortedBank: @@ -395,7 +395,7 @@ export function computeWithdrawalTransactionStatus( return { major: TransactionMajorState.Aborted, }; - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: return { major: TransactionMajorState.Done, }; @@ -499,7 +499,7 @@ export function computeWithdrawalTransactionActions( switch (wgRecord.status) { case WithdrawalGroupStatus.FailedBankAborted: return [TransactionAction.Delete]; - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: return [TransactionAction.Delete]; case WithdrawalGroupStatus.PendingRegisteringBank: return [TransactionAction.Suspend, TransactionAction.Abort]; @@ -1457,7 +1457,7 @@ async function processWithdrawalGroupPendingReady( return undefined; } const txStatusOld = computeWithdrawalTransactionStatus(wg); - wg.status = WithdrawalGroupStatus.Finished; + wg.status = WithdrawalGroupStatus.Done; wg.timestampFinish = TalerPreciseTimestamp.now(); const txStatusNew = computeWithdrawalTransactionStatus(wg); await tx.withdrawalGroups.put(wg); @@ -1555,7 +1555,7 @@ async function processWithdrawalGroupPendingReady( logger.info(`now withdrawn ${numFinished} of ${numTotalCoins} coins`); if (wg.timestampFinish === undefined && numFinished === numTotalCoins) { wg.timestampFinish = TalerPreciseTimestamp.now(); - wg.status = WithdrawalGroupStatus.Finished; + wg.status = WithdrawalGroupStatus.Done; await makeCoinsVisible(ws, tx, transactionId); } @@ -1647,7 +1647,7 @@ export async function processWithdrawalGroup( } break; } - case WithdrawalGroupStatus.Finished: + case WithdrawalGroupStatus.Done: case WithdrawalGroupStatus.FailedBankAborted: { // FIXME return TaskRunResult.pending(); diff --git a/packages/taler-wallet-core/src/pending-types.ts b/packages/taler-wallet-core/src/pending-types.ts index 82eb542a7..627888b4d 100644 --- a/packages/taler-wallet-core/src/pending-types.ts +++ b/packages/taler-wallet-core/src/pending-types.ts @@ -99,14 +99,14 @@ export interface PendingPeerPullInitiationTask { */ export interface PendingPeerPullDebitTask { type: PendingTaskType.PeerPullDebit; - peerPullPaymentIncomingId: string; + peerPullDebitId: string; } /** */ export interface PendingPeerPushCreditTask { type: PendingTaskType.PeerPushCredit; - peerPushPaymentIncomingId: string; + peerPushCreditId: string; } /** diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts index abf0bbc02..ce9fec186 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.ts @@ -1002,7 +1002,7 @@ export async function selectPeerCoins( x.coinAvailability, x.denominations, x.refreshGroups, - x.peerPushPaymentInitiations, + x.peerPushDebit, ]) .runReadWrite(async (tx) => { const exchanges = await tx.exchanges.iter().toArray(); diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts index 1c3ff6a2a..309c17a43 100644 --- a/packages/taler-wallet-core/src/util/query.ts +++ b/packages/taler-wallet-core/src/util/query.ts @@ -35,7 +35,7 @@ import { IDBKeyPath, IDBKeyRange, } from "@gnu-taler/idb-bridge"; -import { Logger, j2s } from "@gnu-taler/taler-util"; +import { Codec, Logger, j2s } from "@gnu-taler/taler-util"; const logger = new Logger("query.ts"); @@ -387,11 +387,11 @@ export interface StoreReadWriteAccessor { export interface StoreWithIndexes< StoreName extends string, - SD extends StoreDescriptor, + RecordType, IndexMap, > { storeName: StoreName; - store: SD; + store: StoreDescriptor; indexMap: IndexMap; /** @@ -401,19 +401,13 @@ export interface StoreWithIndexes< mark: Symbol; } -export type GetRecordType = T extends StoreDescriptor ? X : unknown; - const storeWithIndexesSymbol = Symbol("StoreWithIndexesMark"); -export function describeStore< - StoreName extends string, - SD extends StoreDescriptor, - IndexMap, ->( +export function describeStore( name: StoreName, - s: SD, + s: StoreDescriptor, m: IndexMap, -): StoreWithIndexes { +): StoreWithIndexes { return { storeName: name, store: s, @@ -422,13 +416,72 @@ export function describeStore< }; } +export function describeStoreV2< + StoreName extends string, + RecordType, + IndexMap extends { [x: string]: IndexDescriptor } = {}, +>(args: { + storeName: StoreName; + recordCodec: Codec; + keyPath?: IDBKeyPath | IDBKeyPath[]; + autoIncrement?: boolean; + /** + * Database version that this store was added in, or + * undefined if added in the first version. + */ + versionAdded?: number; + indexes?: IndexMap; +}): StoreWithIndexes { + return { + storeName: args.storeName, + store: { + _dummy: undefined as any, + autoIncrement: args.autoIncrement, + keyPath: args.keyPath, + versionAdded: args.versionAdded, + }, + indexMap: args.indexes ?? ({} as IndexMap), + mark: storeWithIndexesSymbol, + }; +} + +type KeyPathComponents = string | number; + +/** + * Follow a key path (dot-separated) in an object. + */ +type DerefKeyPath = P extends `${infer PX extends keyof T & + KeyPathComponents}` + ? T[PX] + : P extends `${infer P0 extends keyof T & KeyPathComponents}.${infer Rest}` + ? DerefKeyPath + : unknown; + +/** + * Return a path if it is a valid dot-separate path to an object. + * Otherwise, return "never". + */ +type ValidateKeyPath = P extends `${infer PX extends keyof T & + KeyPathComponents}` + ? PX + : P extends `${infer P0 extends keyof T & KeyPathComponents}.${infer Rest}` + ? `${P0}.${ValidateKeyPath}` + : never; + +// function foo( +// x: T, +// p: P extends ValidateKeyPath ? P : never, +// ): void {} + +// foo({x: [0,1,2]}, "x.0"); + export type GetReadOnlyAccess = { [P in keyof BoundStores]: BoundStores[P] extends StoreWithIndexes< - infer SN, - infer SD, - infer IM + infer StoreName, + infer RecordType, + infer IndexMap > - ? StoreReadOnlyAccessor, IM> + ? StoreReadOnlyAccessor : unknown; }; @@ -446,11 +499,11 @@ export type DbReadOnlyTransaction< } ? { [P in Stores]: StoreMap[P] extends StoreWithIndexes< - infer SN, - infer SD, - infer IM + infer StoreName, + infer RecordType, + infer IndexMap > - ? StoreReadOnlyAccessor, IM> + ? StoreReadOnlyAccessor : unknown; } : unknown; @@ -463,22 +516,22 @@ export type DbReadWriteTransaction< } ? { [P in Stores]: StoreMap[P] extends StoreWithIndexes< - infer SN, - infer SD, - infer IM + infer StoreName, + infer RecordType, + infer IndexMap > - ? StoreReadWriteAccessor, IM> + ? StoreReadWriteAccessor : unknown; } : unknown; export type GetReadWriteAccess = { [P in keyof BoundStores]: BoundStores[P] extends StoreWithIndexes< - infer SN, - infer SD, - infer IM + infer StoreName, + infer RecordType, + infer IndexMap > - ? StoreReadWriteAccessor, IM> + ? StoreReadWriteAccessor : unknown; }; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index cb82a3a43..11fb3f739 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -354,9 +354,9 @@ async function callOperationHandler( case PendingTaskType.PeerPullCredit: return await processPeerPullCredit(ws, pending.pursePub); case PendingTaskType.PeerPullDebit: - return await processPeerPullDebit(ws, pending.peerPullPaymentIncomingId); + return await processPeerPullDebit(ws, pending.peerPullDebitId); case PendingTaskType.PeerPushCredit: - return await processPeerPushCredit(ws, pending.peerPushPaymentIncomingId); + return await processPeerPushCredit(ws, pending.peerPushCreditId); default: return assertUnreachable(pending); } @@ -1876,7 +1876,7 @@ class InternalWalletStateImpl implements InternalWalletState { return computeRefundTransactionState(rec); } case TransactionType.PeerPullCredit: - const rec = await tx.peerPullPaymentInitiations.get( + const rec = await tx.peerPullCredit.get( parsedTxId.pursePub, ); if (!rec) { @@ -1884,8 +1884,8 @@ class InternalWalletStateImpl implements InternalWalletState { } return computePeerPullCreditTransactionState(rec); case TransactionType.PeerPullDebit: { - const rec = await tx.peerPullPaymentIncoming.get( - parsedTxId.peerPullPaymentIncomingId, + const rec = await tx.peerPullDebit.get( + parsedTxId.peerPullDebitId, ); if (!rec) { return undefined; @@ -1893,8 +1893,8 @@ class InternalWalletStateImpl implements InternalWalletState { return computePeerPullDebitTransactionState(rec); } case TransactionType.PeerPushCredit: { - const rec = await tx.peerPushPaymentIncoming.get( - parsedTxId.peerPushPaymentIncomingId, + const rec = await tx.peerPushCredit.get( + parsedTxId.peerPushCreditId, ); if (!rec) { return undefined; @@ -1902,7 +1902,7 @@ class InternalWalletStateImpl implements InternalWalletState { return computePeerPushCreditTransactionState(rec); } case TransactionType.PeerPushDebit: { - const rec = await tx.peerPushPaymentInitiations.get( + const rec = await tx.peerPushDebit.get( parsedTxId.pursePub, ); if (!rec) { diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts index 098f18921..8bae9470f 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -78,7 +78,7 @@ export function useComponentState({ const { contractTerms, - peerPullPaymentIncomingId, + peerPullDebitId, amountEffective, amountRaw, } = hook.response.p2p; @@ -155,7 +155,7 @@ export function useComponentState({ const resp = await api.wallet.call( WalletApiOperation.ConfirmPeerPullDebit, { - peerPullPaymentIncomingId, + peerPullDebitId, }, ); onSuccess(resp.transactionId); diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts index fb9acbe83..47c644736 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts @@ -58,7 +58,7 @@ export function useComponentState({ const { contractTerms, - peerPushPaymentIncomingId, + peerPushCreditId, amountEffective, amountRaw, } = hook.response; @@ -72,7 +72,7 @@ export function useComponentState({ const resp = await api.wallet.call( WalletApiOperation.ConfirmPeerPushCredit, { - peerPushPaymentIncomingId, + peerPushCreditId, }, ); onSuccess(resp.transactionId); -- cgit v1.2.3 From 132ece8e53d2c7d69c943a2898ed07411c63f12f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 8 Sep 2023 11:45:31 +0200 Subject: wallet-core: store contract terms in separate object store only --- packages/taler-wallet-core/src/db.ts | 75 +++++++++++----------- .../src/operations/pay-peer-pull-credit.ts | 33 ++++++---- .../src/operations/pay-peer-push-credit.ts | 1 - .../src/operations/pay-peer-push-debit.ts | 33 ++++++---- .../src/operations/transactions.ts | 64 ++++++++---------- 5 files changed, 106 insertions(+), 100 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 9aedb888b..679ca2842 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -101,6 +101,14 @@ import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; * @author Florian Dold */ +/** + FIXMEs: + - Contract terms can be quite large. We currently tend to read the + full contract terms from the DB quite often. + Instead, we should probably extract what we need into a separate object + store. + */ + /** * Name of the Taler database. This is effectively the major * version of the DB schema. Whenever it changes, custom import logic @@ -166,47 +174,47 @@ export enum WithdrawalGroupStatus { /** * Reserve must be registered with the bank. */ - PendingRegisteringBank = 0x0100_0000, - SuspendedRegisteringBank = 0x0110_0000, + PendingRegisteringBank = 0x0100_0001, + SuspendedRegisteringBank = 0x0110_0001, /** * We've registered reserve's information with the bank * and are now waiting for the user to confirm the withdraw * with the bank (typically 2nd factor auth). */ - PendingWaitConfirmBank = 0x0100_0001, - SuspendedWaitConfirmBank = 0x0110_0001, + PendingWaitConfirmBank = 0x0100_0002, + SuspendedWaitConfirmBank = 0x0110_0002, /** * Querying reserve status with the exchange. */ - PendingQueryingStatus = 0x0100_0002, - SuspendedQueryingStatus = 0x0110_0002, + PendingQueryingStatus = 0x0100_0003, + SuspendedQueryingStatus = 0x0110_0003, /** * Ready for withdrawal. */ - PendingReady = 0x0100_0003, - SuspendedReady = 0x0110_0003, + PendingReady = 0x0100_0004, + SuspendedReady = 0x0110_0004, /** * We are telling the bank that we don't want to complete * the withdrawal! */ - AbortingBank = 0x0103_0000, - SuspendedAbortingBank = 0x0113_0000, + AbortingBank = 0x0103_0001, + SuspendedAbortingBank = 0x0113_0001, /** * Exchange wants KYC info from the user. */ - PendingKyc = 0x0100_0004, - SuspendedKyc = 0x0110_004, + PendingKyc = 0x0100_0005, + SuspendedKyc = 0x0110_005, /** * Exchange is doing AML checks. */ - PendingAml = 0x0100_0005, - SuspendedAml = 0x0100_0005, + PendingAml = 0x0100_0006, + SuspendedAml = 0x0100_0006, /** * The corresponding withdraw record has been created. @@ -218,9 +226,9 @@ export enum WithdrawalGroupStatus { /** * The bank aborted the withdrawal. */ - FailedBankAborted = 0x0501_0000, + FailedBankAborted = 0x0501_0001, - FailedAbortingBank = 0x0501_0001, + FailedAbortingBank = 0x0501_0002, /** * Aborted in a state where we were supposed to @@ -272,9 +280,9 @@ export interface ReserveBankInfo { */ export enum DenominationVerificationStatus { /** - * Verification was delayed. + * Verification was delayed (pending). */ - Unverified = 0x0500_0000, + Unverified = 0x0100_0000, /** * Verified as valid. @@ -532,6 +540,7 @@ export enum ExchangeEntryDbRecordStatus { Used = 3, } +// FIXME: Use status ranges for this as well? export enum ExchangeEntryDbUpdateStatus { Initial = 1, InitialUpdate = 2, @@ -612,9 +621,9 @@ export interface ExchangeEntryRecord { } export enum PlanchetStatus { - Pending = 10 /* ACTIVE_START */, - KycRequired = 11 /* ACTIVE_START + 1 */, - WithdrawalDone = 50 /* DORMANT_START */, + Pending = 0x0100_0000, + KycRequired = 0x0100_0001, + WithdrawalDone = 0x0500_000, } /** @@ -1358,7 +1367,8 @@ export interface WgInfoBankManual { export interface WgInfoBankPeerPull { withdrawalType: WithdrawalRecordType.PeerPullCredit; - contractTerms: any; + // FIXME: include a transaction ID here? + /** * Needed to quickly construct the taler:// URI for the counterparty * without a join. @@ -1369,7 +1379,7 @@ export interface WgInfoBankPeerPull { export interface WgInfoBankPeerPush { withdrawalType: WithdrawalRecordType.PeerPushCredit; - contractTerms: any; + // FIXME: include a transaction ID here? } export interface WgInfoBankRecoup { @@ -1829,11 +1839,6 @@ export interface PeerPushDebitRecord { */ contractEncNonce: string; - /** - * FIXME: Put those in a different object store! - */ - contractTerms: PeerContractTerms; - purseExpiration: TalerProtocolTimestamp; timestampCreated: TalerPreciseTimestamp; @@ -1861,7 +1866,7 @@ export enum PeerPullPaymentCreditStatus { SuspendedCreatePurse = 0x0110_0000, SuspendedReady = 0x0110_0001, SuspendedMergeKycRequired = 0x0110_0002, - SuspendedWithdrawing = 0x0113_0000, + SuspendedWithdrawing = 0x0110_0000, SuspendedAbortingDeletePurse = 0x0113_0000, @@ -1878,6 +1883,7 @@ export interface PeerPullCreditRecord { /** * Amount requested. + * FIXME: What type of instructed amount is i? */ amount: AmountString; @@ -1908,11 +1914,6 @@ export interface PeerPullCreditRecord { contractEncNonce: string; - /** - * FIXME: Put in separate object store! - */ - contractTerms: PeerContractTerms; - mergeTimestamp: TalerPreciseTimestamp; mergeReserveRowId: number; @@ -2529,8 +2530,7 @@ export const WalletStoresV1 = { byWithdrawalGroupId: describeIndex( "byWithdrawalGroupId", "withdrawalGroupId", - { - }, + {}, ), }, ), @@ -2571,8 +2571,7 @@ export const WalletStoresV1 = { }), { byProposalId: describeIndex("byProposalId", "proposalId"), - byStatus: describeIndex("byStatus", "status", { - }), + byStatus: describeIndex("byStatus", "status", {}), }, ), refundItems: describeStore( diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts index edadad1fc..0355eb152 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts @@ -27,6 +27,7 @@ import { InitiatePeerPullCreditResponse, Logger, NotificationType, + PeerContractTerms, TalerErrorCode, TalerPreciseTimestamp, TalerProtocolTimestamp, @@ -143,7 +144,6 @@ async function queryPurseForPeerPullCredit( amount: Amounts.parseOrThrow(pullIni.amount), wgInfo: { withdrawalType: WithdrawalRecordType.PeerPullCredit, - contractTerms: pullIni.contractTerms, contractPriv: pullIni.contractPriv, }, forcedWithdrawalGroupId: pullIni.withdrawalGroupId, @@ -283,9 +283,7 @@ async function processPeerPullCreditAbortingDeletePurse( if (!ppiRec) { return undefined; } - if ( - ppiRec.status !== PeerPullPaymentCreditStatus.AbortingDeletePurse - ) { + if (ppiRec.status !== PeerPullPaymentCreditStatus.AbortingDeletePurse) { return undefined; } const oldTxState = computePeerPullCreditTransactionState(ppiRec); @@ -371,6 +369,18 @@ async function handlePeerPullCreditCreatePurse( throw Error("merge reserve for peer pull payment not found in database"); } + const contractTermsRecord = await ws.db + .mktx((x) => [x.contractTerms]) + .runReadOnly(async (tx) => { + return tx.contractTerms.get(pullIni.contractTermsHash); + }); + + if (!contractTermsRecord) { + throw Error("contract terms for peer pull payment not found in database"); + } + + const contractTerms: PeerContractTerms = contractTermsRecord.contractTermsRaw; + const reservePayto = talerPaytoFromExchangeReserve( pullIni.exchangeBaseUrl, mergeReserve.reservePub, @@ -379,19 +389,19 @@ async function handlePeerPullCreditCreatePurse( const econtractResp = await ws.cryptoApi.encryptContractForDeposit({ contractPriv: pullIni.contractPriv, contractPub: pullIni.contractPub, - contractTerms: pullIni.contractTerms, + contractTerms: contractTermsRecord, pursePriv: pullIni.pursePriv, pursePub: pullIni.pursePub, nonce: pullIni.contractEncNonce, }); - const purseExpiration = pullIni.contractTerms.purse_expiration; + const purseExpiration = contractTerms.purse_expiration; const sigRes = await ws.cryptoApi.signReservePurseCreate({ contractTermsHash: pullIni.contractTermsHash, flags: WalletAccountMergeFlags.CreateWithPurseFee, mergePriv: pullIni.mergePriv, mergeTimestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp), - purseAmount: pullIni.contractTerms.amount, + purseAmount: pullIni.amount, purseExpiration: purseExpiration, purseFee: purseFee, pursePriv: pullIni.pursePriv, @@ -410,7 +420,7 @@ async function handlePeerPullCreditCreatePurse( purse_fee: purseFee, purse_pub: pullIni.pursePub, purse_sig: sigRes.purseSig, - purse_value: pullIni.contractTerms.amount, + purse_value: pullIni.amount, reserve_sig: sigRes.accountSig, econtract: econtractResp.econtract, }; @@ -585,8 +595,7 @@ async function processPeerPullCreditKycRequired( requirementRow: kycPending.requirement_row, }; peerInc.kycUrl = kycStatus.kyc_url; - peerInc.status = - PeerPullPaymentCreditStatus.PendingMergeKycRequired; + peerInc.status = PeerPullPaymentCreditStatus.PendingMergeKycRequired; const newTxState = computePeerPullCreditTransactionState(peerInc); await tx.peerPullCredit.put(peerInc); // We'll remove this eventually! New clients should rely on the @@ -769,7 +778,6 @@ export async function initiatePeerPullPayment( mergePriv: mergePair.priv, mergePub: mergePair.pub, status: PeerPullPaymentCreditStatus.PendingCreatePurse, - contractTerms: contractTerms, mergeTimestamp, contractEncNonce, mergeReserveRowId: mergeReserveRowId, @@ -848,8 +856,7 @@ export async function suspendPeerPullCreditTransaction( newStatus = PeerPullPaymentCreditStatus.SuspendedReady; break; case PeerPullPaymentCreditStatus.AbortingDeletePurse: - newStatus = - PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse; + newStatus = PeerPullPaymentCreditStatus.SuspendedAbortingDeletePurse; break; case PeerPullPaymentCreditStatus.Done: case PeerPullPaymentCreditStatus.SuspendedCreatePurse: diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts index f0f659aa3..89d9e3b49 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts @@ -446,7 +446,6 @@ async function handlePendingMerge( amount, wgInfo: { withdrawalType: WithdrawalRecordType.PeerPushCredit, - contractTerms, }, forcedWithdrawalGroupId: peerInc.withdrawalGroupId, exchangeBaseUrl: peerInc.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts index a2e7a6891..e80ffc059 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts @@ -154,9 +154,7 @@ async function handlePurseCreationConflict( await ws.db .mktx((x) => [x.peerPushDebit]) .runReadWrite(async (tx) => { - const myPpi = await tx.peerPushDebit.get( - peerPushInitiation.pursePub, - ); + const myPpi = await tx.peerPushDebit.get(peerPushInitiation.pursePub); if (!myPpi) { return; } @@ -182,10 +180,27 @@ async function processPeerPushDebitCreateReserve( ws: InternalWalletState, peerPushInitiation: PeerPushDebitRecord, ): Promise { - logger.info("processing peer-push-debit pending(create-reserve)"); const pursePub = peerPushInitiation.pursePub; const purseExpiration = peerPushInitiation.purseExpiration; const hContractTerms = peerPushInitiation.contractTermsHash; + const transactionId = constructTransactionIdentifier({ + tag: TransactionType.PeerPushDebit, + pursePub: pursePub, + }); + + logger.trace(`processing ${transactionId} pending(create-reserve)`); + + const contractTermsRecord = await ws.db + .mktx((x) => [x.contractTerms]) + .runReadOnly(async (tx) => { + return tx.contractTerms.get(hContractTerms); + }); + + if (!contractTermsRecord) { + throw Error( + `db invariant failed, contract terms for ${transactionId} missing`, + ); + } const purseSigResp = await ws.cryptoApi.signPurseCreation({ hContractTerms, @@ -208,7 +223,7 @@ async function processPeerPushDebitCreateReserve( }); const encryptContractRequest: EncryptContractRequest = { - contractTerms: peerPushInitiation.contractTerms, + contractTerms: contractTermsRecord.contractTermsRaw, mergePriv: peerPushInitiation.mergePriv, pursePriv: peerPushInitiation.pursePriv, pursePub: peerPushInitiation.pursePub, @@ -329,9 +344,7 @@ async function processPeerPushDebitAbortingDeletePurse( if (!ppiRec) { return undefined; } - if ( - ppiRec.status !== PeerPushDebitStatus.AbortingDeletePurse - ) { + if (ppiRec.status !== PeerPushDebitStatus.AbortingDeletePurse) { return undefined; } const currency = Amounts.currencyOf(ppiRec.amount); @@ -658,7 +671,6 @@ export async function initiatePeerPushDebit( pursePub: pursePair.pub, timestampCreated: TalerPreciseTimestamp.now(), status: PeerPushDebitStatus.PendingCreatePurse, - contractTerms: contractTerms, contractEncNonce, coinSel: { coinPubs: sel.coins.map((x) => x.coinPub), @@ -881,8 +893,7 @@ export async function suspendPeerPushDebitTransaction( newStatus = PeerPushDebitStatus.SuspendedAbortingRefresh; break; case PeerPushDebitStatus.AbortingDeletePurse: - newStatus = - PeerPushDebitStatus.SuspendedAbortingDeletePurse; + newStatus = PeerPushDebitStatus.SuspendedAbortingDeletePurse; break; case PeerPushDebitStatus.PendingReady: newStatus = PeerPushDebitStatus.SuspendedReady; diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 5c57195c1..ff9fbf57a 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -154,7 +154,18 @@ import { resumePeerPushDebitTransaction, abortPeerPushDebitTransaction, } from "./pay-peer-push-debit.js"; -import { iterRecordsForDeposit, iterRecordsForPeerPullDebit, iterRecordsForPeerPullInitiation, iterRecordsForPeerPushCredit, iterRecordsForPeerPushInitiation, iterRecordsForPurchase, iterRecordsForRefresh, iterRecordsForRefund, iterRecordsForReward, iterRecordsForWithdrawal } from "./pending.js"; +import { + iterRecordsForDeposit, + iterRecordsForPeerPullDebit, + iterRecordsForPeerPullInitiation, + iterRecordsForPeerPushCredit, + iterRecordsForPeerPushInitiation, + iterRecordsForPurchase, + iterRecordsForRefresh, + iterRecordsForRefund, + iterRecordsForReward, + iterRecordsForWithdrawal, +} from "./pending.js"; const logger = new Logger("taler-wallet-core:transactions.ts"); @@ -337,9 +348,7 @@ export async function getTransactionById( return await ws.db .mktx((x) => [x.peerPullDebit]) .runReadWrite(async (tx) => { - const debit = await tx.peerPullDebit.get( - parsedTx.peerPullDebitId, - ); + const debit = await tx.peerPullDebit.get(parsedTx.peerPullDebitId); if (!debit) throw Error("not found"); return buildTransactionForPullPaymentDebit(debit); }); @@ -349,9 +358,7 @@ export async function getTransactionById( return await ws.db .mktx((x) => [x.peerPushDebit, x.contractTerms]) .runReadWrite(async (tx) => { - const debit = await tx.peerPushDebit.get( - parsedTx.pursePub, - ); + const debit = await tx.peerPushDebit.get(parsedTx.pursePub); if (!debit) throw Error("not found"); const ct = await tx.contractTerms.get(debit.contractTermsHash); checkDbInvariant(!!ct); @@ -372,9 +379,7 @@ export async function getTransactionById( x.operationRetries, ]) .runReadWrite(async (tx) => { - const pushInc = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const pushInc = await tx.peerPushCredit.get(peerPushCreditId); if (!pushInc) throw Error("not found"); const ct = await tx.contractTerms.get(pushInc.contractTermsHash); checkDbInvariant(!!ct); @@ -532,8 +537,8 @@ function buildTransactionForPeerPullCredit( // Old transactions don't have it! timestamp: pullCredit.mergeTimestamp ?? TalerPreciseTimestamp.now(), info: { - expiration: wsr.wgInfo.contractTerms.purse_expiration, - summary: wsr.wgInfo.contractTerms.summary, + expiration: peerContractTerms.purse_expiration, + summary: peerContractTerms.summary, }, talerUri: stringifyPayPullUri({ exchangeBaseUrl: wsr.exchangeBaseUrl, @@ -600,8 +605,8 @@ function buildTransactionForPeerPushCredit( amountRaw: Amounts.stringify(wsr.instructedAmount), exchangeBaseUrl: wsr.exchangeBaseUrl, info: { - expiration: wsr.wgInfo.contractTerms.purse_expiration, - summary: wsr.wgInfo.contractTerms.summary, + expiration: peerContractTerms.purse_expiration, + summary: peerContractTerms.summary, }, timestamp: wsr.timestampStart, transactionId: constructTransactionIdentifier({ @@ -1033,7 +1038,7 @@ export async function getTransactions( ), ); }); - + await iterRecordsForPeerPullInitiation(tx, filter, async (pi) => { const currency = Amounts.currencyOf(pi.amount); if (shouldSkipCurrency(transactionsRequest, currency)) { @@ -1078,7 +1083,7 @@ export async function getTransactions( ); transactions.push(buildTransactionForRefund(refundGroup, contractData)); }); - + await iterRecordsForRefresh(tx, filter, async (rg) => { if (shouldSkipCurrency(transactionsRequest, rg.currency)) { return; @@ -1099,7 +1104,7 @@ export async function getTransactions( } }); - await iterRecordsForWithdrawal(tx, filter ,async (wsr) => { + await iterRecordsForWithdrawal(tx, filter, async (wsr) => { if ( shouldSkipCurrency( transactionsRequest, @@ -1643,15 +1648,9 @@ export async function deleteTransaction( case TransactionType.PeerPushCredit: { const peerPushCreditId = parsedTx.peerPushCreditId; await ws.db - .mktx((x) => [ - x.withdrawalGroups, - x.peerPushCredit, - x.tombstones, - ]) + .mktx((x) => [x.withdrawalGroups, x.peerPushCredit, x.tombstones]) .runReadWrite(async (tx) => { - const pushInc = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const pushInc = await tx.peerPushCredit.get(peerPushCreditId); if (!pushInc) { return; } @@ -1670,10 +1669,7 @@ export async function deleteTransaction( } await tx.peerPushCredit.delete(peerPushCreditId); await tx.tombstones.put({ - id: - TombstoneTag.DeletePeerPushCredit + - ":" + - peerPushCreditId, + id: TombstoneTag.DeletePeerPushCredit + ":" + peerPushCreditId, }); }); return; @@ -1682,11 +1678,7 @@ export async function deleteTransaction( case TransactionType.PeerPullCredit: { const pursePub = parsedTx.pursePub; await ws.db - .mktx((x) => [ - x.withdrawalGroups, - x.peerPullCredit, - x.tombstones, - ]) + .mktx((x) => [x.withdrawalGroups, x.peerPullCredit, x.tombstones]) .runReadWrite(async (tx) => { const pullIni = await tx.peerPullCredit.get(pursePub); if (!pullIni) { @@ -1813,9 +1805,7 @@ export async function deleteTransaction( await ws.db .mktx((x) => [x.peerPullDebit, x.tombstones]) .runReadWrite(async (tx) => { - const debit = await tx.peerPullDebit.get( - peerPullDebitId, - ); + const debit = await tx.peerPullDebit.get(peerPullDebitId); if (debit) { await tx.peerPullDebit.delete(peerPullDebitId); await tx.tombstones.put({ id: transactionId }); -- cgit v1.2.3 From 50b0b324ae67bea01079d6e9a1d684795f5b430f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 8 Sep 2023 12:26:58 +0200 Subject: wallet-core: put refresh sessions into own store --- packages/taler-wallet-core/src/db.ts | 27 +++-- .../taler-wallet-core/src/operations/balance.ts | 9 +- .../taler-wallet-core/src/operations/refresh.ts | 122 +++++++++++++-------- .../src/operations/transactions.ts | 2 +- 4 files changed, 100 insertions(+), 60 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 679ca2842..359569055 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -107,6 +107,8 @@ import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; full contract terms from the DB quite often. Instead, we should probably extract what we need into a separate object store. + - More object stores should have an "id" primary key, + as this makes referencing less expensive. */ /** @@ -943,9 +945,6 @@ export interface RefreshReasonDetails { export interface RefreshGroupRecord { operationStatus: RefreshOperationStatus; - // FIXME: Put this into a different object store? - lastErrorPerCoin: { [coinIndex: number]: TalerErrorDetail }; - /** * Unique, randomly generated identifier for this group of * refresh operations. @@ -969,13 +968,9 @@ export interface RefreshGroupRecord { oldCoinPubs: string[]; - // FIXME: Should this go into a separate - // object store for faster updates? - refreshSessionPerCoin: (RefreshSessionRecord | undefined)[]; - inputPerCoin: AmountString[]; - estimatedOutputPerCoin: AmountString[]; + expectedOutputPerCoin: AmountString[]; /** * Flag for each coin whether refreshing finished. @@ -997,6 +992,13 @@ export interface RefreshGroupRecord { * Ongoing refresh */ export interface RefreshSessionRecord { + refreshGroupId: string; + + /** + * Index of the coin in the refresh group. + */ + coinIndex: number; + /** * 512-bit secret that can be used to derive * the other cryptographic material for the refresh session. @@ -1021,6 +1023,8 @@ export interface RefreshSessionRecord { * The no-reveal-index after we've done the melting. */ norevealIndex?: number; + + lastError?: TalerErrorDetail; } export enum RefundReason { @@ -2372,6 +2376,13 @@ export const WalletStoresV1 = { byStatus: describeIndex("byStatus", "operationStatus"), }, ), + refreshSessions: describeStore( + "refreshSessions", + describeContents({ + keyPath: ["refreshGroupId", "coinIndex"], + }), + {}, + ), recoupGroups: describeStore( "recoupGroups", describeContents({ diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 287ac94fb..28aa5ac70 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -95,14 +95,7 @@ function computeRefreshGroupAvailableAmount(r: RefreshGroupRecord): AmountJson { return available; } for (let i = 0; i < r.oldCoinPubs.length; i++) { - const session = r.refreshSessionPerCoin[i]; - if (session) { - // We are always assuming the refresh will succeed, thus we - // report the output as available balance. - available = Amounts.add(available, session.amountRefreshOutput).amount; - } else { - available = Amounts.add(available, r.estimatedOutputPerCoin[i]).amount; - } + available = Amounts.add(available, r.expectedOutputPerCoin[i]).amount; } return available; } diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index fb356f0fc..3c4ef207a 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -76,7 +76,11 @@ import { RefreshReasonDetails, WalletStoresV1, } from "../db.js"; -import { isWithdrawableDenom, PendingTaskType } from "../index.js"; +import { + isWithdrawableDenom, + PendingTaskType, + RefreshSessionRecord, +} from "../index.js"; import { EXCHANGE_COINS_LOCK, InternalWalletState, @@ -170,18 +174,23 @@ function updateGroupStatus(rg: RefreshGroupRecord): { final: boolean } { /** * Create a refresh session for one particular coin inside a refresh group. + * + * If the session already exists, return the existing one. + * + * If the session doesn't need to be created (refresh group gone or session already + * finished), return undefined. */ -async function refreshCreateSession( +async function provideRefreshSession( ws: InternalWalletState, refreshGroupId: string, coinIndex: number, -): Promise { +): Promise { logger.trace( `creating refresh session for coin ${coinIndex} in refresh group ${refreshGroupId}`, ); const d = await ws.db - .mktx((x) => [x.refreshGroups, x.coins]) + .mktx((x) => [x.refreshGroups, x.coins, x.refreshSessions]) .runReadWrite(async (tx) => { const refreshGroup = await tx.refreshGroups.get(refreshGroupId); if (!refreshGroup) { @@ -192,21 +201,24 @@ async function refreshCreateSession( ) { return; } - const existingRefreshSession = - refreshGroup.refreshSessionPerCoin[coinIndex]; - if (existingRefreshSession) { - return; - } + const existingRefreshSession = await tx.refreshSessions.get([ + refreshGroupId, + coinIndex, + ]); const oldCoinPub = refreshGroup.oldCoinPubs[coinIndex]; const coin = await tx.coins.get(oldCoinPub); if (!coin) { throw Error("Can't refresh, coin not found"); } - return { refreshGroup, coin }; + return { refreshGroup, coin, existingRefreshSession }; }); if (!d) { - return; + return undefined; + } + + if (d.existingRefreshSession) { + return d.existingRefreshSession; } const { refreshGroup, coin } = d; @@ -288,17 +300,23 @@ async function refreshCreateSession( const sessionSecretSeed = encodeCrock(getRandomBytes(64)); // Store refresh session for this coin in the database. - await ws.db - .mktx((x) => [x.refreshGroups, x.coins]) + const newSession = await ws.db + .mktx((x) => [x.refreshGroups, x.coins, x.refreshSessions]) .runReadWrite(async (tx) => { const rg = await tx.refreshGroups.get(refreshGroupId); if (!rg) { return; } - if (rg.refreshSessionPerCoin[coinIndex]) { + const existingSession = await tx.refreshSessions.get([ + refreshGroupId, + coinIndex, + ]); + if (existingSession) { return; } - rg.refreshSessionPerCoin[coinIndex] = { + const newSession: RefreshSessionRecord = { + coinIndex, + refreshGroupId, norevealIndex: undefined, sessionSecretSeed: sessionSecretSeed, newDenoms: newCoinDenoms.selectedDenoms.map((x) => ({ @@ -307,11 +325,13 @@ async function refreshCreateSession( })), amountRefreshOutput: Amounts.stringify(newCoinDenoms.totalCoinValue), }; - await tx.refreshGroups.put(rg); + await tx.refreshSessions.put(newSession); + return newSession; }); logger.trace( `created refresh session for coin #${coinIndex} in ${refreshGroupId}`, ); + return newSession; } function getRefreshRequestTimeout(rg: RefreshGroupRecord): Duration { @@ -326,13 +346,16 @@ async function refreshMelt( coinIndex: number, ): Promise { const d = await ws.db - .mktx((x) => [x.refreshGroups, x.coins, x.denominations]) + .mktx((x) => [x.refreshGroups, x.refreshSessions, x.coins, x.denominations]) .runReadWrite(async (tx) => { const refreshGroup = await tx.refreshGroups.get(refreshGroupId); if (!refreshGroup) { return; } - const refreshSession = refreshGroup.refreshSessionPerCoin[coinIndex]; + const refreshSession = await tx.refreshSessions.get([ + refreshGroupId, + coinIndex, + ]); if (!refreshSession) { return; } @@ -442,7 +465,12 @@ async function refreshMelt( if (resp.status === HttpStatusCode.NotFound) { const errDetails = await readUnexpectedResponseDetails(resp); const transitionInfo = await ws.db - .mktx((x) => [x.refreshGroups, x.coins, x.coinAvailability]) + .mktx((x) => [ + x.refreshGroups, + x.refreshSessions, + x.coins, + x.coinAvailability, + ]) .runReadWrite(async (tx) => { const rg = await tx.refreshGroups.get(refreshGroupId); if (!rg) { @@ -456,12 +484,22 @@ async function refreshMelt( } const oldTxState = computeRefreshTransactionState(rg); rg.statusPerCoin[coinIndex] = RefreshCoinStatus.Failed; - rg.lastErrorPerCoin[coinIndex] = errDetails; + const refreshSession = await tx.refreshSessions.get([ + refreshGroupId, + coinIndex, + ]); + if (!refreshSession) { + throw Error( + "db invariant failed: missing refresh session in database", + ); + } + refreshSession.lastError = errDetails; const updateRes = updateGroupStatus(rg); if (updateRes.final) { await makeCoinsVisible(ws, tx, transactionId); } await tx.refreshGroups.put(rg); + await tx.refreshSessions.put(refreshSession); const newTxState = computeRefreshTransactionState(rg); return { oldTxState, @@ -493,7 +531,7 @@ async function refreshMelt( refreshSession.norevealIndex = norevealIndex; await ws.db - .mktx((x) => [x.refreshGroups]) + .mktx((x) => [x.refreshGroups, x.refreshSessions]) .runReadWrite(async (tx) => { const rg = await tx.refreshGroups.get(refreshGroupId); if (!rg) { @@ -502,7 +540,7 @@ async function refreshMelt( if (rg.timestampFinished) { return; } - const rs = rg.refreshSessionPerCoin[coinIndex]; + const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]); if (!rs) { return; } @@ -510,7 +548,7 @@ async function refreshMelt( return; } rs.norevealIndex = norevealIndex; - await tx.refreshGroups.put(rg); + await tx.refreshSessions.put(rs); }); } @@ -581,13 +619,16 @@ async function refreshReveal( `doing refresh reveal for ${refreshGroupId} (old coin ${coinIndex})`, ); const d = await ws.db - .mktx((x) => [x.refreshGroups, x.coins, x.denominations]) + .mktx((x) => [x.refreshGroups, x.refreshSessions, x.coins, x.denominations]) .runReadOnly(async (tx) => { const refreshGroup = await tx.refreshGroups.get(refreshGroupId); if (!refreshGroup) { return; } - const refreshSession = refreshGroup.refreshSessionPerCoin[coinIndex]; + const refreshSession = await tx.refreshSessions.get([ + refreshGroupId, + coinIndex, + ]); if (!refreshSession) { return; } @@ -755,6 +796,7 @@ async function refreshReveal( x.denominations, x.coinAvailability, x.refreshGroups, + x.refreshSessions, ]) .runReadWrite(async (tx) => { const rg = await tx.refreshGroups.get(refreshGroupId); @@ -762,7 +804,7 @@ async function refreshReveal( logger.warn("no refresh session found"); return; } - const rs = rg.refreshSessionPerCoin[coinIndex]; + const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]); if (!rs) { return; } @@ -858,10 +900,15 @@ async function processRefreshSession( logger.trace( `processing refresh session for coin ${coinIndex} of group ${refreshGroupId}`, ); - let refreshGroup = await ws.db - .mktx((x) => [x.refreshGroups]) + let { refreshGroup, refreshSession } = await ws.db + .mktx((x) => [x.refreshGroups, x.refreshSessions]) .runReadOnly(async (tx) => { - return tx.refreshGroups.get(refreshGroupId); + const rg = await tx.refreshGroups.get(refreshGroupId); + const rs = await tx.refreshSessions.get([refreshGroupId, coinIndex]); + return { + refreshGroup: rg, + refreshSession: rs, + }; }); if (!refreshGroup) { return; @@ -869,18 +916,9 @@ async function processRefreshSession( if (refreshGroup.statusPerCoin[coinIndex] === RefreshCoinStatus.Finished) { return; } - if (!refreshGroup.refreshSessionPerCoin[coinIndex]) { - await refreshCreateSession(ws, refreshGroupId, coinIndex); - refreshGroup = await ws.db - .mktx((x) => [x.refreshGroups]) - .runReadOnly(async (tx) => { - return tx.refreshGroups.get(refreshGroupId); - }); - if (!refreshGroup) { - return; - } + if (!refreshSession) { + refreshSession = await provideRefreshSession(ws, refreshGroupId, coinIndex); } - const refreshSession = refreshGroup.refreshSessionPerCoin[coinIndex]; if (!refreshSession) { if (refreshGroup.statusPerCoin[coinIndex] !== RefreshCoinStatus.Finished) { throw Error( @@ -1058,13 +1096,11 @@ export async function createRefreshGroup( timestampFinished: undefined, statusPerCoin: oldCoinPubs.map(() => RefreshCoinStatus.Pending), oldCoinPubs: oldCoinPubs.map((x) => x.coinPub), - lastErrorPerCoin: {}, reasonDetails, reason, refreshGroupId, - refreshSessionPerCoin: oldCoinPubs.map(() => undefined), inputPerCoin: oldCoinPubs.map((x) => x.amount), - estimatedOutputPerCoin: estimatedOutputPerCoin.map((x) => + expectedOutputPerCoin: estimatedOutputPerCoin.map((x) => Amounts.stringify(x), ), timestampCreated: TalerPreciseTimestamp.now(), diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index ff9fbf57a..8db68e0f1 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -760,7 +760,7 @@ function buildTransactionForRefresh( ).amount; const outputAmount = Amounts.sumOrZero( refreshGroupRecord.currency, - refreshGroupRecord.estimatedOutputPerCoin, + refreshGroupRecord.expectedOutputPerCoin, ).amount; return { type: TransactionType.Refresh, -- cgit v1.2.3 From 2ae952cdfa8f38a650be8e4438c21bace2f24c19 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 8 Sep 2023 12:54:31 +0200 Subject: wallet-core: remove redundant deposit status field in DB --- packages/taler-wallet-core/src/db.ts | 17 ++++----- .../taler-wallet-core/src/operations/deposits.ts | 41 ++++++++++++---------- .../taler-wallet-core/src/operations/pending.ts | 21 ++++------- .../src/operations/transactions.ts | 10 +++--- 4 files changed, 41 insertions(+), 48 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 359569055..3db7ae9b5 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -921,8 +921,11 @@ export enum RefreshOperationStatus { * Status of a single element of a deposit group. */ export enum DepositElementStatus { - Unknown = 0x0100_0000, - Accepted = 0x0100_0001, + DepositPending = 0x0100_0000, + /** + * Accepted, but tracking. + */ + Tracking = 0x0100_0001, KycRequired = 0x0100_0002, Wired = 0x0500_0000, RefundSuccess = 0x0503_0000, @@ -1723,10 +1726,8 @@ export interface DepositGroupRecord { /** * The counterparty effective deposit amount. - * - * FIXME: If possible, rename to counterpartyEffectiveDepositAmount. */ - effectiveDepositAmount: AmountString; + counterpartyEffectiveDepositAmount: AmountString; timestampCreated: TalerPreciseTimestamp; @@ -1734,11 +1735,7 @@ export interface DepositGroupRecord { operationStatus: DepositOperationStatus; - // FIXME: Duplication between this and transactionPerCoin! - depositedPerCoin: boolean[]; - - // FIXME: Improve name! - transactionPerCoin: DepositElementStatus[]; + statusPerCoin: DepositElementStatus[]; /** * When the deposit transaction was aborted and diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index a8ec859cf..3d78e938b 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -510,10 +510,10 @@ async function refundDepositGroup( ws: InternalWalletState, depositGroup: DepositGroupRecord, ): Promise { - const newTxPerCoin = [...depositGroup.transactionPerCoin]; - logger.info(`status per coin: ${j2s(depositGroup.transactionPerCoin)}`); - for (let i = 0; i < depositGroup.transactionPerCoin.length; i++) { - const st = depositGroup.transactionPerCoin[i]; + const newTxPerCoin = [...depositGroup.statusPerCoin]; + logger.info(`status per coin: ${j2s(depositGroup.statusPerCoin)}`); + for (let i = 0; i < depositGroup.statusPerCoin.length; i++) { + const st = depositGroup.statusPerCoin[i]; switch (st) { case DepositElementStatus.RefundFailed: case DepositElementStatus.RefundSuccess: @@ -593,7 +593,7 @@ async function refundDepositGroup( if (!newDg) { return; } - newDg.transactionPerCoin = newTxPerCoin; + newDg.statusPerCoin = newTxPerCoin; const refreshCoins: CoinRefreshRequest[] = []; for (let i = 0; i < newTxPerCoin.length; i++) { refreshCoins.push({ @@ -766,7 +766,7 @@ async function processDepositGroupPendingTrack( cancellationToken?: CancellationToken, ): Promise { const { depositGroupId } = depositGroup; - for (let i = 0; i < depositGroup.depositedPerCoin.length; i++) { + for (let i = 0; i < depositGroup.statusPerCoin.length; i++) { const coinPub = depositGroup.payCoinSelection.coinPubs[i]; // FIXME: Make the URL part of the coin selection? const exchangeBaseUrl = await ws.db @@ -785,7 +785,7 @@ async function processDepositGroupPendingTrack( } | undefined; - if (depositGroup.transactionPerCoin[i] !== DepositElementStatus.Wired) { + if (depositGroup.statusPerCoin[i] !== DepositElementStatus.Wired) { const track = await trackDeposit( ws, depositGroup, @@ -810,7 +810,7 @@ async function processDepositGroupPendingTrack( exchangeBaseUrl, ); } else { - updatedTxStatus = DepositElementStatus.Accepted; + updatedTxStatus = DepositElementStatus.Tracking; } } else if (track.type === "wired") { updatedTxStatus = DepositElementStatus.Wired; @@ -840,7 +840,7 @@ async function processDepositGroupPendingTrack( id: track.exchange_sig, }; } else { - updatedTxStatus = DepositElementStatus.Unknown; + updatedTxStatus = DepositElementStatus.DepositPending; } } @@ -853,7 +853,7 @@ async function processDepositGroupPendingTrack( return; } if (updatedTxStatus !== undefined) { - dg.transactionPerCoin[i] = updatedTxStatus; + dg.statusPerCoin[i] = updatedTxStatus; } if (newWiredCoin) { /** @@ -885,8 +885,8 @@ async function processDepositGroupPendingTrack( return undefined; } const oldTxState = computeDepositTransactionStatus(dg); - for (let i = 0; i < depositGroup.depositedPerCoin.length; i++) { - if (depositGroup.transactionPerCoin[i] !== DepositElementStatus.Wired) { + for (let i = 0; i < depositGroup.statusPerCoin.length; i++) { + if (depositGroup.statusPerCoin[i] !== DepositElementStatus.Wired) { allWired = false; break; } @@ -943,7 +943,7 @@ async function processDepositGroupPendingDeposit( for (let i = 0; i < depositPermissions.length; i++) { const perm = depositPermissions[i]; - if (depositGroup.depositedPerCoin[i]) { + if (depositGroup.statusPerCoin[i] !== DepositElementStatus.DepositPending) { continue; } @@ -980,8 +980,12 @@ async function processDepositGroupPendingDeposit( if (!dg) { return; } - dg.depositedPerCoin[i] = true; - await tx.depositGroups.put(dg); + const coinStatus = dg.statusPerCoin[i]; + switch (coinStatus) { + case DepositElementStatus.DepositPending: + dg.statusPerCoin[i] = DepositElementStatus.Tracking; + await tx.depositGroups.put(dg); + } }); } @@ -1373,16 +1377,15 @@ export async function createDepositGroup( noncePub: noncePair.pub, timestampCreated: AbsoluteTime.toPreciseTimestamp(now), timestampFinished: undefined, - transactionPerCoin: payCoinSel.coinSel.coinPubs.map( - () => DepositElementStatus.Unknown, + statusPerCoin: payCoinSel.coinSel.coinPubs.map( + () => DepositElementStatus.DepositPending, ), payCoinSelection: payCoinSel.coinSel, payCoinSelectionUid: encodeCrock(getRandomBytes(32)), - depositedPerCoin: payCoinSel.coinSel.coinPubs.map(() => false), merchantPriv: merchantPair.priv, merchantPub: merchantPair.pub, totalPayCost: Amounts.stringify(totalDepositCost), - effectiveDepositAmount: Amounts.stringify( + counterpartyEffectiveDepositAmount: Amounts.stringify( counterpartyEffectiveDepositAmount, ), wire: { diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 207e6ffda..6115f848b 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -46,6 +46,7 @@ import { RefundGroupStatus, ExchangeEntryDbUpdateStatus, RefreshOperationStatus, + DepositElementStatus, } from "../db.js"; import { PendingOperationsResponse, @@ -277,8 +278,8 @@ async function gatherDepositPending( ): Promise { await iterRecordsForDeposit(tx, { onlyState: "nonfinal" }, async (dg) => { let deposited = true; - for (const d of dg.depositedPerCoin) { - if (!d) { + for (const d of dg.statusPerCoin) { + if (d === DepositElementStatus.DepositPending) { deposited = false; } } @@ -480,9 +481,7 @@ export async function iterRecordsForPeerPullInitiation( PeerPullPaymentCreditStatus.PendingCreatePurse, PeerPullPaymentCreditStatus.AbortingDeletePurse, ); - await tx.peerPullCredit.indexes.byStatus - .iter(keyRange) - .forEachAsync(f); + await tx.peerPullCredit.indexes.byStatus.iter(keyRange).forEachAsync(f); } else { await tx.peerPullCredit.indexes.byStatus.iter().forEachAsync(f); } @@ -528,9 +527,7 @@ export async function iterRecordsForPeerPullDebit( PeerPullDebitRecordStatus.PendingDeposit, PeerPullDebitRecordStatus.AbortingRefresh, ); - await tx.peerPullDebit.indexes.byStatus - .iter(keyRange) - .forEachAsync(f); + await tx.peerPullDebit.indexes.byStatus.iter(keyRange).forEachAsync(f); } else { await tx.peerPullDebit.indexes.byStatus.iter().forEachAsync(f); } @@ -576,9 +573,7 @@ export async function iterRecordsForPeerPushInitiation( PeerPushDebitStatus.PendingCreatePurse, PeerPushDebitStatus.AbortingRefresh, ); - await tx.peerPushDebit.indexes.byStatus - .iter(keyRange) - .forEachAsync(f); + await tx.peerPushDebit.indexes.byStatus.iter(keyRange).forEachAsync(f); } else { await tx.peerPushDebit.indexes.byStatus.iter().forEachAsync(f); } @@ -624,9 +619,7 @@ export async function iterRecordsForPeerPushCredit( PeerPushCreditStatus.PendingMerge, PeerPushCreditStatus.PendingWithdrawing, ); - await tx.peerPushCredit.indexes.byStatus - .iter(keyRange) - .forEachAsync(f); + await tx.peerPushCredit.indexes.byStatus.iter(keyRange).forEachAsync(f); } else { await tx.peerPushCredit.indexes.byStatus.iter().forEachAsync(f); } diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 8db68e0f1..9d5ca9f1a 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -791,8 +791,8 @@ function buildTransactionForDeposit( ort?: OperationRetryRecord, ): Transaction { let deposited = true; - for (const d of dg.depositedPerCoin) { - if (!d) { + for (const d of dg.statusPerCoin) { + if (d == DepositElementStatus.DepositPending) { deposited = false; } } @@ -801,7 +801,7 @@ function buildTransactionForDeposit( type: TransactionType.Deposit, txState: computeDepositTransactionStatus(dg), txActions: computeDepositTransactionActions(dg), - amountRaw: Amounts.stringify(dg.effectiveDepositAmount), + amountRaw: Amounts.stringify(dg.counterpartyEffectiveDepositAmount), amountEffective: Amounts.stringify(dg.totalPayCost), timestamp: dg.timestampCreated, targetPaytoUri: dg.wire.payto_uri, @@ -812,11 +812,11 @@ function buildTransactionForDeposit( }), wireTransferProgress: (100 * - dg.transactionPerCoin.reduce( + dg.statusPerCoin.reduce( (prev, cur) => prev + (cur === DepositElementStatus.Wired ? 1 : 0), 0, )) / - dg.transactionPerCoin.length, + dg.statusPerCoin.length, depositGroupId: dg.depositGroupId, trackingState: Object.values(dg.trackingState ?? {}), deposited, -- cgit v1.2.3 From 4898f50db777a68cd2ddd0c1e323ef55033f4af7 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 8 Sep 2023 13:33:21 +0200 Subject: wallet-core: more DB cleanup --- packages/taler-util/src/transactions-types.ts | 17 ------ .../src/crypto/cryptoImplementation.ts | 6 +-- packages/taler-wallet-core/src/db.ts | 63 +++++++++------------- packages/taler-wallet-core/src/dbless.ts | 18 ++----- .../taler-wallet-core/src/operations/balance.ts | 18 ++----- .../taler-wallet-core/src/operations/common.ts | 27 +++++----- .../taler-wallet-core/src/operations/deposits.ts | 2 +- .../taler-wallet-core/src/operations/exchanges.ts | 3 +- .../src/operations/pay-merchant.ts | 4 +- .../src/operations/pay-peer-common.ts | 12 +---- .../taler-wallet-core/src/operations/refresh.ts | 12 +---- .../src/operations/transactions.ts | 1 - .../src/operations/withdraw.test.ts | 22 ++++---- .../taler-wallet-core/src/util/coinSelection.ts | 30 +++-------- .../src/util/instructedAmountConversion.ts | 2 +- packages/taler-wallet-core/src/wallet.ts | 22 ++------ 16 files changed, 77 insertions(+), 182 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-util/src/transactions-types.ts b/packages/taler-util/src/transactions-types.ts index 6331bc731..304183ceb 100644 --- a/packages/taler-util/src/transactions-types.ts +++ b/packages/taler-util/src/transactions-types.ts @@ -527,22 +527,6 @@ export interface OrderShortInfo { */ summary_i18n?: InternationalizedString; - /** - * List of products that are part of the order - */ - products: Product[] | undefined; - - /** - * Time indicating when the order should be delivered. - * May be overwritten by individual products. - */ - delivery_date?: TalerProtocolTimestamp; - - /** - * Delivery location for (all!) products. - */ - delivery_location?: Location; - /** * URL of the fulfillment, given by the merchant */ @@ -724,7 +708,6 @@ export const codecForOrderShortInfo = (): Codec => .property("fulfillmentUrl", codecOptional(codecForString())) .property("merchant", codecForMerchantInfo()) .property("orderId", codecForString()) - .property("products", codecOptional(codecForList(codecForProduct()))) .property("summary", codecForString()) .property("summary_i18n", codecOptional(codecForInternationalizedString())) .build("OrderShortInfo"); diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index c1a761fb6..35777e714 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -959,11 +959,7 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { req: DenominationValidationRequest, ): Promise { const { masterPub, denom } = req; - const value: AmountJson = { - currency: denom.currency, - fraction: denom.amountFrac, - value: denom.amountVal, - }; + const value: AmountJson = Amounts.parseOrThrow(denom.value); const p = buildSigPS(TalerSignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY) .put(decodeCrock(masterPub)) .put(timestampRoundedToBuffer(denom.stampStart)) diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 3db7ae9b5..3a8109320 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -28,56 +28,53 @@ import { } from "@gnu-taler/idb-bridge"; import { AgeCommitmentProof, - AmountJson, AmountString, + Amounts, + AttentionInfo, + Codec, CoinEnvelope, + CoinPublicKeyString, CoinRefreshRequest, CoinStatus, - MerchantContractTerms, + DenomSelectionState, DenominationInfo, DenominationPubKey, - DenomSelectionState, EddsaPublicKeyString, EddsaSignatureString, ExchangeAuditor, ExchangeGlobalFees, + HashCodeString, InternationalizedString, - Location, + Logger, + MerchantContractTerms, MerchantInfo, PayCoinSelection, PeerContractTerms, - Product, RefreshReason, TalerErrorDetail, + TalerPreciseTimestamp, TalerProtocolDuration, TalerProtocolTimestamp, TransactionIdStr, UnblindedSignature, WireInfo, - HashCodeString, - Amounts, - AttentionInfo, - Logger, - CoinPublicKeyString, - TalerPreciseTimestamp, codecForAny, - Codec, } from "@gnu-taler/taler-util"; +import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; import { DbAccess, DbReadOnlyTransaction, DbReadWriteTransaction, - describeContents, - describeIndex, - describeStore, GetReadWriteAccess, IndexDescriptor, - openDatabase, StoreDescriptor, StoreNames, StoreWithIndexes, + describeContents, + describeIndex, + describeStore, + openDatabase, } from "./util/query.js"; -import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; /** * This file contains the database schema of the Taler wallet together @@ -109,6 +106,9 @@ import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; store. - More object stores should have an "id" primary key, as this makes referencing less expensive. + - Coin selections should probably go into a separate object store. + - Some records should be split up into an extra "details" record + that we don't always need to iterate over. */ /** @@ -323,12 +323,14 @@ export interface DenomFees { * Denomination record as stored in the wallet's database. */ export interface DenominationRecord { + /** + * Currency of the denomination. + * + * Stored separately as we have an index on it. + */ currency: string; - // FIXME: Use binary encoding of amount instead? - amountVal: number; - - amountFrac: number; + value: AmountString; /** * The denomination public key. @@ -407,14 +409,6 @@ export interface DenominationRecord { } export namespace DenominationRecord { - export function getValue(d: DenominationRecord): AmountJson { - return { - currency: d.currency, - fraction: d.amountFrac, - value: d.amountVal, - }; - } - export function toDenomInfo(d: DenominationRecord): DenominationInfo { return { denomPub: d.denomPub, @@ -427,7 +421,7 @@ export namespace DenominationRecord { stampExpireLegal: d.stampExpireLegal, stampExpireWithdraw: d.stampExpireWithdraw, stampStart: d.stampStart, - value: Amounts.stringify(DenominationRecord.getValue(d)), + value: Amounts.stringify(d.value), exchangeBaseUrl: d.exchangeBaseUrl, }; } @@ -1056,9 +1050,6 @@ export interface AllowedExchangeInfo { * processing in the wallet. */ export interface WalletContractData { - products?: Product[]; - summaryI18n: { [lang_tag: string]: string } | undefined; - /** * Fulfillment URL, or the empty string if the order has no fulfillment URL. * @@ -1076,6 +1067,7 @@ export interface WalletContractData { orderId: string; merchantBaseUrl: string; summary: string; + summaryI18n: { [lang_tag: string]: string } | undefined; autoRefund: TalerProtocolDuration | undefined; maxWireFee: AmountString; wireFeeAmortization: number; @@ -1087,8 +1079,6 @@ export interface WalletContractData { wireInfoHash: string; maxDepositFee: AmountString; minimumAge?: number; - deliveryDate: TalerProtocolTimestamp | undefined; - deliveryLocation: Location | undefined; } export enum PurchaseStatus { @@ -2095,8 +2085,7 @@ export interface OperationRetryRecord { */ export interface CoinAvailabilityRecord { currency: string; - amountVal: number; - amountFrac: number; + value: AmountString; denomPubHash: string; exchangeBaseUrl: string; diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 0aad477e4..11c6c0f74 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -159,11 +159,7 @@ export async function withdrawCoin(args: { reservePriv: reserveKeyPair.reservePriv, reservePub: reserveKeyPair.reservePub, secretSeed: encodeCrock(getRandomBytes(32)), - value: { - currency: denom.currency, - fraction: denom.amountFrac, - value: denom.amountVal, - }, + value: Amounts.parseOrThrow(denom.value), }); const reqBody: ExchangeWithdrawRequest = { @@ -211,11 +207,7 @@ export function findDenomOrThrow( ): DenominationRecord { const denomselAllowLate = options.denomselAllowLate ?? false; for (const d of exchangeInfo.keys.currentDenominations) { - const value: AmountJson = { - currency: d.currency, - fraction: d.amountFrac, - value: d.amountVal, - }; + const value: AmountJson = Amounts.parseOrThrow(d.value); if ( Amounts.cmp(value, amount) === 0 && isWithdrawableDenom(d, denomselAllowLate) @@ -303,11 +295,7 @@ export async function refreshCoin(req: { denomPub: x.denomPub, denomPubHash: x.denomPubHash, feeWithdraw: x.fees.feeWithdraw, - value: Amounts.stringify({ - currency: x.currency, - fraction: x.amountFrac, - value: x.amountVal, - }), + value: x.value, })), meltCoinMaxAge: oldCoin.maxAge, }); diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 28aa5ac70..a20ded2af 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -133,11 +133,7 @@ export async function getBalancesInsideTransaction( const b = initBalance(ca.currency); const count = ca.visibleCoinCount ?? 0; for (let i = 0; i < count; i++) { - b.available = Amounts.add(b.available, { - currency: ca.currency, - fraction: ca.amountFrac, - value: ca.amountVal, - }).amount; + b.available = Amounts.add(b.available, ca.value).amount; } }); @@ -408,11 +404,7 @@ export async function getMerchantPaymentBalanceDetails( if (ca.currency != req.currency) { return; } - const singleCoinAmount: AmountJson = { - currency: ca.currency, - fraction: ca.amountFrac, - value: ca.amountVal, - }; + const singleCoinAmount: AmountJson = Amounts.parseOrThrow(ca.value); const coinAmount: AmountJson = Amounts.mult( singleCoinAmount, ca.freshCoinCount, @@ -530,11 +522,7 @@ export async function getPeerPaymentBalanceDetailsInTx( ) { return; } - const singleCoinAmount: AmountJson = { - currency: ca.currency, - fraction: ca.amountFrac, - value: ca.amountVal, - }; + const singleCoinAmount: AmountJson = Amounts.parseOrThrow(ca.value); const coinAmount: AmountJson = Amounts.mult( singleCoinAmount, ca.freshCoinCount, diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 680874dfa..50dd3dc5c 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -26,7 +26,6 @@ import { CoinRefreshRequest, CoinStatus, Duration, - ErrorInfoSummary, ExchangeEntryStatus, ExchangeListItem, ExchangeTosStatus, @@ -34,9 +33,11 @@ import { getErrorDetailFromException, j2s, Logger, + makeErrorDetail, NotificationType, OperationErrorInfo, RefreshReason, + TalerError, TalerErrorCode, TalerErrorDetail, TombstoneIdStr, @@ -44,32 +45,31 @@ import { TransactionType, WalletNotification, } from "@gnu-taler/taler-util"; +import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; import { - WalletStoresV1, + BackupProviderRecord, CoinRecord, + DepositGroupRecord, ExchangeDetailsRecord, + ExchangeEntryDbRecordStatus, + ExchangeEntryDbUpdateStatus, ExchangeEntryRecord, - BackupProviderRecord, - DepositGroupRecord, - PeerPullPaymentIncomingRecord, PeerPullCreditRecord, - PeerPushPaymentIncomingRecord, + PeerPullPaymentIncomingRecord, PeerPushDebitRecord, + PeerPushPaymentIncomingRecord, PurchaseRecord, RecoupGroupRecord, RefreshGroupRecord, RewardRecord, + WalletStoresV1, WithdrawalGroupRecord, - ExchangeEntryDbUpdateStatus, - ExchangeEntryDbRecordStatus, } from "../db.js"; -import { makeErrorDetail, TalerError } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; -import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js"; -import { GetReadOnlyAccess, GetReadWriteAccess } from "../util/query.js"; -import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; import { PendingTaskType, TaskId } from "../pending-types.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; +import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js"; +import { GetReadOnlyAccess, GetReadWriteAccess } from "../util/query.js"; import { constructTransactionIdentifier } from "./transactions.js"; const logger = new Logger("operations/common.ts"); @@ -144,8 +144,7 @@ export async function makeCoinAvailable( if (!car) { car = { maxAge: ageRestriction, - amountFrac: denom.amountFrac, - amountVal: denom.amountVal, + value: denom.value, currency: denom.currency, denomPubHash: denom.denomPubHash, exchangeBaseUrl: denom.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index 3d78e938b..8ea792d91 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -1539,7 +1539,7 @@ async function getTotalFeesForDepositAmount( .iter(coin.exchangeBaseUrl) .filter((x) => Amounts.isSameCurrency( - DenominationRecord.getValue(x), + x.value, pcs.coinContributions[i], ), ); diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 13e89b16c..43a08ed3b 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -443,8 +443,7 @@ async function downloadExchangeKeysInfo( exchangeMasterPub: exchangeKeysJsonUnchecked.master_public_key, isOffered: true, isRevoked: false, - amountFrac: value.fraction, - amountVal: value.value, + value: Amounts.stringify(value), currency: value.currency, stampExpireDeposit: denomIn.stamp_expire_deposit, stampExpireLegal: denomIn.stamp_expire_legal, diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 1b3248f49..3a7208ab0 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -174,12 +174,12 @@ export async function getTotalPaymentCost( .iter(coin.exchangeBaseUrl) .filter((x) => Amounts.isSameCurrency( - DenominationRecord.getValue(x), + x.value, pcs.coinContributions[i], ), ); const amountLeft = Amounts.sub( - DenominationRecord.getValue(denom), + denom.value, pcs.coinContributions[i], ).amount; const refreshCost = getTotalRefreshCost( diff --git a/packages/taler-wallet-core/src/operations/pay-peer-common.ts b/packages/taler-wallet-core/src/operations/pay-peer-common.ts index 9e05e43d8..6d425289d 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-common.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-common.ts @@ -108,16 +108,8 @@ export async function getTotalPeerPaymentCost( } const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl .iter(coin.exchangeBaseUrl) - .filter((x) => - Amounts.isSameCurrency( - DenominationRecord.getValue(x), - pcs[i].contribution, - ), - ); - const amountLeft = Amounts.sub( - DenominationRecord.getValue(denom), - pcs[i].contribution, - ).amount; + .filter((x) => Amounts.isSameCurrency(x.value, pcs[i].contribution)); + const amountLeft = Amounts.sub(denom.value, pcs[i].contribution).amount; const refreshCost = getTotalRefreshCost( allDenoms, DenominationRecord.toDenomInfo(denom), diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 3c4ef207a..75adbc860 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -134,11 +134,7 @@ export function getTotalRefreshCost( const resultingAmount = Amounts.add( Amounts.zeroOfCurrency(withdrawAmount.currency), ...withdrawDenoms.selectedDenoms.map( - (d) => - Amounts.mult( - DenominationRecord.getValue(denomMap[d.denomPubHash]), - d.count, - ).amount, + (d) => Amounts.mult(denomMap[d.denomPubHash].value, d.count).amount, ), ).amount; const totalCost = Amounts.sub(amountLeft, resultingAmount).amount; @@ -1200,11 +1196,7 @@ export async function autoRefresh( if (AbsoluteTime.isExpired(executeThreshold)) { refreshCoins.push({ coinPub: coin.coinPub, - amount: Amounts.stringify({ - value: denom.amountVal, - fraction: denom.amountFrac, - currency: denom.currency, - }), + amount: denom.value, }); } else { const checkThreshold = getAutoRefreshCheckThreshold(denom); diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 9d5ca9f1a..7bdb9af5b 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -884,7 +884,6 @@ async function buildTransactionForPurchase( const info: OrderShortInfo = { merchant: contractData.merchant, orderId: contractData.orderId, - products: contractData.products, summary: contractData.summary, summary_i18n: contractData.summaryI18n, contractTermsHash: contractData.contractTermsHash, diff --git a/packages/taler-wallet-core/src/operations/withdraw.test.ts b/packages/taler-wallet-core/src/operations/withdraw.test.ts index 5a557b5de..2d9286610 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.test.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.test.ts @@ -78,8 +78,7 @@ test("withdrawal selection bug repro", (t) => { }, verificationStatus: DenominationVerificationStatus.Unverified, currency: "KUDOS", - amountFrac: 0, - amountVal: 1000, + value: "KUDOS:1000", listIssueDate: { t_s: 0 }, }, { @@ -133,8 +132,7 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - amountFrac: 0, - amountVal: 10, + value: "KUDOS:10", currency: "KUDOS", listIssueDate: { t_s: 0 }, }, @@ -188,8 +186,7 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - amountFrac: 0, - amountVal: 5, + value: "KUDOS:5", currency: "KUDOS", listIssueDate: { t_s: 0 }, }, @@ -244,8 +241,7 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - amountFrac: 0, - amountVal: 1, + value: "KUDOS:1", currency: "KUDOS", listIssueDate: { t_s: 0 }, }, @@ -299,8 +295,11 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - amountFrac: 10000000, - amountVal: 0, + value: Amounts.stringify({ + currency: "KUDOS", + fraction: 10000000, + value: 0, + }), currency: "KUDOS", listIssueDate: { t_s: 0 }, }, @@ -354,8 +353,7 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - amountFrac: 0, - amountVal: 2, + value: "KUDOS:2", currency: "KUDOS", listIssueDate: { t_s: 0 }, }, diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts index ce9fec186..ef2f85789 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.ts @@ -699,25 +699,17 @@ export function selectWithdrawalDenominations( let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency); denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate)); - denoms.sort((d1, d2) => - Amounts.cmp( - DenominationRecord.getValue(d2), - DenominationRecord.getValue(d1), - ), - ); + denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value)); for (const d of denoms) { - const cost = Amounts.add( - DenominationRecord.getValue(d), - d.fees.feeWithdraw, - ).amount; + const cost = Amounts.add(d.value, d.fees.feeWithdraw).amount; const res = Amounts.divmod(remaining, cost); const count = res.quotient; remaining = Amounts.sub(remaining, Amounts.mult(cost, count).amount).amount; if (count > 0) { totalCoinValue = Amounts.add( totalCoinValue, - Amounts.mult(DenominationRecord.getValue(d), count).amount, + Amounts.mult(d.value, count).amount, ).amount; totalWithdrawCost = Amounts.add( totalWithdrawCost, @@ -766,30 +758,22 @@ export function selectForcedWithdrawalDenominations( let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency); denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate)); - denoms.sort((d1, d2) => - Amounts.cmp( - DenominationRecord.getValue(d2), - DenominationRecord.getValue(d1), - ), - ); + denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value)); for (const fds of forcedDenomSel.denoms) { const count = fds.count; const denom = denoms.find((x) => { - return Amounts.cmp(DenominationRecord.getValue(x), fds.value) == 0; + return Amounts.cmp(x.value, fds.value) == 0; }); if (!denom) { throw Error( `unable to find denom for forced selection (value ${fds.value})`, ); } - const cost = Amounts.add( - DenominationRecord.getValue(denom), - denom.fees.feeWithdraw, - ).amount; + const cost = Amounts.add(denom.value, denom.fees.feeWithdraw).amount; totalCoinValue = Amounts.add( totalCoinValue, - Amounts.mult(DenominationRecord.getValue(denom), count).amount, + Amounts.mult(denom.value, count).amount, ).amount; totalWithdrawCost = Amounts.add( totalWithdrawCost, diff --git a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts index bd02e7b22..54c08eee4 100644 --- a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts +++ b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts @@ -321,7 +321,7 @@ function buildCoinInfoFromDenom( AbsoluteTime.fromProtocolTimestamp(denom.stampExpireDeposit), ), totalAvailable: total, - value: DenominationRecord.getValue(denom), + value: Amounts.parseOrThrow(denom.value), maxAge, }; } diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 11fb3f739..1a60b148c 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -915,11 +915,7 @@ async function dumpCoins(ws: InternalWalletState): Promise { coin_pub: c.coinPub, denom_pub: denomInfo.denomPub, denom_pub_hash: c.denomPubHash, - denom_value: Amounts.stringify({ - value: denom.amountVal, - currency: denom.currency, - fraction: denom.amountFrac, - }), + denom_value: denom.value, exchange_base_url: c.exchangeBaseUrl, refresh_parent_coin_pub: refreshParentCoinPub, withdrawal_reserve_pub: withdrawalReservePub, @@ -1876,35 +1872,27 @@ class InternalWalletStateImpl implements InternalWalletState { return computeRefundTransactionState(rec); } case TransactionType.PeerPullCredit: - const rec = await tx.peerPullCredit.get( - parsedTxId.pursePub, - ); + const rec = await tx.peerPullCredit.get(parsedTxId.pursePub); if (!rec) { return undefined; } return computePeerPullCreditTransactionState(rec); case TransactionType.PeerPullDebit: { - const rec = await tx.peerPullDebit.get( - parsedTxId.peerPullDebitId, - ); + const rec = await tx.peerPullDebit.get(parsedTxId.peerPullDebitId); if (!rec) { return undefined; } return computePeerPullDebitTransactionState(rec); } case TransactionType.PeerPushCredit: { - const rec = await tx.peerPushCredit.get( - parsedTxId.peerPushCreditId, - ); + const rec = await tx.peerPushCredit.get(parsedTxId.peerPushCreditId); if (!rec) { return undefined; } return computePeerPushCreditTransactionState(rec); } case TransactionType.PeerPushDebit: { - const rec = await tx.peerPushDebit.get( - parsedTxId.pursePub, - ); + const rec = await tx.peerPushDebit.get(parsedTxId.pursePub); if (!rec) { return undefined; } -- cgit v1.2.3 From 1f7d2a9cd21b1d6702b59d228a590bffe1a6f30e Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 8 Sep 2023 13:51:25 +0200 Subject: -remove fields --- packages/taler-wallet-core/src/operations/pay-merchant.ts | 3 --- 1 file changed, 3 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 3a7208ab0..57367bb20 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -317,11 +317,8 @@ export function extractContractData( wireInfoHash: parsedContractTerms.h_wire, maxDepositFee: Amounts.stringify(parsedContractTerms.max_fee), merchant: parsedContractTerms.merchant, - products: parsedContractTerms.products, summaryI18n: parsedContractTerms.summary_i18n, minimumAge: parsedContractTerms.minimum_age, - deliveryDate: parsedContractTerms.delivery_date, - deliveryLocation: parsedContractTerms.delivery_location, }; } -- cgit v1.2.3