From f4587c44fd6a6d76384cd671550890255c3fe650 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 13 Sep 2023 16:08:51 +0200 Subject: wallet-core: use typed microsecond timestamps in DB --- packages/taler-util/src/time.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts index 46ed37637..a63f9b296 100644 --- a/packages/taler-util/src/time.ts +++ b/packages/taler-util/src/time.ts @@ -52,6 +52,10 @@ export interface TalerProtocolTimestamp { readonly _flavor?: typeof flavor_TalerProtocolTimestamp; } +/** + * Precise timestamp, typically used in the wallet-core + * API but not in other Taler APIs so far. + */ export interface TalerPreciseTimestamp { /** * Seconds (as integer) since epoch. -- cgit v1.2.3 From 1ce53e1c211296233f2f683c64e156e4d3a79678 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 14 Sep 2023 17:36:15 +0200 Subject: wallet-core: consistently use usec timestamps in DB --- packages/taler-util/src/transactions-types.ts | 24 +++-- .../src/crypto/cryptoImplementation.ts | 22 +++- packages/taler-wallet-core/src/db.ts | 97 ++++++++++++------ .../taler-wallet-core/src/operations/attention.ts | 6 +- .../taler-wallet-core/src/operations/common.ts | 45 ++++---- .../taler-wallet-core/src/operations/deposits.ts | 8 +- .../taler-wallet-core/src/operations/exchanges.ts | 56 +++++++--- .../src/operations/pay-merchant.ts | 22 ++-- .../src/operations/pay-peer-push-debit.ts | 8 +- .../taler-wallet-core/src/operations/pending.ts | 113 ++++++++++++-------- .../taler-wallet-core/src/operations/refresh.ts | 14 +-- .../taler-wallet-core/src/operations/reward.ts | 6 +- .../src/operations/transactions.ts | 17 ++- .../src/operations/withdraw.test.ts | 114 +++++++++++---------- packages/taler-wallet-core/src/pending-types.ts | 14 +-- .../taler-wallet-core/src/util/denominations.ts | 9 +- .../src/util/instructedAmountConversion.ts | 17 +-- 17 files changed, 365 insertions(+), 227 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/transactions-types.ts b/packages/taler-util/src/transactions-types.ts index 304183ceb..63db206bd 100644 --- a/packages/taler-util/src/transactions-types.ts +++ b/packages/taler-util/src/transactions-types.ts @@ -67,7 +67,7 @@ export interface TransactionsRequest { */ includeRefreshes?: boolean; - filterByState?: TransactionStateFilter + filterByState?: TransactionStateFilter; } export interface TransactionState { @@ -629,6 +629,17 @@ export interface TransactionRefresh extends TransactionCommon { refreshOutputAmount: AmountString; } +export interface DepositTransactionTrackingState { + // Raw wire transfer identifier of the deposit. + wireTransferId: string; + // When was the wire transfer given to the bank. + timestampExecuted: TalerProtocolTimestamp; + // Total amount transfer for this wtid (including fees) + amountRaw: AmountString; + // Wire fee amount for this exchange + wireFee: AmountString; +} + /** * Deposit transaction, which effectively sends * money from this wallet somewhere else. @@ -662,16 +673,7 @@ export interface TransactionDeposit extends TransactionCommon { */ deposited: boolean; - trackingState: Array<{ - // Raw wire transfer identifier of the deposit. - wireTransferId: string; - // When was the wire transfer given to the bank. - timestampExecuted: TalerProtocolTimestamp; - // Total amount transfer for this wtid (including fees) - amountRaw: AmountString; - // Wire fee amount for this exchange - wireFee: AmountString; - }>; + trackingState: Array; } export interface TransactionByIdRequest { diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index 35777e714..56392f090 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -87,7 +87,7 @@ import { WithdrawalPlanchet, } from "@gnu-taler/taler-util"; // FIXME: Crypto should not use DB Types! -import { DenominationRecord } from "../db.js"; +import { DenominationRecord, timestampProtocolFromDb } from "../db.js"; import { CreateRecoupRefreshReqRequest, CreateRecoupReqRequest, @@ -962,10 +962,22 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { const value: AmountJson = Amounts.parseOrThrow(denom.value); const p = buildSigPS(TalerSignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY) .put(decodeCrock(masterPub)) - .put(timestampRoundedToBuffer(denom.stampStart)) - .put(timestampRoundedToBuffer(denom.stampExpireWithdraw)) - .put(timestampRoundedToBuffer(denom.stampExpireDeposit)) - .put(timestampRoundedToBuffer(denom.stampExpireLegal)) + .put(timestampRoundedToBuffer(timestampProtocolFromDb(denom.stampStart))) + .put( + timestampRoundedToBuffer( + timestampProtocolFromDb(denom.stampExpireWithdraw), + ), + ) + .put( + timestampRoundedToBuffer( + timestampProtocolFromDb(denom.stampExpireDeposit), + ), + ) + .put( + timestampRoundedToBuffer( + timestampProtocolFromDb(denom.stampExpireLegal), + ), + ) .put(amountToBuffer(value)) .put(amountToBuffer(denom.fees.feeWithdraw)) .put(amountToBuffer(denom.fees.feeDeposit)) diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index cebe3635b..4fc6db68a 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -27,6 +27,7 @@ import { structuredEncapsulate, } from "@gnu-taler/idb-bridge"; import { + AbsoluteTime, AgeCommitmentProof, AmountString, Amounts, @@ -51,12 +52,13 @@ import { TalerPreciseTimestamp, TalerProtocolDuration, TalerProtocolTimestamp, + //TalerProtocolTimestamp, TransactionIdStr, UnblindedSignature, WireInfo, codecForAny, } from "@gnu-taler/taler-util"; -import { RetryInfo, TaskIdentifiers } from "./operations/common.js"; +import { DbRetryInfo, TaskIdentifiers } from "./operations/common.js"; import { DbAccess, DbReadOnlyTransaction, @@ -193,6 +195,44 @@ export function timestampPreciseToDb( } } +export function timestampProtocolToDb( + stamp: TalerProtocolTimestamp, +): DbProtocolTimestamp { + if (stamp.t_s === "never") { + return DB_TIMESTAMP_FOREVER as DbProtocolTimestamp; + } else { + let tUs = stamp.t_s * 1000000; + return tUs as DbProtocolTimestamp; + } +} + +export function timestampProtocolFromDb( + stamp: DbProtocolTimestamp, +): TalerProtocolTimestamp { + return TalerProtocolTimestamp.fromSeconds(Math.floor(stamp / 1000000)); +} + +export function timestampAbsoluteFromDb( + stamp: DbProtocolTimestamp | DbPreciseTimestamp, +): AbsoluteTime { + if (stamp >= DB_TIMESTAMP_FOREVER) { + return AbsoluteTime.never(); + } + return AbsoluteTime.fromMilliseconds(Math.floor(stamp / 1000)); +} + +export function timestampOptionalAbsoluteFromDb( + stamp: DbProtocolTimestamp | DbPreciseTimestamp | undefined, +): AbsoluteTime | undefined { + if (stamp == null) { + return undefined; + } + if (stamp >= DB_TIMESTAMP_FOREVER) { + return AbsoluteTime.never(); + } + return AbsoluteTime.fromMilliseconds(Math.floor(stamp / 1000)); +} + /** * Format of the operation status code: 0x0abc_nnnn @@ -391,22 +431,22 @@ export interface DenominationRecord { /** * Validity start date of the denomination. */ - stampStart: TalerProtocolTimestamp; + stampStart: DbProtocolTimestamp; /** * Date after which the currency can't be withdrawn anymore. */ - stampExpireWithdraw: TalerProtocolTimestamp; + stampExpireWithdraw: DbProtocolTimestamp; /** * Date after the denomination officially doesn't exist anymore. */ - stampExpireLegal: TalerProtocolTimestamp; + stampExpireLegal: DbProtocolTimestamp; /** * Data after which coins of this denomination can't be deposited anymore. */ - stampExpireDeposit: TalerProtocolTimestamp; + stampExpireDeposit: DbProtocolTimestamp; /** * Signature by the exchange's master key over the denomination @@ -448,7 +488,7 @@ export interface DenominationRecord { * Latest list issue date of the "/keys" response * that includes this denomination. */ - listIssueDate: TalerProtocolTimestamp; + listIssueDate: DbProtocolTimestamp; } export namespace DenominationRecord { @@ -460,10 +500,10 @@ export namespace DenominationRecord { feeRefresh: Amounts.stringify(d.fees.feeRefresh), feeRefund: Amounts.stringify(d.fees.feeRefund), feeWithdraw: Amounts.stringify(d.fees.feeWithdraw), - stampExpireDeposit: d.stampExpireDeposit, - stampExpireLegal: d.stampExpireLegal, - stampExpireWithdraw: d.stampExpireWithdraw, - stampStart: d.stampStart, + stampExpireDeposit: timestampProtocolFromDb(d.stampExpireDeposit), + stampExpireLegal: timestampProtocolFromDb(d.stampExpireLegal), + stampExpireWithdraw: timestampProtocolFromDb(d.stampExpireWithdraw), + stampStart: timestampProtocolFromDb(d.stampStart), value: Amounts.stringify(d.value), exchangeBaseUrl: d.exchangeBaseUrl, }; @@ -471,9 +511,9 @@ export namespace DenominationRecord { } export interface ExchangeSignkeysRecord { - stampStart: TalerProtocolTimestamp; - stampExpire: TalerProtocolTimestamp; - stampEnd: TalerProtocolTimestamp; + stampStart: DbProtocolTimestamp; + stampExpire: DbProtocolTimestamp; + stampEnd: DbProtocolTimestamp; signkeyPub: EddsaPublicKeyString; masterSig: EddsaSignatureString; @@ -590,11 +630,6 @@ export enum ExchangeEntryDbUpdateStatus { ReadyUpdate = 7, } -/** - * Timestamp stored as a IEEE 754 double, in milliseconds. - */ -export type DbIndexableTimestampMs = number; - /** * Exchange record as stored in the wallet's database. */ @@ -634,13 +669,8 @@ export interface ExchangeEntryRecord { /** * Next scheduled update for the exchange. - * - * (This field must always be present, so we can index on the timestamp.) - * - * FIXME: To index on the timestamp, this needs to be a number of - * binary timestamp! */ - nextUpdateStampMs: DbIndexableTimestampMs; + nextUpdateStamp: DbPreciseTimestamp; lastKeysEtag: string | undefined; @@ -650,7 +680,7 @@ export interface ExchangeEntryRecord { * Updated whenever the exchange's denominations are updated or when * the refresh check has been done. */ - nextRefreshCheckStampMs: DbIndexableTimestampMs; + nextRefreshCheckStamp: DbPreciseTimestamp; /** * Public key of the reserve that we're currently using for @@ -873,7 +903,7 @@ export interface RewardRecord { /** * Timestamp, the tip can't be picked up anymore after this deadline. */ - rewardExpiration: TalerProtocolTimestamp; + rewardExpiration: DbProtocolTimestamp; /** * The exchange that will sign our coins, chosen by the merchant. @@ -1287,7 +1317,7 @@ export interface PurchaseRecord { /** * Continue querying the refund status until this deadline has expired. */ - autoRefundDeadline: TalerProtocolTimestamp | undefined; + autoRefundDeadline: DbProtocolTimestamp | undefined; /** * How much merchant has refund to be taken but the wallet @@ -1668,7 +1698,7 @@ export interface DepositTrackingInfo { // Raw wire transfer identifier of the deposit. wireTransferId: string; // When was the wire transfer given to the bank. - timestampExecuted: TalerProtocolTimestamp; + timestampExecuted: DbProtocolTimestamp; // Total amount transfer for this wtid (including fees) amountRaw: AmountString; // Wire fee amount for this exchange @@ -1690,7 +1720,7 @@ export interface DepositGroupRecord { */ amount: AmountString; - wireTransferDeadline: TalerProtocolTimestamp; + wireTransferDeadline: DbProtocolTimestamp; merchantPub: string; merchantPriv: string; @@ -1831,7 +1861,7 @@ export interface PeerPushDebitRecord { */ contractEncNonce: string; - purseExpiration: TalerProtocolTimestamp; + purseExpiration: DbProtocolTimestamp; timestampCreated: DbPreciseTimestamp; @@ -2077,7 +2107,7 @@ export interface OperationRetryRecord { lastError?: TalerErrorDetail; - retryInfo: RetryInfo; + retryInfo: DbRetryInfo; } /** @@ -2130,9 +2160,8 @@ export interface UserAttentionRecord { /** * When the notification was created. - * FIXME: This should be a TalerPreciseTimestamp */ - createdMs: number; + created: DbPreciseTimestamp; /** * When the user mark this notification as read. @@ -2233,7 +2262,7 @@ export interface RefundItemRecord { /** * Execution time as claimed by the merchant */ - executionTime: TalerProtocolTimestamp; + executionTime: DbProtocolTimestamp; /** * Time when the wallet became aware of the refund. diff --git a/packages/taler-wallet-core/src/operations/attention.ts b/packages/taler-wallet-core/src/operations/attention.ts index 1030db0a6..92d69e93e 100644 --- a/packages/taler-wallet-core/src/operations/attention.ts +++ b/packages/taler-wallet-core/src/operations/attention.ts @@ -31,7 +31,7 @@ import { UserAttentionUnreadList, } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; -import { timestampPreciseToDb } from "../index.js"; +import { timestampPreciseFromDb, timestampPreciseToDb } from "../index.js"; const logger = new Logger("operations/attention.ts"); @@ -75,7 +75,7 @@ export async function getUserAttentions( return; pending.push({ info: x.info, - when: TalerPreciseTimestamp.fromMilliseconds(x.createdMs), + when: timestampPreciseFromDb(x.created), read: x.read !== undefined, }); }); @@ -118,7 +118,7 @@ export async function addAttentionRequest( await tx.userAttention.put({ info, entityId, - createdMs: AbsoluteTime.now().t_ms as number, + created: timestampPreciseToDb(TalerPreciseTimestamp.now()), read: undefined, }); }); diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 50dd3dc5c..e8e492c08 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -40,6 +40,7 @@ import { TalerError, TalerErrorCode, TalerErrorDetail, + TalerPreciseTimestamp, TombstoneIdStr, TransactionIdStr, TransactionType, @@ -49,6 +50,7 @@ import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; import { BackupProviderRecord, CoinRecord, + DbPreciseTimestamp, DepositGroupRecord, ExchangeDetailsRecord, ExchangeEntryDbRecordStatus, @@ -62,6 +64,7 @@ import { RecoupGroupRecord, RefreshGroupRecord, RewardRecord, + timestampPreciseToDb, WalletStoresV1, WithdrawalGroupRecord, } from "../db.js"; @@ -360,11 +363,11 @@ async function storePendingTaskError( retryRecord = { id: pendingTaskId, lastError: e, - retryInfo: RetryInfo.reset(), + retryInfo: DbRetryInfo.reset(), }; } else { retryRecord.lastError = e; - retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo); + retryRecord.retryInfo = DbRetryInfo.increment(retryRecord.retryInfo); } await tx.operationRetries.put(retryRecord); return taskToTransactionNotification(ws, tx, pendingTaskId, e); @@ -383,7 +386,7 @@ export async function resetPendingTaskTimeout( if (retryRecord) { // Note that we don't reset the lastError, it should still be visible // while the retry runs. - retryRecord.retryInfo = RetryInfo.reset(); + retryRecord.retryInfo = DbRetryInfo.reset(); await tx.operationRetries.put(retryRecord); } return taskToTransactionNotification(ws, tx, pendingTaskId, undefined); @@ -403,14 +406,14 @@ async function storePendingTaskPending( if (!retryRecord) { retryRecord = { id: pendingTaskId, - retryInfo: RetryInfo.reset(), + retryInfo: DbRetryInfo.reset(), }; } else { if (retryRecord.lastError) { hadError = true; } delete retryRecord.lastError; - retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo); + retryRecord.retryInfo = DbRetryInfo.increment(retryRecord.retryInfo); } await tx.operationRetries.put(retryRecord); if (hadError) { @@ -736,9 +739,9 @@ export interface TaskRunLongpollResult { type: TaskRunResultType.Longpoll; } -export interface RetryInfo { - firstTry: AbsoluteTime; - nextRetry: AbsoluteTime; +export interface DbRetryInfo { + firstTry: DbPreciseTimestamp; + nextRetry: DbPreciseTimestamp; retryCounter: number; } @@ -755,7 +758,7 @@ const defaultRetryPolicy: RetryPolicy = { }; function updateTimeout( - r: RetryInfo, + r: DbRetryInfo, p: RetryPolicy = defaultRetryPolicy, ): void { const now = AbsoluteTime.now(); @@ -763,7 +766,9 @@ function updateTimeout( throw Error("assertion failed"); } if (p.backoffDelta.d_ms === "forever") { - r.nextRetry = AbsoluteTime.never(); + r.nextRetry = timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ); return; } @@ -775,12 +780,12 @@ function updateTimeout( (p.maxTimeout.d_ms === "forever" ? nextIncrement : Math.min(p.maxTimeout.d_ms, nextIncrement)); - r.nextRetry = AbsoluteTime.fromMilliseconds(t); + r.nextRetry = timestampPreciseToDb(TalerPreciseTimestamp.fromMilliseconds(t)); } -export namespace RetryInfo { +export namespace DbRetryInfo { export function getDuration( - r: RetryInfo | undefined, + r: DbRetryInfo | undefined, p: RetryPolicy = defaultRetryPolicy, ): Duration { if (!r) { @@ -797,11 +802,11 @@ export namespace RetryInfo { }; } - export function reset(p: RetryPolicy = defaultRetryPolicy): RetryInfo { - const now = AbsoluteTime.now(); - const info = { - firstTry: now, - nextRetry: now, + export function reset(p: RetryPolicy = defaultRetryPolicy): DbRetryInfo { + const now = TalerPreciseTimestamp.now(); + const info: DbRetryInfo = { + firstTry: timestampPreciseToDb(now), + nextRetry: timestampPreciseToDb(now), retryCounter: 0, }; updateTimeout(info, p); @@ -809,9 +814,9 @@ export namespace RetryInfo { } export function increment( - r: RetryInfo | undefined, + r: DbRetryInfo | undefined, p: RetryPolicy = defaultRetryPolicy, - ): RetryInfo { + ): DbRetryInfo { if (!r) { return reset(p); } diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index cb40f8f22..111d15989 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -74,6 +74,8 @@ import { createRefreshGroup, getTotalRefreshCost, timestampPreciseToDb, + timestampProtocolFromDb, + timestampProtocolToDb, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; @@ -800,7 +802,7 @@ async function processDepositGroupPendingTrack( amountRaw: Amounts.stringify(raw), wireFee: Amounts.stringify(wireFee), exchangePub: track.exchange_pub, - timestampExecuted: track.execution_time, + timestampExecuted: timestampProtocolToDb(track.execution_time), wireTransferId: track.wtid, }, id: track.exchange_sig, @@ -1393,7 +1395,9 @@ export async function createDepositGroup( counterpartyEffectiveDepositAmount: Amounts.stringify( counterpartyEffectiveDepositAmount, ), - wireTransferDeadline: contractTerms.wire_transfer_deadline, + wireTransferDeadline: timestampProtocolToDb( + contractTerms.wire_transfer_deadline, + ), wire: { payto_uri: req.depositPaytoUri, salt: wireSalt, diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 60d55252a..5e966b719 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -74,7 +74,9 @@ import { ExchangeEntryDbRecordStatus, ExchangeEntryDbUpdateStatus, isWithdrawableDenom, + timestampPreciseFromDb, timestampPreciseToDb, + timestampProtocolToDb, WalletDbReadWriteTransaction, } from "../index.js"; import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js"; @@ -317,8 +319,12 @@ export async function addPresetExchangeEntry( detailsPointer: undefined, lastUpdate: undefined, lastKeysEtag: undefined, - nextRefreshCheckStampMs: AbsoluteTime.getStampMsNever(), - nextUpdateStampMs: AbsoluteTime.getStampMsNever(), + nextRefreshCheckStamp: timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ), + nextUpdateStamp: timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ), }; await tx.exchanges.put(r); } @@ -344,8 +350,12 @@ export async function provideExchangeRecordInTx( baseUrl: baseUrl, detailsPointer: undefined, lastUpdate: undefined, - nextUpdateStampMs: AbsoluteTime.getStampMsNever(), - nextRefreshCheckStampMs: AbsoluteTime.getStampMsNever(), + nextUpdateStamp: timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ), + nextRefreshCheckStamp: timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ), lastKeysEtag: undefined, }; await tx.exchanges.put(r); @@ -446,13 +456,19 @@ async function downloadExchangeKeysInfo( isRevoked: false, value: Amounts.stringify(value), currency: value.currency, - stampExpireDeposit: denomIn.stamp_expire_deposit, - stampExpireLegal: denomIn.stamp_expire_legal, - stampExpireWithdraw: denomIn.stamp_expire_withdraw, - stampStart: denomIn.stamp_start, + stampExpireDeposit: timestampProtocolToDb( + denomIn.stamp_expire_deposit, + ), + stampExpireLegal: timestampProtocolToDb(denomIn.stamp_expire_legal), + stampExpireWithdraw: timestampProtocolToDb( + denomIn.stamp_expire_withdraw, + ), + stampStart: timestampProtocolToDb(denomIn.stamp_start), verificationStatus: DenominationVerificationStatus.Unverified, masterSig: denomIn.master_sig, - listIssueDate: exchangeKeysJsonUnchecked.list_issue_date, + listIssueDate: timestampProtocolToDb( + exchangeKeysJsonUnchecked.list_issue_date, + ), fees: { feeDeposit: Amounts.stringify(denomGroup.fee_deposit), feeRefresh: Amounts.stringify(denomGroup.fee_refresh), @@ -614,7 +630,9 @@ export async function updateExchangeFromUrlHandler( !forceNow && exchangeDetails !== undefined && !AbsoluteTime.isExpired( - AbsoluteTime.fromStampMs(exchange.nextUpdateStampMs), + AbsoluteTime.fromPreciseTimestamp( + timestampPreciseFromDb(exchange.nextUpdateStamp), + ), ) ) { logger.trace("using existing exchange info"); @@ -755,11 +773,15 @@ export async function updateExchangeFromUrlHandler( newDetails.rowId = existingDetails.rowId; } r.lastUpdate = timestampPreciseToDb(TalerPreciseTimestamp.now()); - r.nextUpdateStampMs = AbsoluteTime.toStampMs( - AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry), + r.nextUpdateStamp = timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp( + AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry), + ), ); // New denominations might be available. - r.nextRefreshCheckStampMs = AbsoluteTime.getStampMsNow(); + r.nextRefreshCheckStamp = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); if (detailsPointerChanged) { r.detailsPointer = { currency: newDetails.currency, @@ -777,9 +799,9 @@ export async function updateExchangeFromUrlHandler( exchangeDetailsRowId: drRowId.key, masterSig: sk.master_sig, signkeyPub: sk.key, - stampEnd: sk.stamp_end, - stampExpire: sk.stamp_expire, - stampStart: sk.stamp_start, + stampEnd: timestampProtocolToDb(sk.stamp_end), + stampExpire: timestampProtocolToDb(sk.stamp_expire), + stampStart: timestampProtocolToDb(sk.stamp_start), }); } @@ -814,7 +836,7 @@ export async function updateExchangeFromUrlHandler( ); } } else { - x.listIssueDate = keysInfo.listIssueDate; + x.listIssueDate = timestampProtocolToDb(keysInfo.listIssueDate); if (!x.isOffered) { x.isOffered = true; logger.info( diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 97bf6e2a6..157541ed3 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -104,6 +104,8 @@ import { RefundItemRecord, RefundItemStatus, timestampPreciseToDb, + timestampProtocolFromDb, + timestampProtocolToDb, } from "../index.js"; import { EXCHANGE_COINS_LOCK, @@ -115,7 +117,7 @@ import { checkDbInvariant } from "../util/invariants.js"; import { GetReadOnlyAccess } from "../util/query.js"; import { constructTaskIdentifier, - RetryInfo, + DbRetryInfo, runLongpollAsync, runTaskWithErrorReporting, spendCoins, @@ -217,11 +219,13 @@ async function failProposalPermanently( notifyTransition(ws, transactionId, transitionInfo); } -function getProposalRequestTimeout(retryInfo?: RetryInfo): Duration { +function getProposalRequestTimeout(retryInfo?: DbRetryInfo): Duration { return Duration.clamp({ lower: Duration.fromSpec({ seconds: 1 }), upper: Duration.fromSpec({ seconds: 60 }), - value: retryInfo ? RetryInfo.getDuration(retryInfo) : Duration.fromSpec({}), + value: retryInfo + ? DbRetryInfo.getDuration(retryInfo) + : Duration.fromSpec({}), }); } @@ -738,8 +742,10 @@ async function storeFirstPaySuccess( const ar = Duration.fromTalerProtocolDuration(protoAr); logger.info("auto_refund present"); purchase.purchaseStatus = PurchaseStatus.PendingQueryingAutoRefund; - purchase.autoRefundDeadline = AbsoluteTime.toProtocolTimestamp( - AbsoluteTime.addDuration(AbsoluteTime.now(), ar), + purchase.autoRefundDeadline = timestampProtocolToDb( + AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration(AbsoluteTime.now(), ar), + ), ); } await tx.purchases.put(purchase); @@ -2343,7 +2349,9 @@ async function processPurchaseAutoRefund( if ( !purchase.autoRefundDeadline || AbsoluteTime.isExpired( - AbsoluteTime.fromProtocolTimestamp(purchase.autoRefundDeadline), + AbsoluteTime.fromProtocolTimestamp( + timestampProtocolFromDb(purchase.autoRefundDeadline), + ), ) ) { const transitionInfo = await ws.db @@ -2804,7 +2812,7 @@ async function storeRefunds( const status: RefundItemStatus = getItemStatus(rf); const newItem: RefundItemRecord = { coinPub: rf.coin_pub, - executionTime: rf.execution_time, + executionTime: timestampProtocolToDb(rf.execution_time), obtainedTime: timestampPreciseToDb(now), refundAmount: rf.refund_amount, refundGroupId: newGroup.refundGroupId, 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 b3d0eb132..a7b9f79eb 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 @@ -56,10 +56,13 @@ import { RefreshOperationStatus, createRefreshGroup, timestampPreciseToDb, + timestampProtocolFromDb, + timestampProtocolToDb, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { PendingTaskType } from "../pending-types.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; +import { PeerCoinRepair, selectPeerCoins } from "../util/coinSelection.js"; import { checkLogicInvariant } from "../util/invariants.js"; import { TaskRunResult, @@ -78,7 +81,6 @@ import { notifyTransition, stopLongpolling, } from "./transactions.js"; -import { PeerCoinRepair, selectPeerCoins } from "../util/coinSelection.js"; const logger = new Logger("pay-peer-push-debit.ts"); @@ -208,7 +210,7 @@ async function processPeerPushDebitCreateReserve( mergePub: peerPushInitiation.mergePub, minAge: 0, purseAmount: peerPushInitiation.amount, - purseExpiration, + purseExpiration: timestampProtocolFromDb(purseExpiration), pursePriv: peerPushInitiation.pursePriv, }); @@ -667,7 +669,7 @@ export async function initiatePeerPushDebit( exchangeBaseUrl: sel.exchangeBaseUrl, mergePriv: mergePair.priv, mergePub: mergePair.pub, - purseExpiration: purseExpiration, + purseExpiration: timestampProtocolToDb(purseExpiration), pursePriv: pursePair.priv, pursePub: pursePair.pub, timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()), diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 120d316ce..1819aa1b8 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -21,43 +21,46 @@ /** * Imports. */ +import { GlobalIDB } from "@gnu-taler/idb-bridge"; +import { AbsoluteTime, TransactionRecordFilter } from "@gnu-taler/taler-util"; import { - PurchaseStatus, - WalletStoresV1, BackupProviderStateTag, - RefreshCoinStatus, - PeerPushDebitStatus, - PeerPullDebitRecordStatus, - PeerPushCreditStatus, - PeerPullPaymentCreditStatus, - WithdrawalGroupStatus, - RewardRecordStatus, - DepositOperationStatus, - RefreshGroupRecord, - WithdrawalGroupRecord, + DepositElementStatus, DepositGroupRecord, - RewardRecord, - PurchaseRecord, + DepositOperationStatus, + ExchangeEntryDbUpdateStatus, PeerPullCreditRecord, + PeerPullDebitRecordStatus, + PeerPullPaymentCreditStatus, PeerPullPaymentIncomingRecord, + PeerPushCreditStatus, PeerPushDebitRecord, + PeerPushDebitStatus, PeerPushPaymentIncomingRecord, + PurchaseRecord, + PurchaseStatus, + RefreshCoinStatus, + RefreshGroupRecord, + RefreshOperationStatus, RefundGroupRecord, RefundGroupStatus, - ExchangeEntryDbUpdateStatus, - RefreshOperationStatus, - DepositElementStatus, + RewardRecord, + RewardRecordStatus, + WalletStoresV1, + WithdrawalGroupRecord, + WithdrawalGroupStatus, + timestampAbsoluteFromDb, + timestampOptionalAbsoluteFromDb, timestampPreciseFromDb, + timestampPreciseToDb, } from "../db.js"; +import { InternalWalletState } from "../internal-wallet-state.js"; import { PendingOperationsResponse, PendingTaskType, TaskId, } from "../pending-types.js"; -import { AbsoluteTime, TransactionRecordFilter } from "@gnu-taler/taler-util"; -import { InternalWalletState } from "../internal-wallet-state.js"; import { GetReadOnlyAccess } from "../util/query.js"; -import { GlobalIDB } from "@gnu-taler/idb-bridge"; import { TaskIdentifiers } from "./common.js"; function getPendingCommon( @@ -100,12 +103,14 @@ async function gatherExchangePending( } const opTag = TaskIdentifiers.forExchangeUpdate(exch); let opr = await tx.operationRetries.get(opTag); - const timestampDue = - opr?.retryInfo.nextRetry ?? - AbsoluteTime.fromStampMs(exch.nextUpdateStampMs); + const timestampDue = opr?.retryInfo.nextRetry ?? exch.nextRefreshCheckStamp; resp.pendingOperations.push({ type: PendingTaskType.ExchangeUpdate, - ...getPendingCommon(ws, opTag, timestampDue), + ...getPendingCommon( + ws, + opTag, + AbsoluteTime.fromPreciseTimestamp(timestampPreciseFromDb(timestampDue)), + ), givesLifeness: false, exchangeBaseUrl: exch.baseUrl, lastError: opr?.lastError, @@ -116,8 +121,16 @@ async function gatherExchangePending( if (!opr?.lastError) { resp.pendingOperations.push({ type: PendingTaskType.ExchangeCheckRefresh, - ...getPendingCommon(ws, opTag, timestampDue), - timestampDue: AbsoluteTime.fromStampMs(exch.nextRefreshCheckStampMs), + ...getPendingCommon( + ws, + opTag, + AbsoluteTime.fromPreciseTimestamp( + timestampPreciseFromDb(timestampDue), + ), + ), + timestampDue: AbsoluteTime.fromPreciseTimestamp( + timestampPreciseFromDb(exch.nextRefreshCheckStamp), + ), givesLifeness: false, exchangeBaseUrl: exch.baseUrl, }); @@ -166,7 +179,9 @@ async function gatherRefreshPending( } const opId = TaskIdentifiers.forRefresh(r); const retryRecord = await tx.operationRetries.get(opId); - const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + const timestampDue = + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.Refresh, ...getPendingCommon(ws, opId, timestampDue), @@ -223,8 +238,8 @@ async function gatherWithdrawalPending( opr = { id: opTag, retryInfo: { - firstTry: now, - nextRetry: now, + firstTry: timestampPreciseToDb(AbsoluteTime.toPreciseTimestamp(now)), + nextRetry: timestampPreciseToDb(AbsoluteTime.toPreciseTimestamp(now)), retryCounter: 0, }, }; @@ -234,7 +249,8 @@ async function gatherWithdrawalPending( ...getPendingCommon( ws, opTag, - opr.retryInfo?.nextRetry ?? AbsoluteTime.now(), + timestampOptionalAbsoluteFromDb(opr.retryInfo?.nextRetry) ?? + AbsoluteTime.now(), ), givesLifeness: true, withdrawalGroupId: wsr.withdrawalGroupId, @@ -286,7 +302,9 @@ async function gatherDepositPending( } const opId = TaskIdentifiers.forDeposit(dg); const retryRecord = await tx.operationRetries.get(opId); - const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + const timestampDue = + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.Deposit, ...getPendingCommon(ws, opId, timestampDue), @@ -331,13 +349,15 @@ async function gatherRewardPending( await iterRecordsForReward(tx, { onlyState: "nonfinal" }, async (tip) => { const opId = TaskIdentifiers.forTipPickup(tip); const retryRecord = await tx.operationRetries.get(opId); - const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + const timestampDue = + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); if (tip.acceptedTimestamp) { resp.pendingOperations.push({ type: PendingTaskType.RewardPickup, ...getPendingCommon(ws, opId, timestampDue), givesLifeness: true, - timestampDue: retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(), + timestampDue, merchantBaseUrl: tip.merchantBaseUrl, tipId: tip.walletRewardId, merchantTipId: tip.merchantRewardId, @@ -391,7 +411,9 @@ async function gatherPurchasePending( await iterRecordsForPurchase(tx, { onlyState: "nonfinal" }, async (pr) => { const opId = TaskIdentifiers.forPay(pr); const retryRecord = await tx.operationRetries.get(opId); - const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + const timestampDue = + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.Purchase, ...getPendingCommon(ws, opId, timestampDue), @@ -420,7 +442,9 @@ async function gatherRecoupPending( } const opId = TaskIdentifiers.forRecoup(rg); const retryRecord = await tx.operationRetries.get(opId); - const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + const timestampDue = + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.Recoup, ...getPendingCommon(ws, opId, timestampDue), @@ -445,8 +469,8 @@ async function gatherBackupPending( const opId = TaskIdentifiers.forBackup(bp); const retryRecord = await tx.operationRetries.get(opId); if (bp.state.tag === BackupProviderStateTag.Ready) { - const timestampDue = AbsoluteTime.fromPreciseTimestamp( - timestampPreciseFromDb(bp.state.nextBackupTimestamp), + const timestampDue = timestampAbsoluteFromDb( + bp.state.nextBackupTimestamp, ); resp.pendingOperations.push({ type: PendingTaskType.Backup, @@ -457,7 +481,8 @@ async function gatherBackupPending( }); } else if (bp.state.tag === BackupProviderStateTag.Retrying) { const timestampDue = - retryRecord?.retryInfo?.nextRetry ?? AbsoluteTime.now(); + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo?.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.Backup, ...getPendingCommon(ws, opId, timestampDue), @@ -504,7 +529,8 @@ async function gatherPeerPullInitiationPending( const opId = TaskIdentifiers.forPeerPullPaymentInitiation(pi); const retryRecord = await tx.operationRetries.get(opId); const timestampDue = - retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.PeerPullCredit, ...getPendingCommon(ws, opId, timestampDue), @@ -550,7 +576,8 @@ async function gatherPeerPullDebitPending( const opId = TaskIdentifiers.forPeerPullPaymentDebit(pi); const retryRecord = await tx.operationRetries.get(opId); const timestampDue = - retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.PeerPullDebit, ...getPendingCommon(ws, opId, timestampDue), @@ -596,7 +623,8 @@ async function gatherPeerPushInitiationPending( const opId = TaskIdentifiers.forPeerPushPaymentInitiation(pi); const retryRecord = await tx.operationRetries.get(opId); const timestampDue = - retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.PeerPushDebit, ...getPendingCommon(ws, opId, timestampDue), @@ -646,7 +674,8 @@ async function gatherPeerPushCreditPending( const opId = TaskIdentifiers.forPeerPushCredit(pi); const retryRecord = await tx.operationRetries.get(opId); const timestampDue = - retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); + timestampOptionalAbsoluteFromDb(retryRecord?.retryInfo.nextRetry) ?? + AbsoluteTime.now(); resp.pendingOperations.push({ type: PendingTaskType.PeerPushCredit, ...getPendingCommon(ws, opId, timestampDue), diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index dc1d53627..95aedbbd6 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -81,6 +81,7 @@ import { PendingTaskType, RefreshSessionRecord, timestampPreciseToDb, + timestampProtocolFromDb, } from "../index.js"; import { EXCHANGE_COINS_LOCK, @@ -1125,10 +1126,10 @@ export async function createRefreshGroup( */ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime { const expireWithdraw = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireWithdraw, + timestampProtocolFromDb(d.stampExpireWithdraw), ); const expireDeposit = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireDeposit, + timestampProtocolFromDb(d.stampExpireDeposit), ); const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit); const deltaDiv = durationMul(delta, 0.75); @@ -1140,10 +1141,10 @@ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime { */ function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime { const expireWithdraw = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireWithdraw, + timestampProtocolFromDb(d.stampExpireWithdraw), ); const expireDeposit = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireDeposit, + timestampProtocolFromDb(d.stampExpireDeposit), ); const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit); const deltaDiv = durationMul(delta, 0.5); @@ -1227,8 +1228,9 @@ export async function autoRefresh( logger.trace( `next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`, ); - exchange.nextRefreshCheckStampMs = - AbsoluteTime.toStampMs(minCheckThreshold); + exchange.nextRefreshCheckStamp = timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(minCheckThreshold), + ); await tx.exchanges.put(exchange); }); return TaskRunResult.finished(); diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts index 3681dc4f5..ddcfb20ac 100644 --- a/packages/taler-wallet-core/src/operations/reward.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -52,6 +52,8 @@ import { RewardRecordStatus, timestampPreciseFromDb, timestampPreciseToDb, + timestampProtocolFromDb, + timestampProtocolToDb, } from "../db.js"; import { makeErrorDetail } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -201,7 +203,7 @@ export async function prepareTip( acceptedTimestamp: undefined, status: RewardRecordStatus.DialogAccept, rewardAmountRaw: Amounts.stringify(amount), - rewardExpiration: tipPickupStatus.expiration, + rewardExpiration: timestampProtocolToDb(tipPickupStatus.expiration), exchangeBaseUrl: tipPickupStatus.exchange_url, next_url: tipPickupStatus.next_url, merchantBaseUrl: res.merchantBaseUrl, @@ -231,7 +233,7 @@ export async function prepareTip( rewardAmountRaw: Amounts.stringify(tipRecord.rewardAmountRaw), exchangeBaseUrl: tipRecord.exchangeBaseUrl, merchantBaseUrl: tipRecord.merchantBaseUrl, - expirationTimestamp: tipRecord.rewardExpiration, + expirationTimestamp: timestampProtocolFromDb(tipRecord.rewardExpiration), rewardAmountEffective: Amounts.stringify(tipRecord.rewardAmountEffective), walletRewardId: tipRecord.walletRewardId, transactionId, diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 41bdae249..cf2006406 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -20,6 +20,7 @@ import { AbsoluteTime, Amounts, + DepositTransactionTrackingState, j2s, Logger, NotificationType, @@ -69,6 +70,7 @@ import { GetReadOnlyAccess, timestampOptionalPreciseFromDb, timestampPreciseFromDb, + timestampProtocolFromDb, WalletStoresV1, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -809,6 +811,17 @@ function buildTransactionForDeposit( } } + const trackingState: DepositTransactionTrackingState[] = []; + + for (const ts of Object.values(dg.trackingState ?? {})) { + trackingState.push({ + amountRaw: ts.amountRaw, + timestampExecuted: timestampProtocolFromDb(ts.timestampExecuted), + wireFee: ts.wireFee, + wireTransferId: ts.wireTransferId, + }); + } + return { type: TransactionType.Deposit, txState: computeDepositTransactionStatus(dg), @@ -817,7 +830,7 @@ function buildTransactionForDeposit( amountEffective: Amounts.stringify(dg.totalPayCost), timestamp: timestampPreciseFromDb(dg.timestampCreated), targetPaytoUri: dg.wire.payto_uri, - wireTransferDeadline: dg.wireTransferDeadline, + wireTransferDeadline: timestampProtocolFromDb(dg.wireTransferDeadline), transactionId: constructTransactionIdentifier({ tag: TransactionType.Deposit, depositGroupId: dg.depositGroupId, @@ -830,7 +843,7 @@ function buildTransactionForDeposit( )) / dg.statusPerCoin.length, depositGroupId: dg.depositGroupId, - trackingState: Object.values(dg.trackingState ?? {}), + trackingState, deposited, ...(ort?.lastError ? { error: ort.lastError } : {}), }; diff --git a/packages/taler-wallet-core/src/operations/withdraw.test.ts b/packages/taler-wallet-core/src/operations/withdraw.test.ts index 2d9286610..cb8aa5e81 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.test.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.test.ts @@ -16,7 +16,11 @@ import { Amounts, DenomKeyType } from "@gnu-taler/taler-util"; import test from "ava"; -import { DenominationRecord, DenominationVerificationStatus } from "../db.js"; +import { + DenominationRecord, + DenominationVerificationStatus, + timestampProtocolToDb, +} from "../db.js"; import { selectWithdrawalDenominations } from "../util/coinSelection.js"; test("withdrawal selection bug repro", (t) => { @@ -64,22 +68,22 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "4F0P456CNNTTWK8BFJHGM3JTD6FVVNZY8EP077GYAHDJ5Y81S5RQ3SMS925NXMDVG9A88JAAP0E2GDZBC21PP5NHFFVWHAW3AVT8J3R", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, currency: "KUDOS", value: "KUDOS:1000", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, { denomPub: { @@ -119,22 +123,22 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "P99AW82W46MZ0AKW7Z58VQPXFNTJQM9DVTYPBDF6KVYF38PPVDAZTV7JQ8TY7HGEC7JJJAY4E7AY7J3W1WV10DAZZQHHKTAVTSRAC20", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, value: "KUDOS:10", currency: "KUDOS", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, { denomPub: { @@ -173,22 +177,22 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "8S4VZGHE5WE0N5ZVCHYW9KZZR4YAKK15S46MV1HR1QB9AAMH3NWPW4DCR4NYGJK33Q8YNFY80SWNS6XKAP5DEVK933TM894FJ2VGE3G", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, value: "KUDOS:5", currency: "KUDOS", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, { denomPub: { @@ -228,22 +232,22 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "E3AWGAG8VB42P3KXM8B04Z6M483SX59R3Y4T53C3NXCA2NPB6C7HVCMVX05DC6S58E9X40NGEBQNYXKYMYCF3ASY2C4WP1WCZ4ME610", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, value: "KUDOS:1", currency: "KUDOS", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, { denomPub: { @@ -282,18 +286,18 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "0ES1RKV002XB4YP21SN0QB7RSDHGYT0XAE65JYN8AVJAA6H7JZFN7JADXT521DJS89XMGPZGR8GCXF1516Y0Q9QDV00E6NMFA6CF838", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, value: Amounts.stringify({ currency: "KUDOS", @@ -301,7 +305,7 @@ test("withdrawal selection bug repro", (t) => { value: 0, }), currency: "KUDOS", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, { denomPub: { @@ -340,22 +344,22 @@ test("withdrawal selection bug repro", (t) => { isRevoked: false, masterSig: "58QEB6C6N7602E572E3JYANVVJ9BRW0V9E2ZFDW940N47YVQDK9SAFPWBN5YGT3G1742AFKQ0CYR4DM2VWV0Z0T1XMEKWN6X2EZ9M0R", - stampExpireDeposit: { + stampExpireDeposit: timestampProtocolToDb({ t_s: 1742909388, - }, - stampExpireLegal: { + }), + stampExpireLegal: timestampProtocolToDb({ t_s: 1900589388, - }, - stampExpireWithdraw: { + }), + stampExpireWithdraw: timestampProtocolToDb({ t_s: 1679837388, - }, - stampStart: { + }), + stampStart: timestampProtocolToDb({ t_s: 1585229388, - }, + }), verificationStatus: DenominationVerificationStatus.Unverified, value: "KUDOS:2", currency: "KUDOS", - listIssueDate: { t_s: 0 }, + listIssueDate: timestampProtocolToDb({ t_s: 0 }), }, ]; diff --git a/packages/taler-wallet-core/src/pending-types.ts b/packages/taler-wallet-core/src/pending-types.ts index 627888b4d..e7a40e81b 100644 --- a/packages/taler-wallet-core/src/pending-types.ts +++ b/packages/taler-wallet-core/src/pending-types.ts @@ -25,7 +25,7 @@ * Imports. */ import { TalerErrorDetail, AbsoluteTime } from "@gnu-taler/taler-util"; -import { RetryInfo } from "./operations/common.js"; +import { DbRetryInfo } from "./operations/common.js"; export enum PendingTaskType { ExchangeUpdate = "exchange-update", @@ -137,7 +137,7 @@ export interface PendingRefreshTask { lastError?: TalerErrorDetail; refreshGroupId: string; finishedPerCoin: boolean[]; - retryInfo?: RetryInfo; + retryInfo?: DbRetryInfo; } /** @@ -156,7 +156,7 @@ export interface PendingTipPickupTask { export interface PendingPurchaseTask { type: PendingTaskType.Purchase; proposalId: string; - retryInfo?: RetryInfo; + retryInfo?: DbRetryInfo; /** * Status of the payment as string, used only for debugging. */ @@ -167,7 +167,7 @@ export interface PendingPurchaseTask { export interface PendingRecoupTask { type: PendingTaskType.Recoup; recoupGroupId: string; - retryInfo?: RetryInfo; + retryInfo?: DbRetryInfo; lastError: TalerErrorDetail | undefined; } @@ -177,7 +177,7 @@ export interface PendingRecoupTask { export interface PendingWithdrawTask { type: PendingTaskType.Withdraw; lastError: TalerErrorDetail | undefined; - retryInfo?: RetryInfo; + retryInfo?: DbRetryInfo; withdrawalGroupId: string; } @@ -187,7 +187,7 @@ export interface PendingWithdrawTask { export interface PendingDepositTask { type: PendingTaskType.Deposit; lastError: TalerErrorDetail | undefined; - retryInfo: RetryInfo | undefined; + retryInfo: DbRetryInfo | undefined; depositGroupId: string; } @@ -233,7 +233,7 @@ export interface PendingTaskInfoCommon { * Retry info. Currently used to stop the wallet after any operation * exceeds a number of retries. */ - retryInfo?: RetryInfo; + retryInfo?: DbRetryInfo; } /** diff --git a/packages/taler-wallet-core/src/util/denominations.ts b/packages/taler-wallet-core/src/util/denominations.ts index 76716cf7a..db6e69956 100644 --- a/packages/taler-wallet-core/src/util/denominations.ts +++ b/packages/taler-wallet-core/src/util/denominations.ts @@ -26,10 +26,9 @@ import { FeeDescriptionPair, TalerProtocolTimestamp, TimePoint, - WireFee, } from "@gnu-taler/taler-util"; import { DenominationRecord } from "../db.js"; -import { WalletConfig } from "../index.js"; +import { timestampProtocolFromDb } from "../index.js"; /** * Given a list of denominations with the same value and same period of time: @@ -457,9 +456,11 @@ export function isWithdrawableDenom( denomselAllowLate?: boolean, ): boolean { const now = AbsoluteTime.now(); - const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart); + const start = AbsoluteTime.fromProtocolTimestamp( + timestampProtocolFromDb(d.stampStart), + ); const withdrawExpire = AbsoluteTime.fromProtocolTimestamp( - d.stampExpireWithdraw, + timestampProtocolFromDb(d.stampExpireWithdraw), ); const started = AbsoluteTime.cmp(now, start) >= 0; let lastPossibleWithdraw: AbsoluteTime; diff --git a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts index 54c08eee4..a0394a687 100644 --- a/packages/taler-wallet-core/src/util/instructedAmountConversion.ts +++ b/packages/taler-wallet-core/src/util/instructedAmountConversion.ts @@ -14,6 +14,7 @@ GNU Taler; see the file COPYING. If not, see */ +import { GlobalIDB } from "@gnu-taler/idb-bridge"; import { AbsoluteTime, AgeRestriction, @@ -29,14 +30,14 @@ import { parsePaytoUri, strcmp, } from "@gnu-taler/taler-util"; -import { checkDbInvariant } from "./invariants.js"; import { DenominationRecord, InternalWalletState, getExchangeDetails, + timestampProtocolFromDb, } from "../index.js"; import { CoinInfo } from "./coinSelection.js"; -import { GlobalIDB } from "@gnu-taler/idb-bridge"; +import { checkDbInvariant } from "./invariants.js"; /** * If the operation going to be plan subtracts @@ -224,10 +225,10 @@ async function getAvailableDenoms( ); for (const denom of ds) { const expiresWithdraw = AbsoluteTime.fromProtocolTimestamp( - denom.stampExpireWithdraw, + timestampProtocolFromDb(denom.stampExpireWithdraw), ); const expiresDeposit = AbsoluteTime.fromProtocolTimestamp( - denom.stampExpireDeposit, + timestampProtocolFromDb(denom.stampExpireDeposit), ); creditDeadline = AbsoluteTime.min(deadline, expiresWithdraw); debitDeadline = AbsoluteTime.min(deadline, expiresDeposit); @@ -270,10 +271,10 @@ async function getAvailableDenoms( continue; } const expiresWithdraw = AbsoluteTime.fromProtocolTimestamp( - denom.stampExpireWithdraw, + timestampProtocolFromDb(denom.stampExpireWithdraw), ); const expiresDeposit = AbsoluteTime.fromProtocolTimestamp( - denom.stampExpireDeposit, + timestampProtocolFromDb(denom.stampExpireDeposit), ); creditDeadline = AbsoluteTime.min(deadline, expiresWithdraw); debitDeadline = AbsoluteTime.min(deadline, expiresDeposit); @@ -318,7 +319,9 @@ function buildCoinInfoFromDenom( exchangeBaseUrl: denom.exchangeBaseUrl, duration: AbsoluteTime.difference( AbsoluteTime.now(), - AbsoluteTime.fromProtocolTimestamp(denom.stampExpireDeposit), + AbsoluteTime.fromProtocolTimestamp( + timestampProtocolFromDb(denom.stampExpireDeposit), + ), ), totalAvailable: total, value: Amounts.parseOrThrow(denom.value), -- cgit v1.2.3 From 1d9d63b341e825728120ec7b4eefda496ad32428 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 15 Sep 2023 12:02:11 +0200 Subject: taler-util: fix time conversion --- packages/taler-util/src/time.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts index a63f9b296..c677d52ae 100644 --- a/packages/taler-util/src/time.ts +++ b/packages/taler-util/src/time.ts @@ -92,7 +92,7 @@ export namespace TalerPreciseTimestamp { export function fromMilliseconds(ms: number): TalerPreciseTimestamp { return { t_s: Math.floor(ms / 1000), - off_us: Math.floor((ms - Math.floor(ms / 100) * 1000) * 1000), + off_us: Math.floor((ms - Math.floor(ms / 1000) * 1000) * 1000), }; } } -- cgit v1.2.3 From 0ff189d229b348422239670223b4944b42596f63 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 15 Sep 2023 17:04:44 +0200 Subject: wallet-core: fix tipping --- packages/taler-util/src/MerchantApiClient.ts | 2 +- packages/taler-wallet-core/src/dbless.ts | 5 ++++- packages/taler-wallet-core/src/operations/reward.ts | 7 +++++-- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/MerchantApiClient.ts b/packages/taler-util/src/MerchantApiClient.ts index ccbbf79b3..988872ae7 100644 --- a/packages/taler-util/src/MerchantApiClient.ts +++ b/packages/taler-util/src/MerchantApiClient.ts @@ -269,7 +269,7 @@ export class MerchantApiClient { } async giveTip(req: RewardCreateRequest): Promise { - const reqUrl = new URL(`private/tips`, this.baseUrl); + const reqUrl = new URL(`private/rewards`, this.baseUrl); const resp = await this.httpClient.fetch(reqUrl.href, { method: "POST", body: req, diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index d70eab888..4d2fa5cd4 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -276,7 +276,10 @@ export async function depositCoin(args: { merchant_pub: merchantPub, }; const url = new URL(`batch-deposit`, dp.exchange_url); - const httpResp = await http.fetch(url.href, { body: requestBody }); + const httpResp = await http.fetch(url.href, { + method: "POST", + body: requestBody, + }); await readSuccessResponseJsonOrThrow(httpResp, codecForBatchDepositSuccess()); } diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts index ddcfb20ac..4e16d977d 100644 --- a/packages/taler-wallet-core/src/operations/reward.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -304,13 +304,16 @@ export async function processTip( } const tipStatusUrl = new URL( - `tips/${tipRecord.merchantRewardId}/pickup`, + `rewards/${tipRecord.merchantRewardId}/pickup`, tipRecord.merchantBaseUrl, ); const req = { planchets: planchetsDetail }; logger.trace(`sending tip request: ${j2s(req)}`); - const merchantResp = await ws.http.postJson(tipStatusUrl.href, req); + const merchantResp = await ws.http.fetch(tipStatusUrl.href, { + method: "POST", + body: req, + }); logger.trace(`got tip response, status ${merchantResp.status}`); -- cgit v1.2.3 From 58debefbe0456ce203877f1cc417c42f4abb0685 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 21 Sep 2023 17:56:29 +0200 Subject: wallet-core,harness: towards corebank API instead of fakebank/nexus API --- packages/demobank-ui/src/hooks/access.ts | 1 + packages/taler-harness/src/harness/harness.ts | 11 +- packages/taler-harness/src/harness/helpers.ts | 4 +- .../taler-harness/src/harness/libeufin-apis.ts | 775 --------------- packages/taler-harness/src/harness/libeufin.ts | 1047 -------------------- packages/taler-harness/src/index.ts | 4 +- .../test-age-restrictions-merchant.ts | 4 +- .../src/integrationtests/test-bank-api.ts | 4 +- .../integrationtests/test-exchange-management.ts | 4 +- .../taler-harness/src/integrationtests/test-kyc.ts | 4 +- .../test-libeufin-api-bankaccount.ts | 108 -- .../test-libeufin-api-bankconnection.ts | 56 -- .../test-libeufin-api-facade-bad-request.ts | 68 -- .../integrationtests/test-libeufin-api-facade.ts | 70 -- .../test-libeufin-api-permissions.ts | 65 -- .../test-libeufin-api-sandbox-camt.ts | 76 -- .../test-libeufin-api-sandbox-transactions.ts | 69 -- .../test-libeufin-api-scheduling.ts | 106 -- .../integrationtests/test-libeufin-api-users.ts | 63 -- .../integrationtests/test-libeufin-bad-gateway.ts | 75 -- .../src/integrationtests/test-libeufin-basic.ts | 317 ------ .../src/integrationtests/test-libeufin-c5x.ts | 147 --- .../test-libeufin-facade-anastasis.ts | 179 ---- .../integrationtests/test-libeufin-keyrotation.ts | 82 -- .../test-libeufin-nexus-balance.ts | 117 --- .../test-libeufin-refund-multiple-users.ts | 104 -- .../src/integrationtests/test-libeufin-refund.ts | 101 -- .../test-libeufin-sandbox-wire-transfer-cli.ts | 85 -- .../src/integrationtests/test-libeufin-tutorial.ts | 130 --- .../src/integrationtests/test-payment-fault.ts | 4 +- .../src/integrationtests/test-tipping.ts | 4 +- .../integrationtests/test-wallet-notifications.ts | 4 +- .../integrationtests/test-withdrawal-abort-bank.ts | 4 +- .../test-withdrawal-bank-integrated.ts | 4 +- .../integrationtests/test-withdrawal-fakebank.ts | 5 +- .../src/integrationtests/test-withdrawal-fees.ts | 4 +- .../src/integrationtests/test-withdrawal-manual.ts | 4 +- .../src/integrationtests/testrunner.ts | 38 - packages/taler-util/src/bank-api-client.ts | 126 ++- packages/taler-util/src/wallet-types.ts | 8 +- packages/taler-wallet-core/src/dbless.ts | 4 +- .../taler-wallet-core/src/operations/testing.ts | 21 +- packages/taler-wallet-core/src/wallet.ts | 18 +- 43 files changed, 166 insertions(+), 3958 deletions(-) delete mode 100644 packages/taler-harness/src/harness/libeufin-apis.ts delete mode 100644 packages/taler-harness/src/harness/libeufin.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-bankaccount.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-bankconnection.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-facade-bad-request.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-facade.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-permissions.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-camt.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-transactions.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-scheduling.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-api-users.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-bad-gateway.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-basic.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-c5x.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-facade-anastasis.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-keyrotation.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-nexus-balance.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-refund-multiple-users.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-refund.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-sandbox-wire-transfer-cli.ts delete mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-tutorial.ts (limited to 'packages/taler-util') diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts index b8b6ab899..61f458e51 100644 --- a/packages/demobank-ui/src/hooks/access.ts +++ b/packages/demobank-ui/src/hooks/access.ts @@ -124,6 +124,7 @@ export function useTestingAPI(): TestingAPI { const register = async ( data: SandboxBackend.Access.BankRegistrationRequest, ): Promise> => { + // FIXME: This API is deprecated. The normal account registration API should be used instead. const res = await noAuthRequest(`access-api/testing/register`, { method: "POST", data, diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 0c3c367af..edb0071c8 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -28,7 +28,7 @@ import { AccountAddDetails, AmountJson, Amounts, - BankAccessApiClient, + TalerCorebankApiClient, Configuration, CoreApiResponse, Duration, @@ -650,8 +650,7 @@ export class FakebankService } get bankAccessApiBaseUrl(): string { - let url = new URL("taler-bank-access/", this.baseUrl); - return url.href; + return this.baseUrl; } async createExchangeAccount( @@ -666,7 +665,7 @@ export class FakebankService accountName: accountName, accountPassword: password, accountPaytoUri: getPayto(accountName), - wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`, + wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/accounts/${accountName}/taler-wire-gateway/`, }; } @@ -691,14 +690,14 @@ export class FakebankService "bank", ); await this.pingUntilAvailable(); - const bankClient = new BankAccessApiClient(this.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(this.bankAccessApiBaseUrl); for (const acc of this.accounts) { await bankClient.registerAccount(acc.accountName, acc.accountPassword); } } async pingUntilAvailable(): Promise { - const url = `http://localhost:${this.bankConfig.httpPort}/taler-bank-integration/config`; + const url = `http://localhost:${this.bankConfig.httpPort}/config`; await pingProc(this.proc, url, "bank"); } } diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 9892e600b..0a864cad3 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -25,7 +25,7 @@ */ import { AmountString, - BankAccessApiClient, + TalerCorebankApiClient, ConfirmPayResultType, Duration, Logger, @@ -560,7 +560,7 @@ export async function withdrawViaBankV2( ): Promise { const { walletClient: wallet, bank, exchange, amount } = p; - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation(user.username, amount); diff --git a/packages/taler-harness/src/harness/libeufin-apis.ts b/packages/taler-harness/src/harness/libeufin-apis.ts deleted file mode 100644 index 0193f9252..000000000 --- a/packages/taler-harness/src/harness/libeufin-apis.ts +++ /dev/null @@ -1,775 +0,0 @@ -/** - * This file defines most of the API calls offered - * by Nexus and Sandbox. They don't have state, - * therefore got moved away from libeufin.ts where - * the services get actually started and managed. - */ - -import { URL } from "@gnu-taler/taler-util"; -import { - createPlatformHttpLib, - makeBasicAuthHeader, -} from "@gnu-taler/taler-util/http"; -import { - LibeufinNexusTransactions, - LibeufinSandboxAdminBankAccountBalance, - NexusBankConnections, - NexusFacadeListResponse, - NexusGetPermissionsResponse, - NexusNewTransactionsInfo, - NexusTask, - NexusTaskCollection, - NexusUserResponse, -} from "./libeufin.js"; - -export interface LibeufinSandboxServiceInterface { - baseUrl: string; -} - -export interface LibeufinNexusServiceInterface { - baseUrl: string; -} - -export interface CreateEbicsSubscriberRequest { - hostID: string; - userID: string; - partnerID: string; - systemID?: string; -} - -export interface BankAccountInfo { - iban: string; - bic: string; - name: string; - label: string; -} - -export interface CreateEbicsBankConnectionRequest { - name: string; // connection name. - ebicsURL: string; - hostID: string; - userID: string; - partnerID: string; - systemID?: string; -} - -export interface UpdateNexusUserRequest { - newPassword: string; -} - -export interface NexusAuth { - auth: { - username: string; - password: string; - }; -} - -export interface PostNexusTaskRequest { - name: string; - cronspec: string; - type: string; // fetch | submit - params: - | { - level: string; // report | statement | all - rangeType: string; // all | since-last | previous-days | latest - } - | {}; -} - -export interface CreateNexusUserRequest { - username: string; - password: string; -} - -export interface PostNexusPermissionRequest { - action: "revoke" | "grant"; - permission: { - subjectType: string; - subjectId: string; - resourceType: string; - resourceId: string; - permissionName: string; - }; -} - -export interface CreateAnastasisFacadeRequest { - name: string; - connectionName: string; - accountName: string; - currency: string; - reserveTransferLevel: "report" | "statement" | "notification"; -} - -export interface CreateTalerWireGatewayFacadeRequest { - name: string; - connectionName: string; - accountName: string; - currency: string; - reserveTransferLevel: "report" | "statement" | "notification"; -} - -export interface SandboxAccountTransactions { - payments: { - accountLabel: string; - creditorIban: string; - creditorBic?: string; - creditorName: string; - debtorIban: string; - debtorBic: string; - debtorName: string; - amount: string; - currency: string; - subject: string; - date: string; - creditDebitIndicator: "debit" | "credit"; - accountServicerReference: string; - }[]; -} - -export interface DeleteBankConnectionRequest { - bankConnectionId: string; -} - -export interface SimulateIncomingTransactionRequest { - debtorIban: string; - debtorBic: string; - debtorName: string; - - /** - * Subject / unstructured remittance info. - */ - subject: string; - - /** - * Decimal amount without currency. - */ - amount: string; -} - -export interface CreateEbicsBankAccountRequest { - subscriber: { - hostID: string; - partnerID: string; - userID: string; - systemID?: string; - }; - // IBAN - iban: string; - // BIC - bic: string; - // human name - name: string; - label: string; -} - -export interface LibeufinSandboxAddIncomingRequest { - creditorIban: string; - creditorBic: string; - creditorName: string; - debtorIban: string; - debtorBic: string; - debtorName: string; - subject: string; - amount: string; - currency: string; - uid: string; - direction: string; -} - -const libeufinHarnessHttpLib = createPlatformHttpLib(); - -/** - * APIs spread across Legacy and Access, it is therefore - * the "base URL" relative to which API every call addresses. - */ -export namespace LibeufinSandboxApi { - // Creates one bank account via the Access API. - // Need the /demobanks/$id/access-api as the base URL - export async function createDemobankAccount( - username: string, - password: string, - libeufinSandboxService: LibeufinSandboxServiceInterface, - iban: string | null = null, - ): Promise { - let url = new URL("testing/register", libeufinSandboxService.baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: { - username: username, - password: password, - iban: iban, - }, - }); - } - // Need /demobanks/$id as the base URL - export async function createDemobankEbicsSubscriber( - req: CreateEbicsSubscriberRequest, - demobankAccountLabel: string, - libeufinSandboxService: LibeufinSandboxServiceInterface, - username: string = "admin", - password: string = "secret", - ): Promise { - // baseUrl should already be pointed to one demobank. - let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: { - userID: req.userID, - hostID: req.hostID, - partnerID: req.partnerID, - demobankAccountLabel: demobankAccountLabel, - }, - }); - } - - export async function rotateKeys( - libeufinSandboxService: LibeufinSandboxServiceInterface, - hostID: string, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL(`admin/ebics/hosts/${hostID}/rotate-keys`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: {}, - }); - } - export async function createEbicsHost( - libeufinSandboxService: LibeufinSandboxServiceInterface, - hostID: string, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL("admin/ebics/hosts", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: { - hostID, - ebicsVersion: "2.5", - }, - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - export async function createBankAccount( - libeufinSandboxService: LibeufinSandboxServiceInterface, - req: BankAccountInfo, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL(`admin/bank-accounts/${req.label}`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: req, - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - /** - * This function is useless. It creates a Ebics subscriber - * but never gives it a bank account. To be removed - */ - export async function createEbicsSubscriber( - libeufinSandboxService: LibeufinSandboxServiceInterface, - req: CreateEbicsSubscriberRequest, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL("admin/ebics/subscribers", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: req, - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - /** - * Create a new bank account and associate it to - * a existing EBICS subscriber. - */ - export async function createEbicsBankAccount( - libeufinSandboxService: LibeufinSandboxServiceInterface, - req: CreateEbicsBankAccountRequest, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL("admin/ebics/bank-accounts", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: req, - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - export async function simulateIncomingTransaction( - libeufinSandboxService: LibeufinSandboxServiceInterface, - accountLabel: string, - req: SimulateIncomingTransactionRequest, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL( - `admin/bank-accounts/${accountLabel}/simulate-incoming-transaction`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - body: req, - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - export async function getAccountTransactions( - libeufinSandboxService: LibeufinSandboxServiceInterface, - accountLabel: string, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL( - `admin/bank-accounts/${accountLabel}/transactions`, - baseUrl, - ); - const res = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return (await res.json()) as SandboxAccountTransactions; - } - - export async function getCamt053( - libeufinSandboxService: LibeufinSandboxServiceInterface, - accountLabel: string, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL("admin/payments/camt", baseUrl); - return await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - bankaccount: accountLabel, - type: 53, - }, - }); - } - - export async function getAccountInfoWithBalance( - libeufinSandboxService: LibeufinSandboxServiceInterface, - accountLabel: string, - ): Promise { - const baseUrl = libeufinSandboxService.baseUrl; - let url = new URL(`admin/bank-accounts/${accountLabel}`, baseUrl); - const res = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return res.json(); - } -} - -export namespace LibeufinNexusApi { - export async function getAllConnections( - nexus: LibeufinNexusServiceInterface, - ): Promise { - let url = new URL("bank-connections", nexus.baseUrl); - const res = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return res.json(); - } - - export async function deleteBankConnection( - libeufinNexusService: LibeufinNexusServiceInterface, - req: DeleteBankConnectionRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL("bank-connections/delete-connection", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: req, - }); - } - - export async function createEbicsBankConnection( - libeufinNexusService: LibeufinNexusServiceInterface, - req: CreateEbicsBankConnectionRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL("bank-connections", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - source: "new", - type: "ebics", - name: req.name, - data: { - ebicsURL: req.ebicsURL, - hostID: req.hostID, - userID: req.userID, - partnerID: req.partnerID, - systemID: req.systemID, - }, - }, - }); - } - - export async function getBankAccount( - libeufinNexusService: LibeufinNexusServiceInterface, - accountName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`bank-accounts/${accountName}`, baseUrl); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return resp.json(); - } - - export async function submitInitiatedPayment( - libeufinNexusService: LibeufinNexusServiceInterface, - accountName: string, - paymentId: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `bank-accounts/${accountName}/payment-initiations/${paymentId}/submit`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: {}, - }); - } - - export async function fetchAccounts( - libeufinNexusService: LibeufinNexusServiceInterface, - connectionName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `bank-connections/${connectionName}/fetch-accounts`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: {}, - }); - } - - export async function importConnectionAccount( - libeufinNexusService: LibeufinNexusServiceInterface, - connectionName: string, - offeredAccountId: string, - nexusBankAccountId: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `bank-connections/${connectionName}/import-account`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - offeredAccountId, - nexusBankAccountId, - }, - }); - } - - export async function connectBankConnection( - libeufinNexusService: LibeufinNexusServiceInterface, - connectionName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`bank-connections/${connectionName}/connect`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: {}, - }); - } - - export async function getPaymentInitiations( - libeufinNexusService: LibeufinNexusServiceInterface, - accountName: string, - username: string = "admin", - password: string = "test", - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `/bank-accounts/${accountName}/payment-initiations`, - baseUrl, - ); - let response = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - const respJson = await response.json(); - console.log( - `Payment initiations of: ${accountName}`, - JSON.stringify(respJson, null, 2), - ); - } - - // Uses the Anastasis API to get a list of transactions. - export async function getAnastasisTransactions( - libeufinNexusService: LibeufinNexusServiceInterface, - anastasisBaseUrl: string, - // FIXME: Nail down type! - params: {}, // of the request: {delta: 5, ..} - username: string = "admin", - password: string = "test", - ): Promise { - let url = new URL("history/incoming", anastasisBaseUrl); - for (const [k, v] of Object.entries(params)) { - url.searchParams.set(k, String(v)); - } - let response = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return response.json(); - } - - // FIXME: this function should return some structured - // object that represents a history. - export async function getAccountTransactions( - libeufinNexusService: LibeufinNexusServiceInterface, - accountName: string, - username: string = "admin", - password: string = "test", - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/bank-accounts/${accountName}/transactions`, baseUrl); - let response = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return response.json(); - } - - export async function fetchTransactions( - libeufinNexusService: LibeufinNexusServiceInterface, - accountName: string, - rangeType: string = "all", - level: string = "report", - username: string = "admin", - password: string = "test", - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `/bank-accounts/${accountName}/fetch-transactions`, - baseUrl, - ); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - rangeType: rangeType, - level: level, - }, - }); - return resp.json(); - } - - export async function changePassword( - libeufinNexusService: LibeufinNexusServiceInterface, - username: string, - req: UpdateNexusUserRequest, - auth: NexusAuth, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/users/${username}/password`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: req, - }); - } - - export async function getUser( - libeufinNexusService: LibeufinNexusServiceInterface, - auth: NexusAuth, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/user`, baseUrl); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return resp.json(); - } - - export async function createUser( - libeufinNexusService: LibeufinNexusServiceInterface, - req: CreateNexusUserRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/users`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: req, - }); - } - - export async function getAllPermissions( - libeufinNexusService: LibeufinNexusServiceInterface, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/permissions`, baseUrl); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return resp.json(); - } - - export async function postPermission( - libeufinNexusService: LibeufinNexusServiceInterface, - req: PostNexusPermissionRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/permissions`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: req, - }); - } - - export async function getAllTasks( - libeufinNexusService: LibeufinNexusServiceInterface, - bankAccountName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return resp.json(); - } - - export async function getTask( - libeufinNexusService: LibeufinNexusServiceInterface, - bankAccountName: string, - // When void, the request returns the list of all the - // tasks under this bank account. - taskName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `/bank-accounts/${bankAccountName}/schedule/${taskName}`, - baseUrl, - ); - if (taskName) url = new URL(taskName, `${url.href}/`); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - return resp.json(); - } - - export async function deleteTask( - libeufinNexusService: LibeufinNexusServiceInterface, - bankAccountName: string, - taskName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `/bank-accounts/${bankAccountName}/schedule/${taskName}`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "DELETE", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - export async function postTask( - libeufinNexusService: LibeufinNexusServiceInterface, - bankAccountName: string, - req: PostNexusTaskRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: req, - }); - } - - export async function deleteFacade( - libeufinNexusService: LibeufinNexusServiceInterface, - facadeName: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL(`facades/${facadeName}`, baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "DELETE", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - } - - export async function getAllFacades( - libeufinNexusService: LibeufinNexusServiceInterface, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL("facades", baseUrl); - const resp = await libeufinHarnessHttpLib.fetch(url.href, { - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - }); - // FIXME: Just return validated, typed response here! - return resp.json(); - } - - export async function createAnastasisFacade( - libeufinNexusService: LibeufinNexusServiceInterface, - req: CreateAnastasisFacadeRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL("facades", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - name: req.name, - type: "anastasis", - config: { - bankAccount: req.accountName, - bankConnection: req.connectionName, - currency: req.currency, - reserveTransferLevel: req.reserveTransferLevel, - }, - }, - }); - } - - export async function createTwgFacade( - libeufinNexusService: LibeufinNexusServiceInterface, - req: CreateTalerWireGatewayFacadeRequest, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL("facades", baseUrl); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: { - name: req.name, - type: "taler-wire-gateway", - config: { - bankAccount: req.accountName, - bankConnection: req.connectionName, - currency: req.currency, - reserveTransferLevel: req.reserveTransferLevel, - }, - }, - }); - } - - export async function submitAllPaymentInitiations( - libeufinNexusService: LibeufinNexusServiceInterface, - accountId: string, - ): Promise { - const baseUrl = libeufinNexusService.baseUrl; - let url = new URL( - `/bank-accounts/${accountId}/submit-all-payment-initiations`, - baseUrl, - ); - await libeufinHarnessHttpLib.fetch(url.href, { - method: "POST", - headers: { Authorization: makeBasicAuthHeader("admin", "secret") }, - body: {}, - }); - } -} diff --git a/packages/taler-harness/src/harness/libeufin.ts b/packages/taler-harness/src/harness/libeufin.ts deleted file mode 100644 index caeea85ae..000000000 --- a/packages/taler-harness/src/harness/libeufin.ts +++ /dev/null @@ -1,1047 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 - */ - -/** - * This file defines euFin test logic that needs state - * and that depends on the main harness.ts. The other - * definitions - mainly helper functions to call RESTful - * APIs - moved to libeufin-apis.ts. That enables harness.ts - * to depend on such API calls, in contrast to the previous - * situation where harness.ts had to include this file causing - * a circular dependency. */ - -/** - * Imports. - */ -import { AmountString, Logger } from "@gnu-taler/taler-util"; -import { - DbInfo, - GlobalTestState, - ProcessWrapper, - getRandomIban, - pingProc, - runCommand, - setupDb, - sh, -} from "../harness/harness.js"; -import { - CreateAnastasisFacadeRequest, - CreateEbicsBankAccountRequest, - CreateEbicsBankConnectionRequest, - CreateNexusUserRequest, - CreateTalerWireGatewayFacadeRequest, - LibeufinNexusApi, - LibeufinSandboxApi, - LibeufinSandboxServiceInterface, - PostNexusPermissionRequest, -} from "../harness/libeufin-apis.js"; - -const logger = new Logger("libeufin.ts"); - -export { LibeufinNexusApi, LibeufinSandboxApi }; - -export interface LibeufinServices { - libeufinSandbox: LibeufinSandboxService; - libeufinNexus: LibeufinNexusService; - commonDb: DbInfo; -} - -export interface LibeufinSandboxConfig { - httpPort: number; - databaseJdbcUri: string; -} - -export interface LibeufinNexusConfig { - httpPort: number; - databaseJdbcUri: string; -} - -export interface LibeufinNexusMoneyMovement { - amount: string; - creditDebitIndicator: string; - details: { - debtor: { - name: string; - }; - debtorAccount: { - iban: string; - }; - debtorAgent: { - bic: string; - }; - creditor: { - name: string; - }; - creditorAccount: { - iban: string; - }; - creditorAgent: { - bic: string; - }; - endToEndId: string; - unstructuredRemittanceInformation: string; - }; -} - -export interface LibeufinNexusBatches { - batchTransactions: Array; -} - -export interface LibeufinNexusTransaction { - amount: string; - creditDebitIndicator: string; - status: string; - bankTransactionCode: string; - valueDate: string; - bookingDate: string; - accountServicerRef: string; - batches: Array; -} - -export interface LibeufinNexusTransactions { - transactions: Array; -} - -export interface LibeufinCliDetails { - nexusUrl: string; - sandboxUrl: string; - nexusDatabaseUri: string; - sandboxDatabaseUri: string; - nexusUser: LibeufinNexusUser; -} - -export interface LibeufinEbicsSubscriberDetails { - hostId: string; - partnerId: string; - userId: string; -} - -export interface LibeufinEbicsConnectionDetails { - subscriberDetails: LibeufinEbicsSubscriberDetails; - ebicsUrl: string; - connectionName: string; -} - -export interface LibeufinBankAccountDetails { - currency: string; - iban: string; - bic: string; - personName: string; - accountName: string; -} - -export interface LibeufinNexusUser { - username: string; - password: string; -} - -export interface LibeufinBackupFileDetails { - passphrase: string; - outputFile: string; - connectionName: string; -} - -export interface LibeufinKeyLetterDetails { - outputFile: string; - connectionName: string; -} - -export interface LibeufinBankAccountImportDetails { - offeredBankAccountName: string; - nexusBankAccountName: string; - connectionName: string; -} - -export interface LibeufinPreparedPaymentDetails { - creditorIban: string; - creditorBic: string; - creditorName: string; - subject: string; - amount: string; - currency: string; - nexusBankAccountName: string; -} - -export interface NexusBankConnection { - // connection type. For example "ebics". - type: string; - - // connection name as given by the user at - // the moment of creation. - name: string; -} - -export interface NexusBankConnections { - bankConnections: NexusBankConnection[]; -} - -export interface FacadeShowInfo { - // Name of the facade, same as the "fcid" parameter. - name: string; - - // Type of the facade. - // For example, "taler-wire-gateway". - type: string; - - // Bas URL of the facade. - baseUrl: string; - - // details depending on the facade type. - config: any; -} - -export interface FetchParams { - // Because transactions are delivered by banks in "batches", - // then every batch can have different qualities. This value - // lets the request specify which type of batch ought to be - // returned. Currently, the following two type are supported: - // - // 'report': typically includes only non booked transactions. - // 'statement': typically includes only booked transactions. - level: "report" | "statement" | "all"; - - // This type indicates the time range of the query. - // It allows the following values: - // - // 'latest': retrieves the last transactions from the bank. - // If there are older unread transactions, those will *not* - // be downloaded. - // - // 'all': retrieves all the transactions from the bank, - // until the oldest. - // - // 'previous-days': currently *not* implemented, it will allow - // the request to download transactions from - // today until N days before. - // - // 'since-last': retrieves all the transactions since the last - // time one was downloaded. - // - rangeType: "latest" | "all" | "previous-days" | "since-last"; -} - -export interface NexusTask { - // The resource being impacted by this operation. - // Typically a (Nexus) bank account being fetched - // or whose payments are submitted. In this cases, - // this value is the "bank-account" constant. - resourceType: string; - // Name of the resource. In case of "bank-account", that - // is the name under which the bank account was imported - // from the bank. - resourceId: string; - // Task name, equals 'taskId' - taskName: string; - // Values allowed are "fetch" or "submit". - taskType: string; - // FIXME: describe. - taskCronSpec: string; - // Only meaningful for "fetch" types. - taskParams: FetchParams; - // Timestamp in seconds when the next iteration will run. - nextScheduledExecutionSec: number; - // Timestamp in seconds when the previous iteration ran. - prevScheduledExecutionSec: number; -} - -export interface NexusNewTransactionsInfo { - // How many transactions are new to Nexus. - newTransactions: number; - // How many transactions got downloaded by the request. - // Note that a transaction can be downloaded multiple - // times but only counts as new once. - downloadedTransactions: number; -} - - -export interface NexusUserResponse { - // User name - username: string; - - // Is this a super user? - superuser: boolean; -} - -export interface NexusTaskShortInfo { - cronspec: string; - type: "fetch" | "submit"; - params: FetchParams; -} - -export interface NexusTaskCollection { - // This field can contain *multiple* objects of the type sampled below. - schedule: { - [taskName: string]: NexusTaskShortInfo; - }; -} - -export interface NexusFacadeListResponse { - facades: FacadeShowInfo[]; -} - -export interface LibeufinSandboxAdminBankAccountBalance { - // Balance in the $currency:$amount format. - balance: AmountString; - // IBAN of the bank account identified by $accountLabel - iban: string; - // BIC of the bank account identified by $accountLabel - bic: string; - // Mentions $accountLabel - label: string; -} - -export interface LibeufinPermission { - subjectType: string; - subjectId: string; - resourceType: string; - resourceId: string; - permissionName: string; -} - -export interface NexusGetPermissionsResponse { - permissions: LibeufinPermission[]; -} - -export class LibeufinSandboxService implements LibeufinSandboxServiceInterface { - static async create( - gc: GlobalTestState, - sandboxConfig: LibeufinSandboxConfig, - ): Promise { - return new LibeufinSandboxService(gc, sandboxConfig); - } - - sandboxProc: ProcessWrapper | undefined; - globalTestState: GlobalTestState; - - constructor( - gc: GlobalTestState, - private sandboxConfig: LibeufinSandboxConfig, - ) { - this.globalTestState = gc; - } - - get baseUrl(): string { - return `http://localhost:${this.sandboxConfig.httpPort}/`; - } - - async start(): Promise { - await sh( - this.globalTestState, - "libeufin-sandbox-config", - "libeufin-sandbox config default", - { - ...process.env, - LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxConfig.databaseJdbcUri, - }, - ); - - this.sandboxProc = this.globalTestState.spawnService( - "libeufin-sandbox", - ["serve", "--port", `${this.sandboxConfig.httpPort}`], - "libeufin-sandbox", - { - ...process.env, - LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxConfig.databaseJdbcUri, - LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret", - }, - ); - } - - async c53tick(): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-sandbox-c53tick", - "libeufin-sandbox camt053tick", - { - ...process.env, - LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxConfig.databaseJdbcUri, - }, - ); - return stdout; - } - - async makeTransaction( - debit: string, - credit: string, - amount: string, // $currency:x.y - subject: string, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-sandbox-maketransfer", - `libeufin-sandbox make-transaction --debit-account=${debit} --credit-account=${credit} ${amount} "${subject}"`, - { - ...process.env, - LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxConfig.databaseJdbcUri, - }, - ); - return stdout; - } - - async pingUntilAvailable(): Promise { - const url = this.baseUrl; - await pingProc(this.sandboxProc, url, "libeufin-sandbox"); - } -} - -export class LibeufinNexusService { - static async create( - gc: GlobalTestState, - nexusConfig: LibeufinNexusConfig, - ): Promise { - return new LibeufinNexusService(gc, nexusConfig); - } - - nexusProc: ProcessWrapper | undefined; - globalTestState: GlobalTestState; - - constructor(gc: GlobalTestState, private nexusConfig: LibeufinNexusConfig) { - this.globalTestState = gc; - } - - get baseUrl(): string { - return `http://localhost:${this.nexusConfig.httpPort}/`; - } - - async start(): Promise { - await runCommand( - this.globalTestState, - "libeufin-nexus-superuser", - "libeufin-nexus", - ["superuser", "admin", "--password", "test"], - { - ...process.env, - LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusConfig.databaseJdbcUri, - }, - ); - - this.nexusProc = this.globalTestState.spawnService( - "libeufin-nexus", - ["serve", "--port", `${this.nexusConfig.httpPort}`], - "libeufin-nexus", - { - ...process.env, - LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusConfig.databaseJdbcUri, - }, - ); - } - - async pingUntilAvailable(): Promise { - const url = `${this.baseUrl}config`; - await pingProc(this.nexusProc, url, "libeufin-nexus"); - } - - async createNexusSuperuser(details: LibeufinNexusUser): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-nexus", - `libeufin-nexus superuser ${details.username} --password=${details.password}`, - { - ...process.env, - LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusConfig.databaseJdbcUri, - }, - ); - console.log(stdout); - } -} - -export interface TwgAddIncomingRequest { - amount: string; - reserve_pub: string; - debit_account: string; -} - -/** - * The bundle aims at minimizing the amount of input - * data that is required to initialize a new user + Ebics - * connection. - */ -export class NexusUserBundle { - userReq: CreateNexusUserRequest; - connReq: CreateEbicsBankConnectionRequest; - anastasisReq: CreateAnastasisFacadeRequest; - twgReq: CreateTalerWireGatewayFacadeRequest; - twgTransferPermission: PostNexusPermissionRequest; - twgHistoryPermission: PostNexusPermissionRequest; - twgAddIncomingPermission: PostNexusPermissionRequest; - localAccountName: string; - remoteAccountName: string; - - constructor(salt: string, ebicsURL: string) { - this.userReq = { - username: `username-${salt}`, - password: `password-${salt}`, - }; - - this.connReq = { - name: `connection-${salt}`, - ebicsURL: ebicsURL, - hostID: `ebicshost,${salt}`, - partnerID: `ebicspartner,${salt}`, - userID: `ebicsuser,${salt}`, - }; - - this.twgReq = { - currency: "EUR", - name: `twg-${salt}`, - reserveTransferLevel: "report", - accountName: `local-account-${salt}`, - connectionName: `connection-${salt}`, - }; - this.anastasisReq = { - currency: "EUR", - name: `anastasis-${salt}`, - reserveTransferLevel: "report", - accountName: `local-account-${salt}`, - connectionName: `connection-${salt}`, - }; - this.remoteAccountName = `remote-account-${salt}`; - this.localAccountName = `local-account-${salt}`; - this.twgTransferPermission = { - action: "grant", - permission: { - subjectId: `username-${salt}`, - subjectType: "user", - resourceType: "facade", - resourceId: `twg-${salt}`, - permissionName: "facade.talerWireGateway.transfer", - }, - }; - this.twgHistoryPermission = { - action: "grant", - permission: { - subjectId: `username-${salt}`, - subjectType: "user", - resourceType: "facade", - resourceId: `twg-${salt}`, - permissionName: "facade.talerWireGateway.history", - }, - }; - } -} - -/** - * The bundle aims at minimizing the amount of input - * data that is required to initialize a new Sandbox - * customer, associating their bank account with a Ebics - * subscriber. - */ -export class SandboxUserBundle { - ebicsBankAccount: CreateEbicsBankAccountRequest; - constructor(salt: string) { - this.ebicsBankAccount = { - bic: "BELADEBEXXX", - iban: getRandomIban(), - label: `remote-account-${salt}`, - name: `Taler Exchange: ${salt}`, - subscriber: { - hostID: `ebicshost,${salt}`, - partnerID: `ebicspartner,${salt}`, - userID: `ebicsuser,${salt}`, - }, - }; - } -} - -export class LibeufinCli { - cliDetails: LibeufinCliDetails; - globalTestState: GlobalTestState; - - constructor(gc: GlobalTestState, cd: LibeufinCliDetails) { - this.globalTestState = gc; - this.cliDetails = cd; - } - - env(): any { - return { - ...process.env, - LIBEUFIN_SANDBOX_URL: this.cliDetails.sandboxUrl, - LIBEUFIN_SANDBOX_USERNAME: "admin", - LIBEUFIN_SANDBOX_PASSWORD: "secret", - }; - } - - async checkSandbox(): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-checksandbox", - "libeufin-cli sandbox check", - this.env(), - ); - } - - async registerBankCustomer( - username: string, - password: string, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-registercustomer", - "libeufin-cli sandbox demobank register --name='Test Customer'", - { - ...process.env, - LIBEUFIN_SANDBOX_URL: this.cliDetails.sandboxUrl + "/demobanks/default", - LIBEUFIN_SANDBOX_USERNAME: username, - LIBEUFIN_SANDBOX_PASSWORD: password, - }, - ); - console.log(stdout); - } - - async createEbicsHost(hostId: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createebicshost", - `libeufin-cli sandbox ebicshost create --host-id=${hostId}`, - this.env(), - ); - console.log(stdout); - } - - async createEbicsSubscriber( - details: LibeufinEbicsSubscriberDetails, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createebicssubscriber", - "libeufin-cli sandbox ebicssubscriber create" + - ` --host-id=${details.hostId}` + - ` --partner-id=${details.partnerId}` + - ` --user-id=${details.userId}`, - this.env(), - ); - console.log(stdout); - } - - async createEbicsBankAccount( - sd: LibeufinEbicsSubscriberDetails, - bankAccountDetails: LibeufinBankAccountDetails, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createebicsbankaccount", - "libeufin-cli sandbox ebicsbankaccount create" + - ` --iban=${bankAccountDetails.iban}` + - ` --bic=${bankAccountDetails.bic}` + - ` --person-name='${bankAccountDetails.personName}'` + - ` --account-name=${bankAccountDetails.accountName}` + - ` --ebics-host-id=${sd.hostId}` + - ` --ebics-partner-id=${sd.partnerId}` + - ` --ebics-user-id=${sd.userId}`, - this.env(), - ); - console.log(stdout); - } - - async generateTransactions(accountName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-generatetransactions", - `libeufin-cli sandbox bankaccount generate-transactions ${accountName}`, - this.env(), - ); - console.log(stdout); - } - - async showSandboxTransactions(accountName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-showsandboxtransactions", - `libeufin-cli sandbox bankaccount transactions ${accountName}`, - this.env(), - ); - console.log(stdout); - } - - async createEbicsConnection( - connectionDetails: LibeufinEbicsConnectionDetails, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createebicsconnection", - `libeufin-cli connections new-ebics-connection` + - ` --ebics-url=${connectionDetails.ebicsUrl}` + - ` --host-id=${connectionDetails.subscriberDetails.hostId}` + - ` --partner-id=${connectionDetails.subscriberDetails.partnerId}` + - ` --ebics-user-id=${connectionDetails.subscriberDetails.userId}` + - ` ${connectionDetails.connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async createBackupFile(details: LibeufinBackupFileDetails): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createbackupfile", - `libeufin-cli connections export-backup` + - ` --passphrase=${details.passphrase}` + - ` --output-file=${details.outputFile}` + - ` ${details.connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async createKeyLetter(details: LibeufinKeyLetterDetails): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-createkeyletter", - `libeufin-cli connections get-key-letter` + - ` ${details.connectionName} ${details.outputFile}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async connect(connectionName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-connect", - `libeufin-cli connections connect ${connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async downloadBankAccounts(connectionName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-downloadbankaccounts", - `libeufin-cli connections download-bank-accounts ${connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async listOfferedBankAccounts(connectionName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-listofferedbankaccounts", - `libeufin-cli connections list-offered-bank-accounts ${connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async importBankAccount( - importDetails: LibeufinBankAccountImportDetails, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-importbankaccount", - "libeufin-cli connections import-bank-account" + - ` --offered-account-id=${importDetails.offeredBankAccountName}` + - ` --nexus-bank-account-id=${importDetails.nexusBankAccountName}` + - ` ${importDetails.connectionName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async fetchTransactions(bankAccountName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-fetchtransactions", - `libeufin-cli accounts fetch-transactions ${bankAccountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async transactions(bankAccountName: string): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-transactions", - `libeufin-cli accounts transactions ${bankAccountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async preparePayment(details: LibeufinPreparedPaymentDetails): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-preparepayment", - `libeufin-cli accounts prepare-payment` + - ` --creditor-iban=${details.creditorIban}` + - ` --creditor-bic=${details.creditorBic}` + - ` --creditor-name='${details.creditorName}'` + - ` --payment-subject='${details.subject}'` + - ` --payment-amount=${details.currency}:${details.amount}` + - ` ${details.nexusBankAccountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async submitPayment( - details: LibeufinPreparedPaymentDetails, - paymentUuid: string, - ): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-submitpayments", - `libeufin-cli accounts submit-payments` + - ` --payment-uuid=${paymentUuid}` + - ` ${details.nexusBankAccountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async newAnastasisFacade(req: NewAnastasisFacadeReq): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-new-anastasis-facade", - `libeufin-cli facades new-anastasis-facade` + - ` --currency ${req.currency}` + - ` --facade-name ${req.facadeName}` + - ` ${req.connectionName} ${req.accountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async newTalerWireGatewayFacade(req: NewTalerWireGatewayReq): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-new-taler-wire-gateway-facade", - `libeufin-cli facades new-taler-wire-gateway-facade` + - ` --currency ${req.currency}` + - ` --facade-name ${req.facadeName}` + - ` ${req.connectionName} ${req.accountName}`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } - - async listFacades(): Promise { - const stdout = await sh( - this.globalTestState, - "libeufin-cli-facades-list", - `libeufin-cli facades list`, - { - ...process.env, - LIBEUFIN_NEXUS_URL: this.cliDetails.nexusUrl, - LIBEUFIN_NEXUS_USERNAME: this.cliDetails.nexusUser.username, - LIBEUFIN_NEXUS_PASSWORD: this.cliDetails.nexusUser.password, - }, - ); - console.log(stdout); - } -} - -interface NewAnastasisFacadeReq { - facadeName: string; - connectionName: string; - accountName: string; - currency: string; -} - -interface NewTalerWireGatewayReq { - facadeName: string; - connectionName: string; - accountName: string; - currency: string; -} - -/** - * Launch Nexus and Sandbox AND creates users / facades / bank accounts / - * .. all that's required to start making bank traffic. - */ -export async function launchLibeufinServices( - t: GlobalTestState, - nexusUserBundle: NexusUserBundle[], - sandboxUserBundle: SandboxUserBundle[] = [], - withFacades: string[] = [], // takes only "twg" and/or "anastasis" -): Promise { - const db = await setupDb(t); - - const libeufinSandbox = await LibeufinSandboxService.create(t, { - httpPort: 5010, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - - await libeufinSandbox.start(); - await libeufinSandbox.pingUntilAvailable(); - - const libeufinNexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - - await libeufinNexus.start(); - await libeufinNexus.pingUntilAvailable(); - console.log("Libeufin services launched!"); - - for (let sb of sandboxUserBundle) { - await LibeufinSandboxApi.createEbicsHost( - libeufinSandbox, - sb.ebicsBankAccount.subscriber.hostID, - ); - await LibeufinSandboxApi.createEbicsSubscriber( - libeufinSandbox, - sb.ebicsBankAccount.subscriber, - ); - await LibeufinSandboxApi.createDemobankAccount( - sb.ebicsBankAccount.label, - "password-unused", - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/access-api/" }, - ); - await LibeufinSandboxApi.createDemobankEbicsSubscriber( - sb.ebicsBankAccount.subscriber, - sb.ebicsBankAccount.label, - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/" }, - ); - } - console.log("Sandbox user(s) / account(s) / subscriber(s): created"); - - for (let nb of nexusUserBundle) { - await LibeufinNexusApi.createEbicsBankConnection(libeufinNexus, nb.connReq); - await LibeufinNexusApi.connectBankConnection( - libeufinNexus, - nb.connReq.name, - ); - await LibeufinNexusApi.fetchAccounts(libeufinNexus, nb.connReq.name); - await LibeufinNexusApi.importConnectionAccount( - libeufinNexus, - nb.connReq.name, - nb.remoteAccountName, - nb.localAccountName, - ); - await LibeufinNexusApi.createUser(libeufinNexus, nb.userReq); - for (let facade of withFacades) { - switch (facade) { - case "twg": - await LibeufinNexusApi.createTwgFacade(libeufinNexus, nb.twgReq); - await LibeufinNexusApi.postPermission( - libeufinNexus, - nb.twgTransferPermission, - ); - await LibeufinNexusApi.postPermission( - libeufinNexus, - nb.twgHistoryPermission, - ); - break; - case "anastasis": - await LibeufinNexusApi.createAnastasisFacade( - libeufinNexus, - nb.anastasisReq, - ); - } - } - } - console.log( - "Nexus user(s) / connection(s) / facade(s) / permission(s): created", - ); - - return { - commonDb: db, - libeufinNexus: libeufinNexus, - libeufinSandbox: libeufinSandbox, - }; -} - -/** - * Helper function that searches a payment among - * a list, as returned by Nexus. The key is just - * the payment subject. - */ -export function findNexusPayment( - key: string, - payments: LibeufinNexusTransactions, -): LibeufinNexusMoneyMovement | void { - let transactions = payments["transactions"]; - for (let i = 0; i < transactions.length; i++) { - //FIXME: last line won't compile with the current definition of the type - //@ts-ignore - let batches = transactions[i]["camtData"]["batches"]; - for (let y = 0; y < batches.length; y++) { - let movements = batches[y]["batchTransactions"]; - for (let z = 0; z < movements.length; z++) { - let movement = movements[z]; - if (movement["details"]["unstructuredRemittanceInformation"] == key) - return movement; - } - } - } -} diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index f5d4fd2c2..8ace45a89 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -20,7 +20,7 @@ import { addPaytoQueryParams, Amounts, - BankAccessApiClient, + TalerCorebankApiClient, Configuration, decodeCrock, j2s, @@ -236,7 +236,7 @@ deploymentCli console.log(tipReserveResp); - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( args.tipTopup.bankAccessUrl, { auth: { 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 7f936a479..90b08724f 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -27,7 +27,7 @@ import { withdrawViaBankV2, } from "../harness/helpers.js"; import { - BankAccessApiClient, + TalerCorebankApiClient, MerchantApiClient, WireGatewayApiClient, } from "@gnu-taler/taler-util"; @@ -179,7 +179,7 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { // Pay with coin from tipping { - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const mbu = await bankClient.createRandomBankUser(); const tipReserveResp = await merchantClient.createTippingReserve({ exchange_url: exchange.baseUrl, diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index a13ff63c7..740e89c30 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, CreditDebitIndicator, WireGatewayApiClient, createEddsaKeyPair, @@ -99,7 +99,7 @@ export async function runBankApiTest(t: GlobalTestState) { console.log("setup done!"); - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const bankUser = await bankClient.registerAccount("user1", "pw1"); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index 9338a8988..329012e42 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, ExchangesListResponse, TalerErrorCode, URL, @@ -263,7 +263,7 @@ export async function runExchangeManagementTest( // Create withdrawal operation - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 1f7358b66..2b2b57183 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, Duration, j2s, Logger, @@ -302,7 +302,7 @@ export async function runKycTest(t: GlobalTestState) { // Withdraw digital cash into the wallet. - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const amount = "TESTKUDOS:20"; const user = await bankClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-bankaccount.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-bankaccount.ts deleted file mode 100644 index e5e3dfe64..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-bankaccount.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - LibeufinNexusApi, - LibeufinNexusService, - LibeufinSandboxService, - LibeufinSandboxApi, - findNexusPayment, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinApiBankaccountTest(t: GlobalTestState) { - const nexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await nexus.start(); - await nexus.pingUntilAvailable(); - - await LibeufinNexusApi.createUser(nexus, { - username: "one", - password: "testing-the-bankaccount-api", - }); - const sandbox = await LibeufinSandboxService.create(t, { - httpPort: 5012, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - await sandbox.start(); - await sandbox.pingUntilAvailable(); - await LibeufinSandboxApi.createEbicsHost(sandbox, "mock"); - await LibeufinSandboxApi.createDemobankAccount( - "mock", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - "DE71500105179674997361", - ); - await LibeufinSandboxApi.createDemobankEbicsSubscriber( - { - hostID: "mock", - partnerID: "mock", - userID: "mock", - }, - "mock", - { baseUrl: sandbox.baseUrl + "/demobanks/default/" }, - ); - await LibeufinNexusApi.createEbicsBankConnection(nexus, { - name: "bankaccount-api-test-connection", - ebicsURL: "http://localhost:5012/ebicsweb", - hostID: "mock", - userID: "mock", - partnerID: "mock", - }); - await LibeufinNexusApi.connectBankConnection( - nexus, - "bankaccount-api-test-connection", - ); - await LibeufinNexusApi.fetchAccounts( - nexus, - "bankaccount-api-test-connection", - ); - - await LibeufinNexusApi.importConnectionAccount( - nexus, - "bankaccount-api-test-connection", - "mock", - "local-mock", - ); - await LibeufinSandboxApi.simulateIncomingTransaction( - sandbox, - "mock", // creditor bankaccount label - { - debtorIban: "DE84500105176881385584", - debtorBic: "BELADEBEXXX", - debtorName: "mock2", - amount: "EUR:1", - subject: "mock subject", - }, - ); - await LibeufinNexusApi.fetchTransactions(nexus, "local-mock"); - let transactions = await LibeufinNexusApi.getAccountTransactions( - nexus, - "local-mock", - ); - let el = findNexusPayment("mock subject", transactions); - t.assertTrue(el instanceof Object); -} - -runLibeufinApiBankaccountTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-bankconnection.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-bankconnection.ts deleted file mode 100644 index 243500dc9..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-bankconnection.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { LibeufinNexusApi, LibeufinNexusService } from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinApiBankconnectionTest(t: GlobalTestState) { - const nexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await nexus.start(); - await nexus.pingUntilAvailable(); - - await LibeufinNexusApi.createUser(nexus, { - username: "one", - password: "testing-the-bankconnection-api", - }); - - await LibeufinNexusApi.createEbicsBankConnection(nexus, { - name: "bankconnection-api-test-connection", - ebicsURL: "http://localhost:5012/ebicsweb", - hostID: "mock", - userID: "mock", - partnerID: "mock", - }); - - let connections = await LibeufinNexusApi.getAllConnections(nexus); - t.assertTrue(connections.bankConnections.length == 1); - - await LibeufinNexusApi.deleteBankConnection(nexus, { - bankConnectionId: "bankconnection-api-test-connection", - }); - connections = await LibeufinNexusApi.getAllConnections(nexus); - t.assertTrue(connections.bankConnections.length == 0); -} -runLibeufinApiBankconnectionTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-facade-bad-request.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-facade-bad-request.ts deleted file mode 100644 index 27cc81588..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-facade-bad-request.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { URL } from "@gnu-taler/taler-util"; -import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; -import { - launchLibeufinServices, - NexusUserBundle, - SandboxUserBundle, -} from "../harness/libeufin.js"; -import { - createPlatformHttpLib, - makeBasicAuthHeader, -} from "@gnu-taler/taler-util/http"; - -export async function runLibeufinApiFacadeBadRequestTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus], - [user01sandbox], - ["twg"], - ); - console.log("malformed facade"); - const baseUrl = libeufinServices.libeufinNexus.baseUrl; - let url = new URL("facades", baseUrl); - let resp = await harnessHttpLib.fetch(url.href, { - method: "POST", - body: { - name: "malformed-facade", - type: "taler-wire-gateway", - config: {}, // malformation here. - }, - headers: { - Authorization: makeBasicAuthHeader("admin", "test"), - }, - }); - t.assertTrue(resp.status == 400); -} - -runLibeufinApiFacadeBadRequestTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-facade.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-facade.ts deleted file mode 100644 index a819dd481..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-facade.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinNexusApi, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinApiFacadeTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus], - [user01sandbox], - ["twg"], - ); - let resp = await LibeufinNexusApi.getAllFacades( - libeufinServices.libeufinNexus, - ); - // check that original facade shows up. - t.assertTrue(resp.facades[0].name == user01nexus.twgReq["name"]); - - const twgBaseUrl: string = resp.facades[0]["baseUrl"]; - t.assertTrue(typeof twgBaseUrl === "string"); - t.assertTrue(twgBaseUrl.startsWith("http://")); - t.assertTrue(twgBaseUrl.endsWith("/")); - - // delete it. - await LibeufinNexusApi.deleteFacade( - libeufinServices.libeufinNexus, - user01nexus.twgReq["name"], - ); - resp = await LibeufinNexusApi.getAllFacades(libeufinServices.libeufinNexus); - t.assertTrue(!resp.hasOwnProperty("facades")); -} - -runLibeufinApiFacadeTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-permissions.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-permissions.ts deleted file mode 100644 index 56443c20a..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-permissions.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - NexusUserBundle, - LibeufinNexusApi, - LibeufinNexusService, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinApiPermissionsTest(t: GlobalTestState) { - const nexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await nexus.start(); - await nexus.pingUntilAvailable(); - - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - - await LibeufinNexusApi.createUser(nexus, user01nexus.userReq); - await LibeufinNexusApi.postPermission( - nexus, - user01nexus.twgTransferPermission, - ); - let transferPermission = await LibeufinNexusApi.getAllPermissions(nexus); - let element = transferPermission["permissions"].pop(); - t.assertTrue(!!element); - t.assertTrue( - element["permissionName"] == "facade.talerwiregateway.transfer" && - element["subjectId"] == "username-01", - ); - let denyTransfer = user01nexus.twgTransferPermission; - - // Now revoke permission. - denyTransfer["action"] = "revoke"; - await LibeufinNexusApi.postPermission(nexus, denyTransfer); - - transferPermission = await LibeufinNexusApi.getAllPermissions(nexus); - t.assertTrue(transferPermission["permissions"].length == 0); -} - -runLibeufinApiPermissionsTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-camt.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-camt.ts deleted file mode 100644 index 22b411dc2..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-camt.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - LibeufinSandboxApi, - LibeufinSandboxService, -} from "../harness/libeufin.js"; - -// This test only checks that LibEuFin doesn't fail when -// it generates Camt statements - no assertions take place. -// Furthermore, it prints the Camt.053 being generated. -export async function runLibeufinApiSandboxCamtTest(t: GlobalTestState) { - const sandbox = await LibeufinSandboxService.create(t, { - httpPort: 5012, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - await sandbox.start(); - await sandbox.pingUntilAvailable(); - - await LibeufinSandboxApi.createDemobankAccount( - "mock-account-0", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - ); - await LibeufinSandboxApi.createDemobankAccount( - "mock-account-1", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - ); - await sandbox.makeTransaction( - "mock-account-0", - "mock-account-1", - "EUR:1", - "+1", - ); - await sandbox.makeTransaction( - "mock-account-0", - "mock-account-1", - "EUR:1", - "+1", - ); - await sandbox.makeTransaction( - "mock-account-0", - "mock-account-1", - "EUR:1", - "+1", - ); - await sandbox.makeTransaction( - "mock-account-1", - "mock-account-0", - "EUR:5", - "minus 5", - ); - await sandbox.c53tick(); - let ret = await LibeufinSandboxApi.getCamt053(sandbox, "mock-account-1"); - console.log(ret); -} -runLibeufinApiSandboxCamtTest.experimental = true; -runLibeufinApiSandboxCamtTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-transactions.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-transactions.ts deleted file mode 100644 index 6cfc55aa6..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-sandbox-transactions.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - LibeufinSandboxApi, - LibeufinSandboxService, -} from "../harness/libeufin.js"; - -export async function runLibeufinApiSandboxTransactionsTest( - t: GlobalTestState, -) { - const sandbox = await LibeufinSandboxService.create(t, { - httpPort: 5012, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - await sandbox.start(); - await sandbox.pingUntilAvailable(); - await LibeufinSandboxApi.createDemobankAccount( - "mock-account", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - "DE71500105179674997361", - ); - await LibeufinSandboxApi.simulateIncomingTransaction( - sandbox, - "mock-account", - { - debtorIban: "DE84500105176881385584", - debtorBic: "BELADEBEXXX", - debtorName: "mock2", - subject: "mock subject", - amount: "EUR:1", - }, - ); - await LibeufinSandboxApi.simulateIncomingTransaction( - sandbox, - "mock-account", - { - debtorIban: "DE84500105176881385584", - debtorBic: "BELADEBEXXX", - debtorName: "mock2", - subject: "mock subject 2", - amount: "EUR:1.1", - }, - ); - let ret = await LibeufinSandboxApi.getAccountInfoWithBalance( - sandbox, - "mock-account", - ); - t.assertAmountEquals(ret.balance, "EUR:2.1"); -} -runLibeufinApiSandboxTransactionsTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-scheduling.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-scheduling.ts deleted file mode 100644 index 15ed2ab78..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-scheduling.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - launchLibeufinServices, - LibeufinNexusApi, - LibeufinNexusService, - NexusUserBundle, - SandboxUserBundle, -} from "../harness/libeufin.js"; - -/** - * Test Nexus scheduling API. It creates a task, check whether it shows - * up, then deletes it, and check if it's gone. Ideally, a check over the - * _liveliness_ of a scheduled task should happen. - */ -export async function runLibeufinApiSchedulingTest(t: GlobalTestState) { - const nexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await nexus.start(); - await nexus.pingUntilAvailable(); - - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - await launchLibeufinServices(t, [user01nexus], [user01sandbox]); - await LibeufinNexusApi.postTask(nexus, user01nexus.localAccountName, { - name: "test-task", - cronspec: "* * *", - type: "fetch", - params: { - level: "all", - rangeType: "all", - }, - }); - let resp = await LibeufinNexusApi.getTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - t.assertTrue(resp.taskName == "test-task"); - await LibeufinNexusApi.deleteTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - try { - await LibeufinNexusApi.getTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - } catch (err: any) { - t.assertTrue(err.response.status == 404); - } - - // Same with submit task. - await LibeufinNexusApi.postTask(nexus, user01nexus.localAccountName, { - name: "test-task", - cronspec: "* * *", - type: "submit", - params: {}, - }); - resp = await LibeufinNexusApi.getTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - t.assertTrue(resp.taskName == "test-task"); - await LibeufinNexusApi.deleteTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - try { - await LibeufinNexusApi.getTask( - nexus, - user01nexus.localAccountName, - "test-task", - ); - } catch (err: any) { - t.assertTrue(err.response.status == 404); - } -} -runLibeufinApiSchedulingTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-api-users.ts b/packages/taler-harness/src/integrationtests/test-libeufin-api-users.ts deleted file mode 100644 index 662b22bbe..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-api-users.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { LibeufinNexusApi, LibeufinNexusService } from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinApiUsersTest(t: GlobalTestState) { - const nexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await nexus.start(); - await nexus.pingUntilAvailable(); - - await LibeufinNexusApi.createUser(nexus, { - username: "one", - password: "will-be-changed", - }); - - await LibeufinNexusApi.changePassword( - nexus, - "one", - { - newPassword: "got-changed", - }, - { - auth: { - username: "admin", - password: "test", - }, - }, - ); - - let resp = await LibeufinNexusApi.getUser(nexus, { - auth: { - username: "one", - password: "got-changed", - }, - }); - console.log(resp); - t.assertTrue(resp["username"] == "one" && !resp["superuser"]); -} - -runLibeufinApiUsersTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-bad-gateway.ts b/packages/taler-harness/src/integrationtests/test-libeufin-bad-gateway.ts deleted file mode 100644 index 1187d923b..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-bad-gateway.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState, delayMs } from "../harness/harness.js"; -import { - NexusUserBundle, - LibeufinNexusApi, - LibeufinNexusService, - LibeufinSandboxService, -} from "../harness/libeufin.js"; - -/** - * Testing how Nexus reacts when the Sandbox is unreachable. - * Typically, because the user specified a wrong EBICS endpoint. - */ -export async function runLibeufinBadGatewayTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/not-found", // the EBICS endpoint at Sandbox - ); - - // Start Nexus - const libeufinNexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - await libeufinNexus.start(); - await libeufinNexus.pingUntilAvailable(); - - // Start Sandbox - const libeufinSandbox = await LibeufinSandboxService.create(t, { - httpPort: 5010, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - await libeufinSandbox.start(); - await libeufinSandbox.pingUntilAvailable(); - - // Connecting to a non-existent Sandbox endpoint. - await LibeufinNexusApi.createEbicsBankConnection( - libeufinNexus, - user01nexus.connReq, - ); - - // 502 Bad Gateway expected. - try { - await LibeufinNexusApi.connectBankConnection( - libeufinNexus, - user01nexus.connReq.name, - ); - } catch (e: any) { - t.assertTrue(e.response.status == 502); - return; - } - t.assertTrue(false); -} -runLibeufinBadGatewayTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts b/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts deleted file mode 100644 index d87278197..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-basic.ts +++ /dev/null @@ -1,317 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { - AbsoluteTime, - Duration, - MerchantContractTerms, -} from "@gnu-taler/taler-util"; -import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; -import { - DbInfo, - ExchangeService, - GlobalTestState, - HarnessExchangeBankAccount, - MerchantService, - WalletClient, - setupDb, -} from "../harness/harness.js"; -import { - createWalletDaemonWithClient, - makeTestPaymentV2, -} from "../harness/helpers.js"; -import { - LibeufinNexusApi, - LibeufinNexusService, - LibeufinSandboxApi, - LibeufinSandboxService, -} from "../harness/libeufin.js"; - -const exchangeIban = "DE71500105179674997361"; -const customerIban = "DE84500105176881385584"; -const customerBic = "BELADEBEXXX"; -const merchantIban = "DE42500105171245624648"; - -export interface LibeufinTestEnvironment { - commonDb: DbInfo; - exchange: ExchangeService; - exchangeBankAccount: HarnessExchangeBankAccount; - merchant: MerchantService; - walletClient: WalletClient; - libeufinSandbox: LibeufinSandboxService; - libeufinNexus: LibeufinNexusService; -} - -/** - * Create a Taler environment with LibEuFin and an EBICS account. - */ -export async function createLibeufinTestEnvironment( - t: GlobalTestState, - coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("EUR")), -): Promise { - const db = await setupDb(t); - - const libeufinSandbox = await LibeufinSandboxService.create(t, { - httpPort: 5010, - databaseJdbcUri: db.connStr, - }); - - await libeufinSandbox.start(); - await libeufinSandbox.pingUntilAvailable(); - - const libeufinNexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: db.connStr, - }); - - await libeufinNexus.start(); - await libeufinNexus.pingUntilAvailable(); - - await LibeufinSandboxApi.createEbicsHost(libeufinSandbox, "host01"); - // Subscriber and bank Account for the exchange - await LibeufinSandboxApi.createDemobankAccount( - "exchangeacct", - "password-unused", - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/access-api/" }, - exchangeIban, - ); - await LibeufinSandboxApi.createDemobankEbicsSubscriber( - { - hostID: "host01", - partnerID: "partner01", - userID: "user01", - }, - "exchangeacct", - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/" }, - ); - - await LibeufinSandboxApi.createDemobankAccount( - "merchantacct", - "password-unused", - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/access-api/" }, - merchantIban, - ); - await LibeufinSandboxApi.createDemobankEbicsSubscriber( - { - hostID: "host01", - partnerID: "partner02", - userID: "user02", - }, - "merchantacct", - { baseUrl: libeufinSandbox.baseUrl + "/demobanks/default/" }, - ); - - await LibeufinNexusApi.createEbicsBankConnection(libeufinNexus, { - name: "myconn", - ebicsURL: "http://localhost:5010/ebicsweb", - hostID: "host01", - partnerID: "partner01", - userID: "user01", - }); - await LibeufinNexusApi.connectBankConnection(libeufinNexus, "myconn"); - await LibeufinNexusApi.fetchAccounts(libeufinNexus, "myconn"); - await LibeufinNexusApi.importConnectionAccount( - libeufinNexus, - "myconn", - "exchangeacct", - "myacct", - ); - - await LibeufinNexusApi.createTwgFacade(libeufinNexus, { - name: "twg1", - accountName: "myacct", - connectionName: "myconn", - currency: "EUR", - reserveTransferLevel: "report", - }); - - await LibeufinNexusApi.createUser(libeufinNexus, { - username: "twguser", - password: "twgpw", - }); - - await LibeufinNexusApi.postPermission(libeufinNexus, { - action: "grant", - permission: { - subjectType: "user", - subjectId: "twguser", - resourceType: "facade", - resourceId: "twg1", - permissionName: "facade.talerWireGateway.history", - }, - }); - - await LibeufinNexusApi.postPermission(libeufinNexus, { - action: "grant", - permission: { - subjectType: "user", - subjectId: "twguser", - resourceType: "facade", - resourceId: "twg1", - permissionName: "facade.talerWireGateway.transfer", - }, - }); - - const exchange = ExchangeService.create(t, { - name: "testexchange-1", - currency: "EUR", - httpPort: 8081, - database: db.connStr, - }); - - const merchant = await MerchantService.create(t, { - name: "testmerchant-1", - currency: "EUR", - httpPort: 8083, - database: db.connStr, - }); - - const exchangeBankAccount: HarnessExchangeBankAccount = { - accountName: "twguser", - accountPassword: "twgpw", - accountPaytoUri: `payto://iban/${exchangeIban}?receiver-name=Exchange`, - wireGatewayApiBaseUrl: - "http://localhost:5011/facades/twg1/taler-wire-gateway/", - }; - - exchange.addBankAccount("1", exchangeBankAccount); - - exchange.addCoinConfigList(coinConfig); - - await exchange.start(); - await exchange.pingUntilAvailable(); - - merchant.addExchange(exchange); - - await merchant.start(); - await merchant.pingUntilAvailable(); - - await merchant.addInstanceWithWireAccount({ - id: "default", - name: "Default Instance", - paytoUris: [`payto://iban/${merchantIban}?receiver-name=Merchant`], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.getZero(), - ), - }); - - console.log("setup done!"); - - const { walletClient } = await createWalletDaemonWithClient(t, { - name: "default", - }); - - return { - commonDb: db, - exchange, - merchant, - walletClient, - exchangeBankAccount, - libeufinNexus, - libeufinSandbox, - }; -} - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinBasicTest(t: GlobalTestState) { - // Set up test environment - - const { walletClient, exchange, merchant, libeufinSandbox, libeufinNexus } = - await createLibeufinTestEnvironment(t); - - await walletClient.call(WalletApiOperation.AddExchange, { - exchangeBaseUrl: exchange.baseUrl, - }); - - const wr = await walletClient.call( - WalletApiOperation.AcceptManualWithdrawal, - { - exchangeBaseUrl: exchange.baseUrl, - amount: "EUR:15", - }, - ); - - const reservePub: string = wr.reservePub; - - await LibeufinSandboxApi.simulateIncomingTransaction( - libeufinSandbox, - "exchangeacct", - { - amount: "EUR:15.00", - debtorBic: customerBic, - debtorIban: customerIban, - debtorName: "Jane Customer", - subject: `Taler Top-up ${reservePub}`, - }, - ); - - await LibeufinNexusApi.fetchTransactions(libeufinNexus, "myacct"); - - await exchange.runWirewatchOnce(); - - await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - - const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); - console.log("balances", JSON.stringify(bal, undefined, 2)); - t.assertAmountEquals(bal.balances[0].available, "EUR:14.7"); - - const order: Partial = { - summary: "Buy me!", - amount: "EUR:5", - fulfillment_url: "taler://fulfillment-success/thx", - wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp( - AbsoluteTime.now(), - ), - }; - - await makeTestPaymentV2(t, { walletClient, merchant, order }); - - await exchange.runAggregatorOnce(); - await exchange.runTransferOnce(); - - await LibeufinNexusApi.submitAllPaymentInitiations(libeufinNexus, "myacct"); - - const exchangeTransactions = await LibeufinSandboxApi.getAccountTransactions( - libeufinSandbox, - "exchangeacct", - ); - - console.log( - "exchange transactions:", - JSON.stringify(exchangeTransactions, undefined, 2), - ); - - t.assertDeepEqual( - exchangeTransactions.payments[0].creditDebitIndicator, - "credit", - ); - t.assertDeepEqual( - exchangeTransactions.payments[1].creditDebitIndicator, - "debit", - ); - t.assertDeepEqual(exchangeTransactions.payments[1].debtorIban, exchangeIban); - t.assertDeepEqual( - exchangeTransactions.payments[1].creditorIban, - merchantIban, - ); -} -runLibeufinBasicTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-c5x.ts b/packages/taler-harness/src/integrationtests/test-libeufin-c5x.ts deleted file mode 100644 index 5097bc4d3..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-c5x.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - launchLibeufinServices, - LibeufinNexusApi, - NexusUserBundle, - SandboxUserBundle, -} from "../harness/libeufin.js"; - -/** - * This test checks how the C52 and C53 coordinate. It'll test - * whether fresh transactions stop showing as C52 after they get - * included in a bank statement. - */ -export async function runLibeufinC5xTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * User saltetd "02". - */ - const user02nexus = new NexusUserBundle( - "02", - "http://localhost:5010/ebicsweb", - ); - const user02sandbox = new SandboxUserBundle("02"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus, user02nexus], - [user01sandbox, user02sandbox], - ["twg"], - ); - - // Check that C52 and C53 have zero entries. - - // C52 - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "report", // level - ); - // C53 - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "statement", // level - ); - const nexusTxs = await LibeufinNexusApi.getAccountTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - t.assertTrue(nexusTxs["transactions"].length == 0); - - // Addressing one payment to user 01 - await libeufinServices.libeufinSandbox.makeTransaction( - user02sandbox.ebicsBankAccount.label, // debit - user01sandbox.ebicsBankAccount.label, // credit - "EUR:10", - "first payment", - ); - - let expectOne = await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "report", // C52 - ); - t.assertTrue(expectOne.newTransactions == 1); - t.assertTrue(expectOne.downloadedTransactions == 1); - - /* Expect zero payments being downloaded because the - * previous request consumed already the one pending - * payment. - */ - let expectZero = await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "report", // C52 - ); - t.assertTrue(expectZero.newTransactions == 0); - t.assertTrue(expectZero.downloadedTransactions == 0); - - /** - * A statement should still account zero payments because - * so far the payment made before is still pending. - */ - expectZero = await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "statement", // C53 - ); - t.assertTrue(expectZero.newTransactions == 0); - t.assertTrue(expectZero.downloadedTransactions == 0); - - /** - * Ticking now. That books any pending transaction. - */ - await libeufinServices.libeufinSandbox.c53tick(); - - /** - * A statement is now expected to download the transaction, - * although that got already ingested along the report - * earlier. Thus the transaction counts as downloaded but - * not as new. - */ - expectOne = await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "statement", // C53 - ); - t.assertTrue(expectOne.downloadedTransactions == 1); - t.assertTrue(expectOne.newTransactions == 0); -} -runLibeufinC5xTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-facade-anastasis.ts b/packages/taler-harness/src/integrationtests/test-libeufin-facade-anastasis.ts deleted file mode 100644 index 0efd55f44..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-facade-anastasis.ts +++ /dev/null @@ -1,179 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinNexusApi, - LibeufinSandboxApi, -} from "../harness/libeufin.js"; - -/** - * Testing the Anastasis API, offered by the Anastasis facade. - */ -export async function runLibeufinAnastasisFacadeTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus], - [user01sandbox], - ["anastasis"], // create only one Anastasis facade. - ); - let resp = await LibeufinNexusApi.getAllFacades( - libeufinServices.libeufinNexus, - ); - // check that original facade shows up. - t.assertTrue( - resp["facades"][0]["name"] == user01nexus.anastasisReq["name"], - ); -const anastasisBaseUrl: string = resp["facades"][0]["baseUrl"]; - t.assertTrue(typeof anastasisBaseUrl === "string"); - t.assertTrue(anastasisBaseUrl.startsWith("http://")); - t.assertTrue(anastasisBaseUrl.endsWith("/")); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - - await LibeufinNexusApi.postPermission(libeufinServices.libeufinNexus, { - action: "grant", - permission: { - subjectId: user01nexus.userReq.username, - subjectType: "user", - resourceType: "facade", - resourceId: user01nexus.anastasisReq.name, - permissionName: "facade.anastasis.history", - }, - }); - - // check if empty. - let txsEmpty = await LibeufinNexusApi.getAnastasisTransactions( - libeufinServices.libeufinNexus, - anastasisBaseUrl, - { delta: 5 }, - ); - - t.assertTrue(txsEmpty.data.incoming_transactions.length == 0); - - LibeufinSandboxApi.simulateIncomingTransaction( - libeufinServices.libeufinSandbox, - user01sandbox.ebicsBankAccount.label, - { - debtorIban: "ES3314655813489414469157", - debtorBic: "BCMAESM1XXX", - debtorName: "Mock Donor", - subject: "Anastasis donation", - amount: "EUR:3", // Sandbox takes currency from its 'config' - }, - ); - - LibeufinSandboxApi.simulateIncomingTransaction( - libeufinServices.libeufinSandbox, - user01sandbox.ebicsBankAccount.label, - { - debtorIban: "ES3314655813489414469157", - debtorBic: "BCMAESM1XXX", - debtorName: "Mock Donor", - subject: "another Anastasis donation", - amount: "EUR:1", // Sandbox takes currency from its "config" - }, - ); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - - let txs = await LibeufinNexusApi.getAnastasisTransactions( - libeufinServices.libeufinNexus, - anastasisBaseUrl, - { delta: 5 }, - user01nexus.userReq.username, - user01nexus.userReq.password, - ); - - // check the two payments show up - let txsList = txs.data.incoming_transactions; - t.assertTrue(txsList.length == 2); - t.assertTrue( - [txsList[0].subject, txsList[1].subject].includes("Anastasis donation"), - ); - t.assertTrue( - [txsList[0].subject, txsList[1].subject].includes( - "another Anastasis donation", - ), - ); - t.assertTrue(txsList[0].row_id == 1); - t.assertTrue(txsList[1].row_id == 2); - - LibeufinSandboxApi.simulateIncomingTransaction( - libeufinServices.libeufinSandbox, - user01sandbox.ebicsBankAccount.label, - { - debtorIban: "ES3314655813489414469157", - debtorBic: "BCMAESM1XXX", - debtorName: "Mock Donor", - subject: "last Anastasis donation", - amount: "EUR:10.10", // Sandbox takes currency from its "config" - }, - ); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - - let txsLast = await LibeufinNexusApi.getAnastasisTransactions( - libeufinServices.libeufinNexus, - anastasisBaseUrl, - { delta: 5, start: 2 }, - user01nexus.userReq.username, - user01nexus.userReq.password, - ); - console.log( - txsLast.data.incoming_transactions[0].subject == "last Anastasis donation", - ); - - let txsReverse = await LibeufinNexusApi.getAnastasisTransactions( - libeufinServices.libeufinNexus, - anastasisBaseUrl, - { delta: -5, start: 4 }, - user01nexus.userReq.username, - user01nexus.userReq.password, - ); - t.assertTrue(txsReverse.data.incoming_transactions[0].row_id == 3); - t.assertTrue(txsReverse.data.incoming_transactions[1].row_id == 2); - t.assertTrue(txsReverse.data.incoming_transactions[2].row_id == 1); -} - -runLibeufinAnastasisFacadeTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-keyrotation.ts b/packages/taler-harness/src/integrationtests/test-libeufin-keyrotation.ts deleted file mode 100644 index a2c21d5d8..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-keyrotation.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinSandboxApi, - LibeufinNexusApi, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinKeyrotationTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus], - [user01sandbox], - ); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - - /* Rotate the Sandbox keys, and fetch the transactions again */ - await LibeufinSandboxApi.rotateKeys( - libeufinServices.libeufinSandbox, - user01sandbox.ebicsBankAccount.subscriber.hostID, - ); - - try { - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - } catch (e: any) { - /** - * Asserting that Nexus responded with a 500 Internal server - * error, because the bank signed the last response with a new - * key pair that was never downloaded by Nexus. - * - * NOTE: the bank accepted the request addressed to the old - * public key. Should it in this case reject the request even - * before trying to verify it? - */ - t.assertTrue(e.response.status == 500); - // FIXME: uncomment and adapt the following command after #6723 is fixed. - // t.assertTrue(e.response.data.code == 9000); - } -} -runLibeufinKeyrotationTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-nexus-balance.ts b/packages/taler-harness/src/integrationtests/test-libeufin-nexus-balance.ts deleted file mode 100644 index 868f93759..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-nexus-balance.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinNexusApi, -} from "../harness/libeufin.js"; - -/** - * This test checks how the C52 and C53 coordinate. It'll test - * whether fresh transactions stop showing as C52 after they get - * included in a bank statement. - */ -export async function runLibeufinNexusBalanceTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * User saltetd "02". - */ - const user02nexus = new NexusUserBundle( - "02", - "http://localhost:5010/ebicsweb", - ); - const user02sandbox = new SandboxUserBundle("02"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus, user02nexus], - [user01sandbox, user02sandbox], - ["twg"], - ); - - // user 01 gets 10 - await libeufinServices.libeufinSandbox.makeTransaction( - user02sandbox.ebicsBankAccount.label, // debit - user01sandbox.ebicsBankAccount.label, // credit - "EUR:10", - "first payment", - ); - // user 01 gets another 10 - await libeufinServices.libeufinSandbox.makeTransaction( - user02sandbox.ebicsBankAccount.label, // debit - user01sandbox.ebicsBankAccount.label, // credit - "EUR:10", - "second payment", - ); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "report", // level - ); - - // Check that user 01 has 20, via Nexus. - let accountInfo = await LibeufinNexusApi.getBankAccount( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - t.assertAmountEquals(accountInfo.data.lastSeenBalance, "EUR:20"); - - // Booking the first two transactions. - await libeufinServices.libeufinSandbox.c53tick(); - - // user 01 gives 30 - await libeufinServices.libeufinSandbox.makeTransaction( - user01sandbox.ebicsBankAccount.label, - user02sandbox.ebicsBankAccount.label, - "EUR:30", - "third payment", - ); - - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "all", // range - "report", // level - ); - - let accountInfoDebit = await LibeufinNexusApi.getBankAccount( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - t.assertDeepEqual(accountInfoDebit.data.lastSeenBalance, "-EUR:10"); -} - -runLibeufinNexusBalanceTest.suites = ["libeufin"]; -runLibeufinNexusBalanceTest.experimental = true; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-refund-multiple-users.ts b/packages/taler-harness/src/integrationtests/test-libeufin-refund-multiple-users.ts deleted file mode 100644 index 245f34331..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-refund-multiple-users.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState, delayMs } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinSandboxApi, - LibeufinNexusApi, -} from "../harness/libeufin.js"; - -/** - * User 01 expects a refund from user 02, and expectedly user 03 - * should not be involved in the process. - */ -export async function runLibeufinRefundMultipleUsersTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * User saltetd "02" - */ - const user02nexus = new NexusUserBundle( - "02", - "http://localhost:5010/ebicsweb", - ); - const user02sandbox = new SandboxUserBundle("02"); - - /** - * User saltetd "03" - */ - const user03nexus = new NexusUserBundle( - "03", - "http://localhost:5010/ebicsweb", - ); - const user03sandbox = new SandboxUserBundle("03"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus, user02nexus], - [user01sandbox, user02sandbox], - ["twg"], - ); - - // user 01 gets the payment - await libeufinServices.libeufinSandbox.makeTransaction( - user02sandbox.ebicsBankAccount.label, // debit - user01sandbox.ebicsBankAccount.label, // credit - "EUR:1", - "not a public key", - ); - - // user 01 fetches the payments - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - - // user 01 tries to submit the reimbursement, as - // the payment didn't have a valid public key in - // the subject. - await LibeufinNexusApi.submitInitiatedPayment( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - "1", // so far the only one that can exist. - ); - - // user 02 checks whether a reimbursement arrived. - let history = await LibeufinSandboxApi.getAccountTransactions( - libeufinServices.libeufinSandbox, - user02sandbox.ebicsBankAccount["label"], - ); - // reimbursement arrived IFF the total payments are 2: - // 1 the original (faulty) transaction + 1 the reimbursement. - t.assertTrue(history["payments"].length == 2); -} - -runLibeufinRefundMultipleUsersTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-refund.ts b/packages/taler-harness/src/integrationtests/test-libeufin-refund.ts deleted file mode 100644 index d37363bab..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-refund.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState, delayMs } from "../harness/harness.js"; -import { - SandboxUserBundle, - NexusUserBundle, - launchLibeufinServices, - LibeufinSandboxApi, - LibeufinNexusApi, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinRefundTest(t: GlobalTestState) { - /** - * User saltetd "01" - */ - const user01nexus = new NexusUserBundle( - "01", - "http://localhost:5010/ebicsweb", - ); - const user01sandbox = new SandboxUserBundle("01"); - - /** - * User saltetd "02" - */ - const user02nexus = new NexusUserBundle( - "02", - "http://localhost:5010/ebicsweb", - ); - const user02sandbox = new SandboxUserBundle("02"); - - /** - * Launch Sandbox and Nexus. - */ - const libeufinServices = await launchLibeufinServices( - t, - [user01nexus, user02nexus], - [user01sandbox, user02sandbox], - ["twg"], - ); - - // user 02 pays user 01 with a faulty (non Taler) subject. - await libeufinServices.libeufinSandbox.makeTransaction( - user02sandbox.ebicsBankAccount.label, // debit - user01sandbox.ebicsBankAccount.label, // credit - "EUR:1", - "not a public key", - ); - - // The bad payment should be now ingested and prepared as - // a reimbursement. - await LibeufinNexusApi.fetchTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - // Check that the payment arrived at the Nexus. - const nexusTxs = await LibeufinNexusApi.getAccountTransactions( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - ); - t.assertTrue(nexusTxs["transactions"].length == 1); - - // Submit the reimbursement - await LibeufinNexusApi.submitInitiatedPayment( - libeufinServices.libeufinNexus, - user01nexus.localAccountName, - // The initiated payment (= the reimbursement) ID below - // got set by the Taler facade; at this point only one must - // exist. If "1" is not found, a 404 will make this test fail. - "1", - ); - - // user 02 checks whether the reimbursement arrived. - let history = await LibeufinSandboxApi.getAccountTransactions( - libeufinServices.libeufinSandbox, - user02sandbox.ebicsBankAccount["label"], - ); - // 2 payments must exist: 1 the original (faulty) payment + - // 1 the reimbursement. - t.assertTrue(history["payments"].length == 2); -} -runLibeufinRefundTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-sandbox-wire-transfer-cli.ts b/packages/taler-harness/src/integrationtests/test-libeufin-sandbox-wire-transfer-cli.ts deleted file mode 100644 index be467e2f1..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-sandbox-wire-transfer-cli.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - LibeufinSandboxApi, - LibeufinSandboxService, -} from "../harness/libeufin.js"; - -export async function runLibeufinSandboxWireTransferCliTest( - t: GlobalTestState, -) { - const sandbox = await LibeufinSandboxService.create(t, { - httpPort: 5012, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - await sandbox.start(); - await sandbox.pingUntilAvailable(); - await LibeufinSandboxApi.createDemobankAccount( - "mock-account", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - "DE71500105179674997361", - ); - await LibeufinSandboxApi.createDemobankAccount( - "mock-account-2", - "password-unused", - { baseUrl: sandbox.baseUrl + "/demobanks/default/access-api/" }, - "DE71500105179674997364", - ); - - await sandbox.makeTransaction( - "mock-account", - "mock-account-2", - "EUR:1", - "one!", - ); - await sandbox.makeTransaction( - "mock-account", - "mock-account-2", - "EUR:1", - "two!", - ); - await sandbox.makeTransaction( - "mock-account", - "mock-account-2", - "EUR:1", - "three!", - ); - await sandbox.makeTransaction( - "mock-account-2", - "mock-account", - "EUR:1", - "Give one back.", - ); - await sandbox.makeTransaction( - "mock-account-2", - "mock-account", - "EUR:0.11", - "Give fraction back.", - ); - let ret = await LibeufinSandboxApi.getAccountInfoWithBalance( - sandbox, - "mock-account-2", - ); - console.log(ret.balance); - t.assertTrue(ret.balance == "EUR:1.89"); -} -runLibeufinSandboxWireTransferCliTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-tutorial.ts b/packages/taler-harness/src/integrationtests/test-libeufin-tutorial.ts deleted file mode 100644 index 496b65ee3..000000000 --- a/packages/taler-harness/src/integrationtests/test-libeufin-tutorial.ts +++ /dev/null @@ -1,130 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 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 - */ - -/** - * Imports. - */ -import { GlobalTestState } from "../harness/harness.js"; -import { - LibeufinNexusService, - LibeufinSandboxService, - LibeufinCli, -} from "../harness/libeufin.js"; - -/** - * Run basic test with LibEuFin. - */ -export async function runLibeufinTutorialTest(t: GlobalTestState) { - // Set up test environment - - const libeufinSandbox = await LibeufinSandboxService.create(t, { - httpPort: 5010, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - }); - - await libeufinSandbox.start(); - await libeufinSandbox.pingUntilAvailable(); - - const libeufinNexus = await LibeufinNexusService.create(t, { - httpPort: 5011, - databaseJdbcUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - }); - - const nexusUser = { username: "foo", password: "secret" }; - const libeufinCli = new LibeufinCli(t, { - sandboxUrl: libeufinSandbox.baseUrl, - nexusUrl: libeufinNexus.baseUrl, - sandboxDatabaseUri: `jdbc:sqlite:${t.testDir}/libeufin-sandbox.sqlite3`, - nexusDatabaseUri: `jdbc:sqlite:${t.testDir}/libeufin-nexus.sqlite3`, - nexusUser: nexusUser, - }); - - const ebicsDetails = { - hostId: "testhost", - partnerId: "partner01", - userId: "user01", - }; - const bankAccountDetails = { - currency: "EUR", - iban: "DE18500105172929531888", - bic: "INGDDEFFXXX", - personName: "Jane Normal", - accountName: "testacct01", - }; - - await libeufinCli.checkSandbox(); - await libeufinCli.createEbicsHost("testhost"); - await libeufinCli.createEbicsSubscriber(ebicsDetails); - await libeufinCli.createEbicsBankAccount(ebicsDetails, bankAccountDetails); - await libeufinCli.generateTransactions(bankAccountDetails.accountName); - - await libeufinNexus.start(); - await libeufinNexus.pingUntilAvailable(); - - await libeufinNexus.createNexusSuperuser(nexusUser); - const connectionDetails = { - subscriberDetails: ebicsDetails, - ebicsUrl: `${libeufinSandbox.baseUrl}ebicsweb`, // FIXME: need appropriate URL concatenation - connectionName: "my-ebics-conn", - }; - await libeufinCli.createEbicsConnection(connectionDetails); - await libeufinCli.createBackupFile({ - passphrase: "secret", - outputFile: `${t.testDir}/connection-backup.json`, - connectionName: connectionDetails.connectionName, - }); - await libeufinCli.createKeyLetter({ - outputFile: `${t.testDir}/letter.pdf`, - connectionName: connectionDetails.connectionName, - }); - await libeufinCli.connect(connectionDetails.connectionName); - await libeufinCli.downloadBankAccounts(connectionDetails.connectionName); - await libeufinCli.listOfferedBankAccounts(connectionDetails.connectionName); - - const bankAccountImportDetails = { - offeredBankAccountName: bankAccountDetails.accountName, - nexusBankAccountName: "at-nexus-testacct01", - connectionName: connectionDetails.connectionName, - }; - - await libeufinCli.importBankAccount(bankAccountImportDetails); - await libeufinSandbox.c53tick(); - await libeufinCli.fetchTransactions( - bankAccountImportDetails.nexusBankAccountName, - ); - await libeufinCli.transactions(bankAccountImportDetails.nexusBankAccountName); - - const paymentDetails = { - creditorIban: "DE42500105171245624648", - creditorBic: "BELADEBEXXX", - creditorName: "Mina Musterfrau", - subject: "Purchase 01234", - amount: "1.0", - currency: "EUR", - nexusBankAccountName: bankAccountImportDetails.nexusBankAccountName, - }; - await libeufinCli.preparePayment(paymentDetails); - await libeufinCli.submitPayment(paymentDetails, "1"); - - await libeufinCli.newTalerWireGatewayFacade({ - accountName: bankAccountImportDetails.nexusBankAccountName, - connectionName: "my-ebics-conn", - currency: "EUR", - facadeName: "my-twg", - }); - await libeufinCli.listFacades(); -} -runLibeufinTutorialTest.suites = ["libeufin"]; diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index e57427fac..ca74a4ad6 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -22,7 +22,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, CoreApiResponse, MerchantApiClient, } from "@gnu-taler/taler-util"; @@ -127,7 +127,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { // Create withdrawal operation - const bankClient = new BankAccessApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index 4140311ab..3d4ea6663 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, MerchantApiClient, TransactionMajorState, WireGatewayApiClient, @@ -38,7 +38,7 @@ export async function runTippingTest(t: GlobalTestState) { const { walletClient, bank, exchange, merchant, exchangeBankAccount } = await createSimpleTestkudosEnvironmentV2(t); - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); const mbu = await bankAccessApiClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index 9a0eb77ae..ae582fe60 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, Duration, NotificationType, TransactionMajorState, @@ -121,7 +121,7 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { skipDefaults: true, }); - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); 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 aa5e2b770..4a0dd845b 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts @@ -17,7 +17,7 @@ /** * Imports. */ -import { BankAccessApiClient, TalerErrorCode } from "@gnu-taler/taler-util"; +import { TalerCorebankApiClient, 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"; @@ -33,7 +33,7 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); 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 232b6d7c2..4a2cc7df9 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -18,7 +18,7 @@ * Imports. */ import { - BankAccessApiClient, + TalerCorebankApiClient, j2s, NotificationType, TransactionMajorState, @@ -41,7 +41,7 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts index ec6e54e6c..7cd0548a5 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts @@ -54,7 +54,10 @@ export async function runWithdrawalFakebankTest(t: GlobalTestState) { exchange.addBankAccount("1", { accountName: "exchange", accountPassword: "x", - wireGatewayApiBaseUrl: new URL("/exchange/", bank.baseUrl).href, + wireGatewayApiBaseUrl: new URL( + "/accounts/exchange/taler-wire-gateway", + bank.baseUrl, + ).href, accountPaytoUri: "payto://x-taler-bank/localhost/exchange", }); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index bc2946a18..a5a5a0d99 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -17,7 +17,7 @@ /** * Imports. */ -import { BankAccessApiClient, j2s } from "@gnu-taler/taler-util"; +import { TalerCorebankApiClient, j2s } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig } from "../harness/denomStructures.js"; import { @@ -107,7 +107,7 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) { const amount = "TESTKUDOS:7.5"; - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts index 1d98cd46e..316e3cc18 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts @@ -19,7 +19,7 @@ */ import { AbsoluteTime, - BankAccessApiClient, + TalerCorebankApiClient, Logger, WireGatewayApiClient, j2s, @@ -41,7 +41,7 @@ export async function runWithdrawalManualTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new BankAccessApiClient( + const bankAccessApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index 237d3bf9f..071871837 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -43,25 +43,6 @@ import { runExchangeTimetravelTest } from "./test-exchange-timetravel.js"; import { runFeeRegressionTest } from "./test-fee-regression.js"; import { runForcedSelectionTest } from "./test-forced-selection.js"; import { runKycTest } from "./test-kyc.js"; -import { runLibeufinApiBankaccountTest } from "./test-libeufin-api-bankaccount.js"; -import { runLibeufinApiBankconnectionTest } from "./test-libeufin-api-bankconnection.js"; -import { runLibeufinApiFacadeBadRequestTest } from "./test-libeufin-api-facade-bad-request.js"; -import { runLibeufinApiFacadeTest } from "./test-libeufin-api-facade.js"; -import { runLibeufinApiPermissionsTest } from "./test-libeufin-api-permissions.js"; -import { runLibeufinApiSandboxCamtTest } from "./test-libeufin-api-sandbox-camt.js"; -import { runLibeufinApiSandboxTransactionsTest } from "./test-libeufin-api-sandbox-transactions.js"; -import { runLibeufinApiSchedulingTest } from "./test-libeufin-api-scheduling.js"; -import { runLibeufinApiUsersTest } from "./test-libeufin-api-users.js"; -import { runLibeufinBadGatewayTest } from "./test-libeufin-bad-gateway.js"; -import { runLibeufinBasicTest } from "./test-libeufin-basic.js"; -import { runLibeufinC5xTest } from "./test-libeufin-c5x.js"; -import { runLibeufinAnastasisFacadeTest } from "./test-libeufin-facade-anastasis.js"; -import { runLibeufinKeyrotationTest } from "./test-libeufin-keyrotation.js"; -import { runLibeufinNexusBalanceTest } from "./test-libeufin-nexus-balance.js"; -import { runLibeufinRefundMultipleUsersTest } from "./test-libeufin-refund-multiple-users.js"; -import { runLibeufinRefundTest } from "./test-libeufin-refund.js"; -import { runLibeufinSandboxWireTransferCliTest } from "./test-libeufin-sandbox-wire-transfer-cli.js"; -import { runLibeufinTutorialTest } from "./test-libeufin-tutorial.js"; import { runMerchantExchangeConfusionTest } from "./test-merchant-exchange-confusion.js"; import { runMerchantInstancesDeleteTest } from "./test-merchant-instances-delete.js"; import { runMerchantInstancesUrlsTest } from "./test-merchant-instances-urls.js"; @@ -144,25 +125,6 @@ const allTests: TestMainFunction[] = [ runKycTest, runExchangePurseTest, runExchangeDepositTest, - runLibeufinAnastasisFacadeTest, - runLibeufinApiBankaccountTest, - runLibeufinApiBankconnectionTest, - runLibeufinApiFacadeBadRequestTest, - runLibeufinApiFacadeTest, - runLibeufinApiPermissionsTest, - runLibeufinApiSandboxCamtTest, - runLibeufinApiSandboxTransactionsTest, - runLibeufinApiSchedulingTest, - runLibeufinApiUsersTest, - runLibeufinBadGatewayTest, - runLibeufinBasicTest, - runLibeufinC5xTest, - runLibeufinKeyrotationTest, - runLibeufinNexusBalanceTest, - runLibeufinRefundMultipleUsersTest, - runLibeufinRefundTest, - runLibeufinSandboxWireTransferCliTest, - runLibeufinTutorialTest, runMerchantExchangeConfusionTest, runMerchantInstancesDeleteTest, runMerchantInstancesTest, diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts index cc4123500..164cd333d 100644 --- a/packages/taler-util/src/bank-api-client.ts +++ b/packages/taler-util/src/bank-api-client.ts @@ -146,11 +146,87 @@ export class WireGatewayApiClient { } } +export interface ChallengeContactData { + // E-Mail address + email?: string; + + // Phone number. + phone?: string; +} + +export interface Balance { + amount: AmountString; + credit_debit_indicator: "credit" | "debit"; +} + +export interface RegisterAccountRequest { + // Username + username: string; + + // Password. + password: string; + + // Legal name of the account owner + name: string; + + // Defaults to false. + is_public?: boolean; + + // Is this a taler exchange account? + // If true: + // - incoming transactions to the account that do not + // have a valid reserve public key are automatically + // - the account provides the taler-wire-gateway-api endpoints + // Defaults to false. + is_taler_exchange?: boolean; + + // Addresses where to send the TAN for transactions. + // Currently only used for cashouts. + // If missing, cashouts will fail. + // In the future, might be used for other transactions + // as well. + challenge_contact_data?: ChallengeContactData; + + // 'payto' address pointing a bank account + // external to the libeufin-bank. + // Payments will be sent to this bank account + // when the user wants to convert the local currency + // back to fiat currency outside libeufin-bank. + cashout_payto_uri?: string; + + // Internal payto URI of this bank account. + // Used mostly for testing. + internal_payto_uri?: string; +} + +export interface AccountData { + // Legal name of the account owner. + name: string; + + // Available balance on the account. + balance: Balance; + + // payto://-URI of the account. + payto_uri: string; + + // Number indicating the max debit allowed for the requesting user. + debit_threshold: AmountString; + + contact_data?: ChallengeContactData; + + // 'payto' address pointing the bank account + // where to send cashouts. This field is optional + // because not all the accounts are required to participate + // in the merchants' circuit. One example is the exchange: + // that never cashouts. Registering these accounts can + // be done via the access API. + cashout_payto_uri?: string; +} + /** - * This API look like it belongs to harness - * but it will be nice to have in utils to be used by others + * Client for the Taler corebank API. */ -export class BankAccessApiClient { +export class TalerCorebankApiClient { httpLib: HttpRequestLibrary; constructor( @@ -215,23 +291,22 @@ export class BankAccessApiClient { return await readSuccessResponseJsonOrThrow(resp, codecForAny()); } - async registerAccount( - username: string, - password: string, - options: { - iban?: string; - } = {}, - ): Promise { - const url = new URL("testing/register", this.baseUrl); + /** + * Register a new account and return information about it. + * + * This is a helper, as it does both the registration and the + * account info query. + */ + async registerAccount(username: string, password: string): Promise { + const url = new URL("accounts", this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", body: { username, password, - iban: options?.iban, + name: username, }, }); - 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( @@ -241,31 +316,24 @@ export class BankAccessApiClient { }, ); } - 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 - } + const infoUrl = new URL(`accounts/${username}`, this.baseUrl); + const infoResp = await this.httpLib.fetch(infoUrl.href); + // FIXME: Validate! + const acctInfo: AccountData = await readSuccessResponseJsonOrThrow( + infoResp, + codecForAny(), + ); return { password, username, - accountPaytoUri: paytoUri, + accountPaytoUri: acctInfo.payto_uri, }; } 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, - }); + return await this.registerAccount(username, password); } async createWithdrawalOperation( diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index f7bd3d120..87985fa2a 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -366,7 +366,7 @@ export const codecForAmountResponse = (): Codec => .property("rawAmount", codecForAmountString()) .build("AmountResponse"); -export interface Balance { +export interface WalletBalance { scopeInfo: ScopeInfo; available: AmountString; pendingIncoming: AmountString; @@ -458,11 +458,11 @@ export type ScopeInfoAuditor = { export type ScopeInfo = ScopeInfoGlobal | ScopeInfoExchange | ScopeInfoAuditor; export interface BalancesResponse { - balances: Balance[]; + balances: WalletBalance[]; } -export const codecForBalance = (): Codec => - buildCodecForObject() +export const codecForBalance = (): Codec => + buildCodecForObject() .property("scopeInfo", codecForAny()) // FIXME .property("available", codecForString()) .property("hasPendingTransactions", codecForBoolean()) diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 4d2fa5cd4..1684977d5 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -31,7 +31,7 @@ import { AmountJson, Amounts, AmountString, - BankAccessApiClient, + TalerCorebankApiClient, codecForAny, codecForBankWithdrawalOperationPostResponse, codecForBatchDepositSuccess, @@ -118,7 +118,7 @@ export async function topupReserveWithDemobank( args: TopupReserveWithDemobankArgs, ) { const { http, bankAccessApiBaseUrl, amount, exchangeInfo, reservePub } = args; - const bankClient = new BankAccessApiClient(bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bankAccessApiBaseUrl); const bankUser = await bankClient.createRandomBankUser(); const wopi = await bankClient.createWithdrawalOperation( bankUser.username, diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index f71d842c7..b5840c3a6 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -25,6 +25,7 @@ import { IntegrationTestV2Args, Logger, NotificationType, + RegisterAccountRequest, stringToBytes, TestPayResult, TransactionMajorState, @@ -216,17 +217,25 @@ async function confirmBankWithdrawalUri( async function registerRandomBankUser( http: HttpRequestLibrary, - bankAccessApiBaseUrl: string, + corebankApiBaseUrl: string, ): Promise { - const reqUrl = new URL("testing/register", bankAccessApiBaseUrl).href; + const reqUrl = new URL("accounts", corebankApiBaseUrl).href; const randId = makeId(8); + const username = `testuser-${randId.toLowerCase()}`; + const password = `testpw-${randId}`; + const bankUser: BankUser = { - // euFin doesn't allow resource names to have upper case letters. - username: `testuser-${randId.toLowerCase()}`, - password: `testpw-${randId}`, + username, + password, + }; + + const userReq: RegisterAccountRequest = { + username, + password, + name: username, }; - const resp = await http.postJson(reqUrl, bankUser); + const resp = await http.fetch(reqUrl, { method: "POST", body: userReq }); await checkSuccessResponseOrThrow(resp); return bankUser; } diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 9091a92bf..2c4f1ba6f 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -1513,13 +1513,19 @@ async function dispatchRequestInternal( const components = pt.targetPath.split("/"); const creditorAcct = components[components.length - 1]; logger.info(`making testbank transfer to '${creditorAcct}'`); - const fbReq = await ws.http.postJson( - new URL(`${creditorAcct}/admin/add-incoming`, req.bank).href, + const fbReq = await ws.http.fetch( + new URL( + `accounts/${creditorAcct}/taler-wire-gateway/admin/add-incoming`, + req.bank, + ).href, { - amount: Amounts.stringify(amount), - reserve_pub: wres.reservePub, - debit_account: - "payto://x-taler-bank/localhost/testdebtor?receiver-name=Foo", + method: "POST", + body: { + amount: Amounts.stringify(amount), + reserve_pub: wres.reservePub, + debit_account: + "payto://x-taler-bank/localhost/testdebtor?receiver-name=Foo", + }, }, ); const fbResp = await readSuccessResponseJsonOrThrow(fbReq, codecForAny()); -- cgit v1.2.3 From 6b63ecc49e4baafcd2833503418bb531025d8054 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 21 Sep 2023 19:43:59 +0200 Subject: -fix botched Balance->WalletBalance rename --- packages/taler-util/src/bank-api-client.ts | 4 ++-- .../src/components/BalanceTable.tsx | 6 +++--- .../taler-wallet-webextension/src/popup/BalancePage.tsx | 16 ++++++++++------ .../taler-wallet-webextension/src/wallet/History.tsx | 12 ++++++------ 4 files changed, 21 insertions(+), 17 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts index 164cd333d..facb02ea8 100644 --- a/packages/taler-util/src/bank-api-client.ts +++ b/packages/taler-util/src/bank-api-client.ts @@ -154,7 +154,7 @@ export interface ChallengeContactData { phone?: string; } -export interface Balance { +export interface AccountBalance { amount: AmountString; credit_debit_indicator: "credit" | "debit"; } @@ -204,7 +204,7 @@ export interface AccountData { name: string; // Available balance on the account. - balance: Balance; + balance: AccountBalance; // payto://-URI of the account. payto_uri: string; diff --git a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx index c2cef451b..d3733e6cc 100644 --- a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx +++ b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx @@ -14,15 +14,15 @@ GNU Taler; see the file COPYING. If not, see */ -import { Amounts, Balance } from "@gnu-taler/taler-util"; -import { h, VNode } from "preact"; +import { Amounts, WalletBalance } from "@gnu-taler/taler-util"; +import { VNode, h } from "preact"; import { TableWithRoundRows as TableWithRoundedRows } from "./styled/index.js"; export function BalanceTable({ balances, goToWalletHistory, }: { - balances: Balance[]; + balances: WalletBalance[]; goToWalletHistory: (currency: string) => void; }): VNode { return ( diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx index a8d2d6fcf..23614e290 100644 --- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -14,25 +14,29 @@ GNU Taler; see the file COPYING. If not, see */ -import { Amounts, Balance, NotificationType } from "@gnu-taler/taler-util"; +import { + Amounts, + NotificationType, + WalletBalance, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { Fragment, h, VNode } from "preact"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; import { useEffect, useState } from "preact/hooks"; import { BalanceTable } from "../components/BalanceTable.js"; import { ErrorAlertView } from "../components/CurrentAlerts.js"; import { Loading } from "../components/Loading.js"; import { MultiActionButton } from "../components/MultiActionButton.js"; import { - alertFromError, ErrorAlert, + alertFromError, useAlertContext, } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; import { ButtonHandler } from "../mui/handlers.js"; -import { compose, StateViewMap } from "../utils/index.js"; +import { StateViewMap, compose } from "../utils/index.js"; import { AddNewActionView } from "../wallet/AddNewActionView.js"; import { NoBalanceHelp } from "./NoBalanceHelp.js"; @@ -64,7 +68,7 @@ export namespace State { export interface Balances { status: "balance"; error: undefined; - balances: Balance[]; + balances: WalletBalance[]; addAction: ButtonHandler; goToWalletDeposit: (currency: string) => Promise; goToWalletHistory: (currency: string) => Promise; diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx index 900218991..56d0ef7bd 100644 --- a/packages/taler-wallet-webextension/src/wallet/History.tsx +++ b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -17,26 +17,26 @@ import { AbsoluteTime, Amounts, - Balance, NotificationType, Transaction, + WalletBalance, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { Fragment, h, VNode } from "preact"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; import { useEffect, useState } from "preact/hooks"; import { ErrorAlertView } from "../components/CurrentAlerts.js"; +import { HistoryItem } from "../components/HistoryItem.js"; import { Loading } from "../components/Loading.js"; +import { Time } from "../components/Time.js"; import { CenteredBoldText, CenteredText, DateSeparator, NiceSelect, } from "../components/styled/index.js"; -import { Time } from "../components/Time.js"; -import { HistoryItem } from "../components/HistoryItem.js"; import { alertFromError, useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; import { NoBalanceHelp } from "../popup/NoBalanceHelp.js"; @@ -109,7 +109,7 @@ export function HistoryView({ goToWalletManualWithdraw: (currency?: string) => Promise; defaultCurrency?: string; transactions: Transaction[]; - balances: Balance[]; + balances: WalletBalance[]; }): VNode { const { i18n } = useTranslationContext(); const { pushAlertOnError } = useAlertContext(); -- cgit v1.2.3 From bdd906c88707b2ec8d6d1d4afbd0bba8e3a9a3cd Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 24 Sep 2023 13:01:42 +0200 Subject: adapt to corebank API change, minor refactoring --- packages/taler-harness/src/harness/helpers.ts | 4 +- .../taler-harness/src/integrationtests/test-kyc.ts | 4 +- .../src/integrationtests/test-payment-fault.ts | 4 +- .../integrationtests/test-wallet-notifications.ts | 4 +- .../test-withdrawal-bank-integrated.ts | 4 +- .../src/integrationtests/test-withdrawal-fees.ts | 4 +- packages/taler-util/src/bank-api-client.ts | 8 +- packages/taler-wallet-core/src/dbless.ts | 4 +- .../taler-wallet-core/src/operations/testing.ts | 146 ++++----------------- 9 files changed, 50 insertions(+), 132 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 0a864cad3..27980857c 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -592,7 +592,9 @@ export async function withdrawViaBankV2( // Confirm it - await bankClient.confirmWithdrawalOperation(user.username, wop); + await bankClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); return { withdrawalFinishedCond, diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 2b2b57183..4fc725bc3 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -331,7 +331,9 @@ export async function runKycTest(t: GlobalTestState) { // Confirm it - await bankClient.confirmWithdrawalOperation(user.username, wop); + await bankClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); const kycNotificationCond = walletClient.waitForNotificationCond((x) => { if ( diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index ca74a4ad6..8076e2fb4 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -153,7 +153,9 @@ export async function runPaymentFaultTest(t: GlobalTestState) { // Confirm it - await bankClient.confirmWithdrawalOperation(user.username, wop); + await bankClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); await wallet.runUntilDone(); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index ae582fe60..2496f4887 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -161,7 +161,9 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { // Confirm it - await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop); + await bankAccessApiClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); await withdrawalFinishedReceivedPromise; } 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 4a2cc7df9..8c8853f4a 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -129,7 +129,9 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Confirm it - await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop); + await bankAccessApiClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); await withdrawalBankConfirmedCond; diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index a5a5a0d99..d3df19664 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -152,7 +152,9 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) { // Confirm it - await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop); + await bankAccessApiClient.confirmWithdrawalOperation(user.username, { + withdrawalOperationId: wop.withdrawal_id, + }); await wallet.runUntilDone(); // Check balance diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts index facb02ea8..d42317f91 100644 --- a/packages/taler-util/src/bank-api-client.ts +++ b/packages/taler-util/src/bank-api-client.ts @@ -223,6 +223,10 @@ export interface AccountData { cashout_payto_uri?: string; } +export interface ConfirmWithdrawalArgs { + withdrawalOperationId: string; +} + /** * Client for the Taler corebank API. */ @@ -356,10 +360,10 @@ export class TalerCorebankApiClient { async confirmWithdrawalOperation( username: string, - wopi: WithdrawalOperationInfo, + wopi: ConfirmWithdrawalArgs, ): Promise { const url = new URL( - `accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`, + `withdrawals/${wopi.withdrawalOperationId}/confirm`, this.baseUrl, ); logger.info(`confirming withdrawal operation via ${url.href}`); diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 1684977d5..0d702a00c 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -142,7 +142,9 @@ export async function topupReserveWithDemobank( httpResp, codecForBankWithdrawalOperationPostResponse(), ); - await bankClient.confirmWithdrawalOperation(bankUser.username, wopi); + await bankClient.confirmWithdrawalOperation(bankUser.username, { + withdrawalOperationId: wopi.withdrawal_id, + }); } export async function withdrawCoin(args: { diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index b5840c3a6..9b5dd2a19 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -27,6 +27,7 @@ import { NotificationType, RegisterAccountRequest, stringToBytes, + TalerCorebankApiClient, TestPayResult, TransactionMajorState, TransactionMinorState, @@ -74,16 +75,6 @@ import { getTransactionById, getTransactions } from "./transactions.js"; const logger = new Logger("operations/testing.ts"); -interface BankUser { - username: string; - password: string; -} - -interface BankWithdrawalResponse { - taler_withdraw_uri: string; - withdrawal_id: string; -} - interface MerchantBackendInfo { baseUrl: string; authToken?: string; @@ -103,16 +94,6 @@ function makeId(length: number): string { return result; } -/** - * Helper function to generate the "Authorization" HTTP header. - * FIXME: redundant, put in taler-util - */ -function makeBasicAuthHeader(username: string, password: string): string { - const auth = `${username}:${password}`; - const authEncoded: string = base64FromArrayBuffer(stringToBytes(auth)); - return `Basic ${authEncoded}`; -} - export async function withdrawTestBalance( ws: InternalWalletState, req: WithdrawTestBalanceRequest, @@ -122,15 +103,18 @@ export async function withdrawTestBalance( const bankAccessApiBaseUrl = req.bankAccessApiBaseUrl; logger.trace( - `Registered bank user, bank access base url ${bankAccessApiBaseUrl}`, + `Registering bank user, bank access base url ${bankAccessApiBaseUrl}`, ); - const bankUser = await registerRandomBankUser(ws.http, bankAccessApiBaseUrl); + + const corebankClient = new TalerCorebankApiClient(bankAccessApiBaseUrl); + + const bankUser = await corebankClient.createRandomBankUser(); logger.trace(`Registered bank user ${JSON.stringify(bankUser)}`); - const wresp = await createDemoBankWithdrawalUri( - ws.http, - bankAccessApiBaseUrl, - bankUser, + corebankClient.setAuth(bankUser); + + const wresp = await corebankClient.createWithdrawalOperation( + bankUser.username, amount, ); @@ -140,14 +124,14 @@ export async function withdrawTestBalance( forcedDenomSel: req.forcedDenomSel, }); - await confirmBankWithdrawalUri( - ws.http, - bankAccessApiBaseUrl, - bankUser, - wresp.withdrawal_id, - ); + await corebankClient.confirmWithdrawalOperation(bankUser.username, { + withdrawalOperationId: wresp.withdrawal_id, + }); } +/** + * FIXME: User MerchantApiClient instead. + */ function getMerchantAuthHeader(m: MerchantBackendInfo): Record { if (m.authToken) { return { @@ -158,88 +142,8 @@ function getMerchantAuthHeader(m: MerchantBackendInfo): Record { } /** - * Use the testing API of a demobank to create a taler://withdraw URI - * that the wallet can then use to make a withdrawal. + * FIXME: User MerchantApiClient instead. */ -export async function createDemoBankWithdrawalUri( - http: HttpRequestLibrary, - bankAccessApiBaseUrl: string, - bankUser: BankUser, - amount: AmountString, -): Promise { - const reqUrl = new URL( - `accounts/${bankUser.username}/withdrawals`, - bankAccessApiBaseUrl, - ).href; - const resp = await http.postJson( - reqUrl, - { - amount, - }, - { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }, - ); - const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny()); - return respJson; -} - -async function confirmBankWithdrawalUri( - http: HttpRequestLibrary, - bankAccessApiBaseUrl: string, - bankUser: BankUser, - withdrawalId: string, -): Promise { - const reqUrl = new URL( - `accounts/${bankUser.username}/withdrawals/${withdrawalId}/confirm`, - bankAccessApiBaseUrl, - ).href; - const resp = await http.postJson( - reqUrl, - {}, - { - headers: { - Authorization: makeBasicAuthHeader( - bankUser.username, - bankUser.password, - ), - }, - }, - ); - await readSuccessResponseJsonOrThrow(resp, codecForAny()); - return; -} - -async function registerRandomBankUser( - http: HttpRequestLibrary, - corebankApiBaseUrl: string, -): Promise { - const reqUrl = new URL("accounts", corebankApiBaseUrl).href; - const randId = makeId(8); - const username = `testuser-${randId.toLowerCase()}`; - const password = `testpw-${randId}`; - - const bankUser: BankUser = { - username, - password, - }; - - const userReq: RegisterAccountRequest = { - username, - password, - name: username, - }; - - const resp = await http.fetch(reqUrl, { method: "POST", body: userReq }); - await checkSuccessResponseOrThrow(resp); - return bankUser; -} - async function refund( http: HttpRequestLibrary, merchantBackend: MerchantBackendInfo, @@ -267,6 +171,9 @@ async function refund( return refundUri; } +/** + * FIXME: User MerchantApiClient instead. + */ async function createOrder( http: HttpRequestLibrary, merchantBackend: MerchantBackendInfo, @@ -296,6 +203,9 @@ async function createOrder( return { orderId }; } +/** + * FIXME: User MerchantApiClient instead. + */ async function checkPayment( http: HttpRequestLibrary, merchantBackend: MerchantBackendInfo, @@ -309,16 +219,6 @@ async function checkPayment( return readSuccessResponseJsonOrThrow(resp, codecForCheckPaymentResponse()); } -interface BankUser { - username: string; - password: string; -} - -interface BankWithdrawalResponse { - taler_withdraw_uri: string; - withdrawal_id: string; -} - async function makePayment( ws: InternalWalletState, merchant: MerchantBackendInfo, -- cgit v1.2.3 From 7b93938e710c8673ae9a0381b8867705ae872d6f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 24 Sep 2023 21:03:22 +0200 Subject: harness: add libeufin-bank integration test --- packages/taler-harness/src/env-full.ts | 6 +- packages/taler-harness/src/harness/harness.ts | 166 +++++++++++++-- packages/taler-harness/src/harness/helpers.ts | 14 +- .../src/integrationtests/test-bank-api.ts | 6 +- .../src/integrationtests/test-deposit.ts | 4 +- .../integrationtests/test-exchange-management.ts | 6 +- .../integrationtests/test-exchange-timetravel.ts | 6 +- .../src/integrationtests/test-fee-regression.ts | 4 +- .../taler-harness/src/integrationtests/test-kyc.ts | 6 +- .../src/integrationtests/test-libeufin-bank.ts | 222 +++++++++++++++++++++ .../test-merchant-exchange-confusion.ts | 6 +- .../test-merchant-instances-delete.ts | 6 +- .../test-merchant-instances-urls.ts | 6 +- .../integrationtests/test-merchant-instances.ts | 8 +- .../src/integrationtests/test-payment-fault.ts | 4 +- .../src/integrationtests/test-payment-multiple.ts | 6 +- .../src/integrationtests/test-revocation.ts | 6 +- .../test-timetravel-autorefresh.ts | 6 +- .../integrationtests/test-wallet-notifications.ts | 4 +- .../src/integrationtests/test-wallettesting.ts | 4 +- .../test-withdrawal-bank-integrated.ts | 10 +- .../src/integrationtests/testrunner.ts | 2 + packages/taler-util/src/bank-api-client.ts | 41 +++- packages/taler-util/src/talerconfig.ts | 6 +- packages/taler-util/src/wallet-types.ts | 13 +- .../taler-wallet-core/src/operations/testing.ts | 45 +++++ packages/taler-wallet-core/src/wallet-api-types.ts | 12 ++ packages/taler-wallet-core/src/wallet.ts | 7 + 28 files changed, 552 insertions(+), 80 deletions(-) create mode 100644 packages/taler-harness/src/integrationtests/test-libeufin-bank.ts (limited to 'packages/taler-util') diff --git a/packages/taler-harness/src/env-full.ts b/packages/taler-harness/src/env-full.ts index 210d38e32..bb2cb8c47 100644 --- a/packages/taler-harness/src/env-full.ts +++ b/packages/taler-harness/src/env-full.ts @@ -25,7 +25,7 @@ import { ExchangeService, FakebankService, MerchantService, - getPayto, + generateRandomPayto, } from "./harness/harness.js"; /** @@ -82,7 +82,7 @@ export async function runEnvFull(t: GlobalTestState): Promise { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -91,7 +91,7 @@ export async function runEnvFull(t: GlobalTestState): Promise { await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index edb0071c8..8f2d40d6e 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -565,7 +565,7 @@ class BankServiceBase { protected globalTestState: GlobalTestState, protected bankConfig: BankConfig, protected configFile: string, - ) { } + ) {} } export interface HarnessExchangeBankAccount { @@ -580,7 +580,8 @@ export interface HarnessExchangeBankAccount { */ export class FakebankService extends BankServiceBase - implements BankServiceHandle { + implements BankServiceHandle +{ proc: ProcessWrapper | undefined; http = createPlatformHttpLib({ enableThrottling: false }); @@ -664,7 +665,7 @@ export class FakebankService return { accountName: accountName, accountPassword: password, - accountPaytoUri: getPayto(accountName), + accountPaytoUri: generateRandomPayto(accountName), wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/accounts/${accountName}/taler-wire-gateway/`, }; } @@ -702,6 +703,140 @@ export class FakebankService } } +/** + * Implementation of the bank service using the "taler-fakebank-run" tool. + */ +export class LibeufinBankService + extends BankServiceBase + implements BankServiceHandle +{ + proc: ProcessWrapper | undefined; + + http = createPlatformHttpLib({ enableThrottling: false }); + + // We store "created" accounts during setup and + // register them after startup. + private accounts: { + accountName: string; + accountPassword: string; + }[] = []; + + /** + * Create a new fakebank service handle. + * + * First generates the configuration for the fakebank and + * then creates a fakebank handle, but doesn't start the fakebank + * service yet. + */ + static async create( + gc: GlobalTestState, + bc: BankConfig, + ): Promise { + const config = new Configuration(); + const testDir = bc.overrideTestDir ?? gc.testDir; + setTalerPaths(config, testDir + "/talerhome"); + config.setString("libeufin-bankdb", "config", bc.database); + config.setString("libeufin-bank", "currency", bc.currency); + config.setString("libeufin-bank", "port", `${bc.httpPort}`); + config.setString("libeufin-bank", "serve", "tcp"); + config.setString( + "libeufin-bank", + "DEFAULT_CUSTOMER_DEBT_LIMIT", + `${bc.currency}:500`, + ); + config.setString( + "libeufin-bank", + "DEFAULT_ADMIN_DEBT_LIMIT", + `${bc.currency}:999999`, + ); + config.setString( + "libeufin-bank", + "registration_bonus", + `${bc.currency}:100`, + ); + config.setString("libeufin-bank", "registration_bonus_enabled", `yes`); + config.setString("libeufin-bank", "max_auth_token_duration", "1h"); + const cfgFilename = testDir + "/bank.conf"; + config.write(cfgFilename, { excludeDefaults: true }); + + return new LibeufinBankService(gc, bc, cfgFilename); + } + + static fromExistingConfig( + gc: GlobalTestState, + opts: { overridePath?: string }, + ): FakebankService { + const testDir = opts.overridePath ?? gc.testDir; + const cfgFilename = testDir + `/bank.conf`; + const config = Configuration.load(cfgFilename); + const bc: BankConfig = { + allowRegistrations: + config.getYesNo("libeufin-bank", "allow_registrations").orUndefined() ?? + true, + currency: config.getString("libeufin-bank", "currency").required(), + database: config + .getString("libeufin-bankdb", "config") + .required(), + httpPort: config.getNumber("libeufin-bank", "port").required(), + maxDebt: config + .getString("libeufin-bank", "DEFAULT_CUSTOMER_DEBT_LIMIT") + .required(), + }; + return new FakebankService(gc, bc, cfgFilename); + } + + setSuggestedExchange(e: ExchangeServiceInterface) { + if (!!this.proc) { + throw Error("Can't set suggested exchange while bank is running."); + } + const config = Configuration.load(this.configFile); + config.setString("libeufin-bank", "suggested_withdrawal_exchange", e.baseUrl); + config.write(this.configFile, { excludeDefaults: true }); + } + + get baseUrl(): string { + return `http://localhost:${this.bankConfig.httpPort}/`; + } + + get bankAccessApiBaseUrl(): string { + return this.baseUrl; + } + + get port() { + return this.bankConfig.httpPort; + } + + async start(): Promise { + logger.info("starting libeufin-bank"); + if (this.proc) { + logger.info("libeufin-bank already running, not starting again"); + return; + } + + await sh( + this.globalTestState, + "libeufin-bank-dbinit", + `libeufin-bank dbinit -r -c "${this.configFile}"`, + ); + + this.proc = this.globalTestState.spawnService( + "libeufin-bank", + ["serve", "-c", this.configFile], + "libeufin-bank-httpd", + ); + await this.pingUntilAvailable(); + const bankClient = new TalerCorebankApiClient(this.bankAccessApiBaseUrl); + for (const acc of this.accounts) { + await bankClient.registerAccount(acc.accountName, acc.accountPassword); + } + } + + async pingUntilAvailable(): Promise { + const url = `http://localhost:${this.bankConfig.httpPort}/config`; + await pingProc(this.proc, url, "libeufin-bank"); + } +} + // Use libeufin bank instead of pybank. const useLibeufinBank = false; @@ -1011,7 +1146,7 @@ export class ExchangeService implements ExchangeServiceInterface { private exchangeConfig: ExchangeConfig, private configFilename: string, private keyPair: EddsaKeyPair, - ) { } + ) {} get name() { return this.exchangeConfig.name; @@ -1367,7 +1502,7 @@ export class MerchantService implements MerchantServiceInterface { private globalState: GlobalTestState, private merchantConfig: MerchantConfig, private configFilename: string, - ) { } + ) {} private currentTimetravelOffsetMs: number | undefined; @@ -1495,7 +1630,7 @@ export class MerchantService implements MerchantServiceInterface { return await this.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, @@ -1658,6 +1793,7 @@ export async function runTestWithState( e.message, `error detail: ${j2s(e.errorDetail)}`, ); + console.error(e.stack); } else { console.error("FATAL: test failed with exception", e); } @@ -1705,7 +1841,7 @@ export class WalletService { constructor( private globalState: GlobalTestState, private opts: WalletServiceOptions, - ) { } + ) {} get socketPath() { const unixPath = path.join( @@ -1814,7 +1950,7 @@ export class WalletClient { return client.call(operation, payload); } - constructor(private args: WalletClientArgs) { } + constructor(private args: WalletClientArgs) {} async connect(): Promise { const waiter = this.waiter; @@ -1881,9 +2017,11 @@ export class WalletCli { ? `--crypto-worker=${cliOpts.cryptoWorkerType}` : ""; const logName = `wallet-${self.name}`; - const command = `taler-wallet-cli ${self.timetravelArg ?? "" - } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${self.dbfile - }' api '${op}' ${shellWrap(JSON.stringify(payload))}`; + const command = `taler-wallet-cli ${ + self.timetravelArg ?? "" + } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${ + self.dbfile + }' api '${op}' ${shellWrap(JSON.stringify(payload))}`; const resp = await sh(self.globalTestState, logName, command); logger.info("--- wallet core response ---"); logger.info(resp); @@ -1966,7 +2104,7 @@ export class WalletCli { } } -export function getRandomIban(salt: string | null = null): string { +export function generateRandomTestIban(salt: string | null = null): string { function getBban(salt: string | null): string { if (!salt) return Math.random().toString().substring(2, 6); let hashed = hash(stringToBytes(salt)); @@ -1998,9 +2136,9 @@ export function getWireMethodForTest(): string { * Generate a payto address, whose authority depends * on whether the banking is served by euFin or Pybank. */ -export function getPayto(label: string): string { +export function generateRandomPayto(label: string): string { if (useLibeufinBank) - return `payto://iban/SANDBOXX/${getRandomIban( + return `payto://iban/SANDBOXX/${generateRandomTestIban( label, )}?receiver-name=${label}`; return `payto://x-taler-bank/localhost/${label}`; diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 27980857c..68b7d087c 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -56,7 +56,7 @@ import { WalletClient, WalletService, WithAuthorization, - getPayto, + generateRandomPayto, setupDb, setupSharedDb, } from "./harness.js"; @@ -236,7 +236,7 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -245,7 +245,7 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -368,7 +368,7 @@ export async function createSimpleTestkudosEnvironmentV2( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -377,7 +377,7 @@ export async function createSimpleTestkudosEnvironmentV2( await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -512,13 +512,13 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index 740e89c30..b87a4043b 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -30,7 +30,7 @@ import { ExchangeService, GlobalTestState, MerchantService, - getPayto, + generateRandomPayto, setupDb, } from "../harness/harness.js"; @@ -88,13 +88,13 @@ export async function runBankApiTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-deposit.ts b/packages/taler-harness/src/integrationtests/test-deposit.ts index 7e1bb2a5c..d4bfa3da5 100644 --- a/packages/taler-harness/src/integrationtests/test-deposit.ts +++ b/packages/taler-harness/src/integrationtests/test-deposit.ts @@ -23,7 +23,7 @@ import { TransactionMinorState, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { GlobalTestState, getPayto } from "../harness/harness.js"; +import { GlobalTestState, generateRandomPayto } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV2, withdrawViaBankV2, @@ -75,7 +75,7 @@ export async function runDepositTest(t: GlobalTestState) { WalletApiOperation.CreateDepositGroup, { amount: "TESTKUDOS:10", - depositPaytoUri: getPayto("foo"), + depositPaytoUri: generateRandomPayto("foo"), transactionId: depositTxId, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index 329012e42..fbee50385 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -36,7 +36,7 @@ import { GlobalTestState, MerchantService, WalletCli, - getPayto, + generateRandomPayto, setupDb, } from "../harness/harness.js"; @@ -105,13 +105,13 @@ export async function runExchangeManagementTest( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts index 2ef7683b3..efa21e1a0 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts @@ -35,7 +35,7 @@ import { makeNoFeeCoinConfig } from "../harness/denomStructures.js"; import { BankService, ExchangeService, - getPayto, + generateRandomPayto, GlobalTestState, MerchantService, setupDb, @@ -151,13 +151,13 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-fee-regression.ts b/packages/taler-harness/src/integrationtests/test-fee-regression.ts index 2d84b3a7c..f164606c4 100644 --- a/packages/taler-harness/src/integrationtests/test-fee-regression.ts +++ b/packages/taler-harness/src/integrationtests/test-fee-regression.ts @@ -23,7 +23,7 @@ import { ExchangeService, GlobalTestState, MerchantService, - getPayto, + generateRandomPayto, setupDb, } from "../harness/harness.js"; import { @@ -142,7 +142,7 @@ export async function createMyTestkudosEnvironment( await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index 4fc725bc3..d646995d6 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -34,7 +34,7 @@ import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { BankService, ExchangeService, - getPayto, + generateRandomPayto, GlobalTestState, MerchantService, setupDb, @@ -162,7 +162,7 @@ export async function createKycTestkudosEnvironment( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), @@ -171,7 +171,7 @@ export async function createKycTestkudosEnvironment( await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), ), diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts b/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts new file mode 100644 index 000000000..66b4c0b80 --- /dev/null +++ b/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts @@ -0,0 +1,222 @@ +/* + This file is part of GNU Taler + (C) 2020 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 + */ + +/** + * Imports. + */ +import { + TalerCorebankApiClient, + CreditDebitIndicator, + WireGatewayApiClient, + createEddsaKeyPair, + encodeCrock, + Logger, + j2s, + NotificationType, + TransactionMajorState, + TransactionMinorState, +} from "@gnu-taler/taler-util"; +import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { + ExchangeService, + GlobalTestState, + LibeufinBankService, + MerchantService, + generateRandomPayto, + generateRandomTestIban, + setupDb, +} from "../harness/harness.js"; +import { createWalletDaemonWithClient } from "../harness/helpers.js"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; + +const logger = new Logger("test-libeufin-bank.ts"); + +/** + * Run test for the basic functionality of libeufin-bank. + */ +export async function runLibeufinBankTest(t: GlobalTestState) { + // Set up test environment + + const db = await setupDb(t); + + const bank = await LibeufinBankService.create(t, { + currency: "TESTKUDOS", + httpPort: 8082, + database: db.connStr, + allowRegistrations: true, + }); + + 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 exchangeIban = generateRandomTestIban(); + const exchangeBankUsername = "exchange"; + const exchangeBankPw = "mypw"; + const exchangePlainPayto = `payto://iban/${exchangeIban}`; + const exchangeExtendedPayto = `payto://iban/${exchangeIban}?receiver-name=Exchange`; + const wireGatewayApiBaseUrl = new URL( + "accounts/exchange/taler-wire-gateway/", + bank.baseUrl, + ).href; + + logger.info("creating bank account for the exchange"); + + exchange.addBankAccount("1", { + wireGatewayApiBaseUrl, + accountName: exchangeBankUsername, + accountPassword: exchangeBankPw, + accountPaytoUri: exchangeExtendedPayto, + }); + + bank.setSuggestedExchange(exchange); + + await bank.start(); + + await bank.pingUntilAvailable(); + + exchange.addOfferedCoins(defaultCoinConfig); + + await exchange.start(); + await exchange.pingUntilAvailable(); + + merchant.addExchange(exchange); + + await merchant.start(); + await merchant.pingUntilAvailable(); + + await merchant.addInstanceWithWireAccount({ + id: "default", + name: "Default Instance", + paytoUris: [generateRandomPayto("merchant-default")], + }); + + await merchant.addInstanceWithWireAccount({ + id: "minst1", + name: "minst1", + paytoUris: [generateRandomPayto("minst1")], + }); + + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "wallet", + }); + + console.log("setup done!"); + + const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + + // register exchange bank account + await bankClient.registerAccountExtended({ + name: "Exchange", + password: exchangeBankPw, + username: exchangeBankUsername, + is_taler_exchange: true, + internal_payto_uri: exchangePlainPayto, + }); + + const bankUser = await bankClient.registerAccount("user1", "pw1"); + bankClient.setAuth({ + username: "user1", + password: "pw1", + }); + + // Make sure that registering twice results in a 409 Conflict + // { + // const e = await t.assertThrowsTalerErrorAsync(async () => { + // await bankClient.registerAccount("user1", "pw2"); + // }); + // t.assertTrue(e.errorDetail.httpStatusCode === 409); + // } + + let balResp = await bankClient.getAccountBalance(bankUser.username); + + console.log(balResp); + + // Check that we got the sign-up bonus. + t.assertAmountEquals(balResp.balance.amount, "TESTKUDOS:100"); + t.assertTrue( + balResp.balance.credit_debit_indicator === CreditDebitIndicator.Credit, + ); + + const res = createEddsaKeyPair(); + + const wireGatewayApiClient = new WireGatewayApiClient(wireGatewayApiBaseUrl, { + auth: { + username: exchangeBankUsername, + password: exchangeBankPw, + }, + }); + + await wireGatewayApiClient.adminAddIncoming({ + amount: "TESTKUDOS:115", + debitAccountPayto: bankUser.accountPaytoUri, + reservePub: encodeCrock(res.eddsaPub), + }); + + balResp = await bankClient.getAccountBalance(bankUser.username); + t.assertAmountEquals(balResp.balance.amount, "TESTKUDOS:15"); + t.assertTrue( + balResp.balance.credit_debit_indicator === CreditDebitIndicator.Debit, + ); + + const wop = await bankClient.createWithdrawalOperation( + bankUser.username, + "TESTKUDOS:10", + ); + + const r1 = await walletClient.client.call( + WalletApiOperation.GetWithdrawalDetailsForUri, + { + talerWithdrawUri: wop.taler_withdraw_uri, + }, + ); + + console.log(j2s(r1)); + + const r2 = await walletClient.client.call( + WalletApiOperation.AcceptBankIntegratedWithdrawal, + { + exchangeBaseUrl: exchange.baseUrl, + talerWithdrawUri: wop.taler_withdraw_uri, + }, + ); + + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: r2.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.BankConfirmTransfer, + }, + }); + + await bankClient.confirmWithdrawalOperation(bankUser.username, { + withdrawalOperationId: wop.withdrawal_id, + }); + + await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); +} + +runLibeufinBankTest.suites = ["fakebank"]; 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 2f79041d6..35e3267b1 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts @@ -33,7 +33,7 @@ import { import { BankService, ExchangeService, - getPayto, + generateRandomPayto, GlobalTestState, harnessHttpLib, MerchantService, @@ -112,13 +112,13 @@ export async function createConfusedMerchantTestkudosEnvironment( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); 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 ff567d33d..4508b9976 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts @@ -22,7 +22,7 @@ import { ExchangeService, GlobalTestState, MerchantService, - getPayto, + generateRandomPayto, harnessHttpLib, setupDb, } from "../harness/harness.js"; @@ -78,7 +78,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, @@ -88,7 +88,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "myinst", name: "Second Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts index 071288b0f..a037a01c5 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts @@ -22,7 +22,7 @@ import { ExchangeService, GlobalTestState, MerchantService, - getPayto, + generateRandomPayto, harnessHttpLib, setupDb, } from "../harness/harness.js"; @@ -74,7 +74,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { name: "My Default Instance", accounts: [ { - payto_uri: getPayto("bar"), + payto_uri: generateRandomPayto("bar"), }, ], auth: { @@ -97,7 +97,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { name: "My Second Instance", accounts: [ { - payto_uri: getPayto("bar"), + payto_uri: generateRandomPayto("bar"), }, ], auth: { diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts index 27de8a0a0..a77e9ca51 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts @@ -23,7 +23,7 @@ import { GlobalTestState, MerchantService, setupDb, - getPayto, + generateRandomPayto, harnessHttpLib, } from "../harness/harness.js"; @@ -78,7 +78,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, @@ -88,7 +88,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, @@ -98,7 +98,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "myinst", name: "Second Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], auth: { method: "external", }, diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index 8076e2fb4..63244a4e3 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -39,7 +39,7 @@ import { GlobalTestState, MerchantService, WalletCli, - getPayto, + generateRandomPayto, setupDb, } from "../harness/harness.js"; @@ -116,7 +116,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); const merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl()); diff --git a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts index 4ef5e3bff..0caa3c3e7 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts @@ -25,7 +25,7 @@ import { ExchangeService, GlobalTestState, MerchantService, - getPayto, + generateRandomPayto, setupDb, } from "../harness/harness.js"; import { @@ -87,13 +87,13 @@ async function setupTest(t: GlobalTestState): Promise<{ await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-revocation.ts b/packages/taler-harness/src/integrationtests/test-revocation.ts index 0cb6987ad..9ed2d6206 100644 --- a/packages/taler-harness/src/integrationtests/test-revocation.ts +++ b/packages/taler-harness/src/integrationtests/test-revocation.ts @@ -27,7 +27,7 @@ import { setupDb, BankService, delayMs, - getPayto, + generateRandomPayto, WalletClient, } from "../harness/harness.js"; import { @@ -125,13 +125,13 @@ async function createTestEnvironment( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts b/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts index b94f7757c..449142809 100644 --- a/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts +++ b/packages/taler-harness/src/integrationtests/test-timetravel-autorefresh.ts @@ -32,7 +32,7 @@ import { makeNoFeeCoinConfig } from "../harness/denomStructures.js"; import { BankService, ExchangeService, - getPayto, + generateRandomPayto, GlobalTestState, MerchantService, setupDb, @@ -97,13 +97,13 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); await merchant.addInstanceWithWireAccount({ id: "minst1", name: "minst1", - paytoUris: [getPayto("minst1")], + paytoUris: [generateRandomPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index 2496f4887..0b5bc45ef 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -32,7 +32,7 @@ import { MerchantService, WalletClient, WalletService, - getRandomIban, + generateRandomTestIban, setupDb, } from "../harness/harness.js"; @@ -94,7 +94,7 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { id: "default", name: "Default Instance", paytoUris: [ - `payto://iban/SANDBOXX/${getRandomIban(label)}?receiver-name=${label}`, + `payto://iban/SANDBOXX/${generateRandomTestIban(label)}?receiver-name=${label}`, ], defaultWireTransferDelay: Duration.toTalerProtocolDuration( Duration.fromSpec({ minutes: 1 }), diff --git a/packages/taler-harness/src/integrationtests/test-wallettesting.ts b/packages/taler-harness/src/integrationtests/test-wallettesting.ts index 4fa870f1c..6d58ae1f2 100644 --- a/packages/taler-harness/src/integrationtests/test-wallettesting.ts +++ b/packages/taler-harness/src/integrationtests/test-wallettesting.ts @@ -32,7 +32,7 @@ import { MerchantService, setupDb, WalletCli, - getPayto, + generateRandomPayto, } from "../harness/harness.js"; import { SimpleTestEnvironment } from "../harness/helpers.js"; @@ -94,7 +94,7 @@ export async function createMyEnvironment( await merchant.addInstanceWithWireAccount({ id: "default", name: "Default Instance", - paytoUris: [getPayto("merchant-default")], + paytoUris: [generateRandomPayto("merchant-default")], }); console.log("setup done!"); 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 8c8853f4a..817da5865 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -41,12 +41,12 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Create a withdrawal operation - const bankAccessApiClient = new TalerCorebankApiClient( + const corebankApiClient = new TalerCorebankApiClient( bank.bankAccessApiBaseUrl, ); - const user = await bankAccessApiClient.createRandomBankUser(); - bankAccessApiClient.setAuth(user); - const wop = await bankAccessApiClient.createWithdrawalOperation( + const user = await corebankApiClient.createRandomBankUser(); + corebankApiClient.setAuth(user); + const wop = await corebankApiClient.createWithdrawalOperation( user.username, "TESTKUDOS:10", ); @@ -129,7 +129,7 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Confirm it - await bankAccessApiClient.confirmWithdrawalOperation(user.username, { + await corebankApiClient.confirmWithdrawalOperation(user.username, { withdrawalOperationId: wop.withdrawal_id, }); diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index 071871837..cf5691fe3 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -92,6 +92,7 @@ import { runWithdrawalFeesTest } from "./test-withdrawal-fees.js"; import { runWithdrawalHugeTest } from "./test-withdrawal-huge.js"; import { runWithdrawalManualTest } from "./test-withdrawal-manual.js"; import { runWalletGenDbTest } from "./test-wallet-gendb.js"; +import { runLibeufinBankTest } from "./test-libeufin-bank.js"; /** * Test runner. @@ -173,6 +174,7 @@ const allTests: TestMainFunction[] = [ runStoredBackupsTest, runPaymentExpiredTest, runWalletGenDbTest, + runLibeufinBankTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts index d42317f91..a8cd4b0da 100644 --- a/packages/taler-util/src/bank-api-client.ts +++ b/packages/taler-util/src/bank-api-client.ts @@ -264,7 +264,7 @@ export class TalerCorebankApiClient { const resp = await this.httpLib.fetch(url.href, { headers: this.makeAuthHeader(), }); - return await resp.json(); + return readSuccessResponseJsonOrThrow(resp, codecForAny()); } async getTransactions(username: string): Promise { @@ -295,6 +295,30 @@ export class TalerCorebankApiClient { return await readSuccessResponseJsonOrThrow(resp, codecForAny()); } + async registerAccountExtended(req: RegisterAccountRequest): Promise { + const url = new URL("accounts", this.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: req, + }); + + if ( + resp.status !== 200 && + resp.status !== 201 && + resp.status !== 202 && + resp.status !== 204 + ) { + logger.error(`unexpected status ${resp.status} from POST ${url.href}`); + logger.error(`${j2s(await resp.json())}`); + throw TalerError.fromDetail( + TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, + { + httpStatusCode: resp.status, + }, + ); + } + } + /** * Register a new account and return information about it. * @@ -311,7 +335,13 @@ export class TalerCorebankApiClient { name: username, }, }); - if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) { + if ( + resp.status !== 200 && + resp.status !== 201 && + resp.status !== 202 && + resp.status !== 204 + ) { + logger.error(`unexpected status ${resp.status} from POST ${url.href}`); logger.error(`${j2s(await resp.json())}`); throw TalerError.fromDetail( TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, @@ -320,8 +350,13 @@ export class TalerCorebankApiClient { }, ); } + // FIXME: Corebank should directly return this info! const infoUrl = new URL(`accounts/${username}`, this.baseUrl); - const infoResp = await this.httpLib.fetch(infoUrl.href); + const infoResp = await this.httpLib.fetch(infoUrl.href, { + headers: { + Authorization: makeBasicAuthHeader(username, password), + }, + }); // FIXME: Validate! const acctInfo: AccountData = await readSuccessResponseJsonOrThrow( infoResp, diff --git a/packages/taler-util/src/talerconfig.ts b/packages/taler-util/src/talerconfig.ts index e9eb71279..f817d9bcb 100644 --- a/packages/taler-util/src/talerconfig.ts +++ b/packages/taler-util/src/talerconfig.ts @@ -143,9 +143,9 @@ export function expandPath(path: string): string { export function pathsub( x: string, lookup: (s: string, depth: number) => string | undefined, - depth = 0, + recursionDepth = 0, ): string { - if (depth >= 128) { + if (recursionDepth >= 128) { throw Error("recursion in path substitution"); } let s = x; @@ -201,7 +201,7 @@ export function pathsub( } else { const m = /^[a-zA-Z-_][a-zA-Z0-9-_]*/.exec(s.substring(l + 1)); if (m && m[0]) { - const r = lookup(m[0], depth + 1); + const r = lookup(m[0], recursionDepth + 1); if (r !== undefined) { s = s.substring(0, l) + r + s.substring(l + 1 + m[0].length); l = l + r.length; diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 87985fa2a..c5c2c375c 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -73,7 +73,13 @@ import { codecForAbsoluteTime, codecForTimestamp, } from "./time.js"; -import { OrderShortInfo, TransactionType } from "./transactions-types.js"; +import { + OrderShortInfo, + TransactionMajorState, + TransactionMinorState, + TransactionState, + TransactionType, +} from "./transactions-types.js"; /** * Identifier for a transaction in the wallet. @@ -2715,3 +2721,8 @@ export interface WalletContractData { maxDepositFee: AmountString; minimumAge?: number; } + +export interface TestingWaitTransactionRequest { + transactionId: string; + txState: TransactionState; +} diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index 9b5dd2a19..b21f1992c 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -23,6 +23,7 @@ import { ConfirmPayResultType, Duration, IntegrationTestV2Args, + j2s, Logger, NotificationType, RegisterAccountRequest, @@ -31,6 +32,7 @@ import { TestPayResult, TransactionMajorState, TransactionMinorState, + TransactionState, TransactionType, WithdrawTestBalanceRequest, } from "@gnu-taler/taler-util"; @@ -494,6 +496,49 @@ async function waitUntilPendingReady( cancelNotifs(); } +/** + * Wait until a transaction is in a particular state. + */ +export async function waitTransactionState( + ws: InternalWalletState, + transactionId: string, + txState: TransactionState, +): Promise { + logger.info( + `starting waiting for ${transactionId} to be in ${JSON.stringify( + txState, + )})`, + ); + ws.ensureTaskLoopRunning(); + let p: OpenedPromise | undefined = undefined; + const cancelNotifs = ws.addNotificationListener((notif) => { + if (!p) { + return; + } + if (notif.type === NotificationType.TransactionStateTransition) { + p.resolve(); + } + }); + while (1) { + p = openPromise(); + const tx = await getTransactionById(ws, { + transactionId, + }); + if ( + tx.txState.major === txState.major && + tx.txState.minor === txState.minor + ) { + break; + } + // Wait until transaction state changed + await p.promise; + } + logger.info( + `done waiting for ${transactionId} to be in ${JSON.stringify(txState)}`, + ); + cancelNotifs(); +} + export async function runIntegrationTest2( ws: InternalWalletState, args: IntegrationTestV2Args, diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 3520a05cb..6d66e7ad3 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -104,6 +104,7 @@ import { TestPayArgs, TestPayResult, TestingSetTimetravelRequest, + TestingWaitTransactionRequest, Transaction, TransactionByIdRequest, TransactionsRequest, @@ -214,6 +215,7 @@ export enum WalletApiOperation { ValidateIban = "validateIban", TestingWaitTransactionsFinal = "testingWaitTransactionsFinal", TestingWaitRefreshesFinal = "testingWaitRefreshesFinal", + TestingWaitTransactionState = "testingWaitTransactionState", TestingSetTimetravel = "testingSetTimetravel", GetScopedCurrencyInfo = "getScopedCurrencyInfo", ListStoredBackups = "listStoredBackups", @@ -1004,6 +1006,15 @@ export type TestingWaitRefreshesFinal = { response: EmptyObject; }; +/** + * Wait until a transaction is in a particular state. + */ +export type TestingWaitTransactionStateOp = { + op: WalletApiOperation.TestingWaitTransactionState; + request: TestingWaitTransactionRequest; + response: EmptyObject; +}; + /** * Set a coin as (un-)suspended. * Suspended coins won't be used for payments. @@ -1108,6 +1119,7 @@ export type WalletOperations = { [WalletApiOperation.TestingWaitTransactionsFinal]: TestingWaitTransactionsFinal; [WalletApiOperation.TestingWaitRefreshesFinal]: TestingWaitRefreshesFinal; [WalletApiOperation.TestingSetTimetravel]: TestingSetTimetravelOp; + [WalletApiOperation.TestingWaitTransactionState]: TestingWaitTransactionStateOp; [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 75f1a33a9..ccc7ec094 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -127,6 +127,7 @@ import { codecForRecoverStoredBackupRequest, codecForTestingSetTimetravelRequest, setDangerousTimetravel, + TestingWaitTransactionRequest, } from "@gnu-taler/taler-util"; import type { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; @@ -250,6 +251,7 @@ import { runIntegrationTest, runIntegrationTest2, testPay, + waitTransactionState, waitUntilDone, waitUntilRefreshesDone, withdrawTestBalance, @@ -1414,6 +1416,11 @@ async function dispatchRequestInternal( const resp = await getBackupRecovery(ws); return resp; } + case WalletApiOperation.TestingWaitTransactionState: { + const req = payload as TestingWaitTransactionRequest; + await waitTransactionState(ws, req.transactionId, req.txState); + return {}; + } case WalletApiOperation.GetScopedCurrencyInfo: { // Ignore result, just validate in this mock implementation codecForGetCurrencyInfoRequest().decode(payload); -- cgit v1.2.3 From ae49194d4271f1108ec9b8318ea3b7977314cb85 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 25 Sep 2023 08:40:18 -0300 Subject: more ui --- .../demobank-ui/src/components/ErrorLoading.tsx | 19 +++++-- packages/demobank-ui/src/components/Routing.tsx | 4 +- .../src/components/Transactions/views.tsx | 1 + packages/demobank-ui/src/hooks/access.ts | 2 +- .../demobank-ui/src/pages/AccountPage/index.ts | 10 ++-- .../demobank-ui/src/pages/AccountPage/state.ts | 7 +++ packages/demobank-ui/src/pages/BankFrame.tsx | 5 +- packages/demobank-ui/src/pages/HomePage.tsx | 8 +-- packages/demobank-ui/src/pages/LoginForm.tsx | 4 +- .../demobank-ui/src/pages/OperationState/index.ts | 11 ++-- .../demobank-ui/src/pages/OperationState/state.ts | 36 ++++++++++---- .../demobank-ui/src/pages/OperationState/views.tsx | 44 ++++++---------- packages/demobank-ui/src/pages/PaymentOptions.tsx | 4 +- .../demobank-ui/src/pages/RegistrationPage.tsx | 58 +++++++++++++++++++--- packages/demobank-ui/src/pages/Test.tsx | 5 -- .../demobank-ui/src/pages/WalletWithdrawForm.tsx | 1 - packages/taler-util/src/errors.ts | 2 +- .../taler-wallet-core/src/operations/withdraw.ts | 17 +++---- packages/taler-wallet-core/src/versions.ts | 2 +- 19 files changed, 145 insertions(+), 95 deletions(-) delete mode 100644 packages/demobank-ui/src/pages/Test.tsx (limited to 'packages/taler-util') diff --git a/packages/demobank-ui/src/components/ErrorLoading.tsx b/packages/demobank-ui/src/components/ErrorLoading.tsx index fbc4ffceb..a4faa4d5d 100644 --- a/packages/demobank-ui/src/components/ErrorLoading.tsx +++ b/packages/demobank-ui/src/components/ErrorLoading.tsx @@ -15,15 +15,24 @@ GNU Taler; see the file COPYING. If not, see */ -import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { HttpError, useTranslationContext } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; -export function ErrorLoading(): VNode { +export function ErrorLoading({ error }: { error: HttpError }): VNode { const { i18n } = useTranslationContext() return ( -
- Could not complete the request - +
+
+
+ +
+
+

{error.message}

+
+
+
); } diff --git a/packages/demobank-ui/src/components/Routing.tsx b/packages/demobank-ui/src/components/Routing.tsx index d51bd01eb..2710069c2 100644 --- a/packages/demobank-ui/src/components/Routing.tsx +++ b/packages/demobank-ui/src/components/Routing.tsx @@ -23,7 +23,6 @@ import { BusinessAccount } from "../pages/business/Home.js"; import { HomePage, WithdrawalOperationPage } from "../pages/HomePage.js"; import { PublicHistoriesPage } from "../pages/PublicHistoriesPage.js"; import { RegistrationPage } from "../pages/RegistrationPage.js"; -import { Test } from "../pages/Test.js"; import { useBackendContext } from "../context/backend.js"; import { LoginForm } from "../pages/LoginForm.js"; import { AdminHome } from "../pages/admin/Home.js"; @@ -69,6 +68,9 @@ export function Routing(): VNode { onComplete={() => { route("/account"); }} + onCancel={() => { + route("/account"); + }} /> )} /> diff --git a/packages/demobank-ui/src/components/Transactions/views.tsx b/packages/demobank-ui/src/components/Transactions/views.tsx index b11888320..e34120e34 100644 --- a/packages/demobank-ui/src/components/Transactions/views.tsx +++ b/packages/demobank-ui/src/components/Transactions/views.tsx @@ -32,6 +32,7 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { export function ReadyView({ transactions }: State.Ready): VNode { const { i18n } = useTranslationContext(); + if (!transactions.length) return
const txByDate = transactions.reduce((prev, cur) => { const d = cur.when.t_ms === "never" ? "" diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts index 13fee71f0..2f6848af8 100644 --- a/packages/demobank-ui/src/hooks/access.ts +++ b/packages/demobank-ui/src/hooks/access.ts @@ -94,7 +94,7 @@ export function useAccessAnonAPI(): AccessAnonAPI { const { request } = useAuthenticatedBackend(); const abortWithdrawal = async (id: string): Promise> => { - const res = await request(`accounts/withdrawals/${id}/abort`, { + const res = await request(`withdrawals/${id}/abort`, { method: "POST", contentType: "json", }); diff --git a/packages/demobank-ui/src/pages/AccountPage/index.ts b/packages/demobank-ui/src/pages/AccountPage/index.ts index ba9b85710..9230fb6b1 100644 --- a/packages/demobank-ui/src/pages/AccountPage/index.ts +++ b/packages/demobank-ui/src/pages/AccountPage/index.ts @@ -18,7 +18,7 @@ import { HttpError, HttpResponseOk, HttpResponsePaginated, utils } from "@gnu-ta import { AbsoluteTime, AmountJson, PaytoUriIBAN, PaytoUriTalerBank } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { useComponentState } from "./state.js"; -import { ReadyView, InvalidIbanView} from "./views.js"; +import { ReadyView, InvalidIbanView } from "./views.js"; import { VNode } from "preact"; import { LoginForm } from "../LoginForm.js"; import { ErrorLoading } from "../../components/ErrorLoading.js"; @@ -29,7 +29,7 @@ export interface Props { error: HttpResponsePaginated, ) => VNode; goToBusinessAccount: () => void; - goToConfirmOperation: (id:string) => void; + goToConfirmOperation: (id: string) => void; } export type State = State.Loading | State.LoadingError | State.Ready | State.InvalidIban | State.UserNotFound; @@ -48,14 +48,14 @@ export namespace State { export interface BaseInfo { error: undefined; } - + export interface Ready extends BaseInfo { status: "ready"; error: undefined; - account: string, + account: string, limit: AmountJson, goToBusinessAccount: () => void; - goToConfirmOperation: (id:string) => void; + goToConfirmOperation: (id: string) => void; } export interface InvalidIban { diff --git a/packages/demobank-ui/src/pages/AccountPage/state.ts b/packages/demobank-ui/src/pages/AccountPage/state.ts index b12afbf9e..3df463f4e 100644 --- a/packages/demobank-ui/src/pages/AccountPage/state.ts +++ b/packages/demobank-ui/src/pages/AccountPage/state.ts @@ -48,6 +48,13 @@ export function useComponentState({ account, goToBusinessAccount, goToConfirmOpe error: result, }; } + if (result.status === HttpStatusCode.Unauthorized) { + notifyError(i18n.str`Require login`, undefined); + return { + status: "error-user-not-found", + error: result, + }; + } return { status: "loading-error", error: result, diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx b/packages/demobank-ui/src/pages/BankFrame.tsx index a1414544e..214aac063 100644 --- a/packages/demobank-ui/src/pages/BankFrame.tsx +++ b/packages/demobank-ui/src/pages/BankFrame.tsx @@ -344,8 +344,6 @@ function StatusBanner(): VNode { class="fixed top-10 z-20 ml-4 mr-4" > { notifs.map(n => { - const info = n.message.type === "info" ? n.message : undefined - const error = n.message.type === "error" ? n.message : undefined switch (n.message.type) { case "error": return
@@ -478,8 +476,7 @@ function AccountBalance({ account }: { account: string }): VNode { // FIXME: balance return
- {Amounts.currencyOf(result.data.balance)} - {Amounts.stringifyValue(result.data.balance)} + {Amounts.currencyOf(result.data.balance)} {Amounts.stringifyValue(result.data.balance)} {/* {Amounts.currencyOf(result.data.balance.amount)}  {result.data.balance.credit_debit_indicator === "debit" ? "-" : ""} {Amounts.stringifyValue(result.data.balance.amount)} */} diff --git a/packages/demobank-ui/src/pages/HomePage.tsx b/packages/demobank-ui/src/pages/HomePage.tsx index d80a57d21..fb30c1218 100644 --- a/packages/demobank-ui/src/pages/HomePage.tsx +++ b/packages/demobank-ui/src/pages/HomePage.tsx @@ -59,7 +59,7 @@ export function HomePage({ account: string, onRegister: () => void; goToBusinessAccount: () => void; - goToConfirmOperation: (id:string) => void; + goToConfirmOperation: (id: string) => void; }): VNode { const { i18n } = useTranslationContext(); @@ -84,7 +84,7 @@ export function WithdrawalOperationPage({ //or return withdrawal uri from response const baseUrl = getInitialBackendBaseURL() const uri = stringifyWithdrawUri({ - bankIntegrationApiBaseUrl: `${baseUrl}/integration-api`, + bankIntegrationApiBaseUrl: `${baseUrl}/taler-integration`, withdrawalOperationId: operationId, }); const parsedUri = parseWithdrawUri(uri); @@ -98,7 +98,7 @@ export function WithdrawalOperationPage({ ); return ; } - + return ( ( result: | HttpResponsePaginated - | HttpResponse, + | HttpResponse, ): VNode { if (result.loading) return ; if (!result.ok) { diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx b/packages/demobank-ui/src/pages/LoginForm.tsx index 0d4bd1261..cfef71b9a 100644 --- a/packages/demobank-ui/src/pages/LoginForm.tsx +++ b/packages/demobank-ui/src/pages/LoginForm.tsx @@ -49,7 +49,7 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { ? i18n.str`Missing username` // : !USERNAME_REGEX.test(username) // ? i18n.str`Use letters and numbers only, and start with a lowercase letter` - : undefined, + : undefined, password: !password ? i18n.str`Missing password` : undefined, }) ?? busy; @@ -213,7 +213,7 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { {bankUiSettings.allowRegistrations && onRegister &&

+

@@ -360,39 +370,13 @@ export function ReadyView({ uri, onClose }: State.Ready): VNode<{}> { Scan the QR code with your mobile device.

-
- -
- {show && -
- -
- } +
+ +
-
- -
} diff --git a/packages/demobank-ui/src/pages/PaymentOptions.tsx b/packages/demobank-ui/src/pages/PaymentOptions.tsx index 2830f5c1e..49419d0dc 100644 --- a/packages/demobank-ui/src/pages/PaymentOptions.tsx +++ b/packages/demobank-ui/src/pages/PaymentOptions.tsx @@ -56,11 +56,11 @@ export function PaymentOptions({ limit, goToConfirmOperation }: { limit: AmountJ Withdraw digital money into your mobile wallet or browser extension {!!settings.currentWithdrawalOperationId && - + - Operation in progress + operation ready } diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx b/packages/demobank-ui/src/pages/RegistrationPage.tsx index 8221457bf..5325f43ab 100644 --- a/packages/demobank-ui/src/pages/RegistrationPage.tsx +++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx @@ -33,8 +33,10 @@ const logger = new Logger("RegistrationPage"); export function RegistrationPage({ onComplete, + onCancel }: { onComplete: () => void; + onCancel: () => void; }): VNode { const { i18n } = useTranslationContext(); if (!bankUiSettings.allowRegistrations) { @@ -42,7 +44,7 @@ export function RegistrationPage({

{i18n.str`Currently, the bank is not accepting new registrations!`}

); } - return ; + return ; } export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9-]*$/; @@ -50,7 +52,7 @@ export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9-]*$/; /** * Collect and submit registration data. */ -function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode { +function RegistrationForm({ onComplete, onCancel }: { onComplete: () => void, onCancel: () => void }): VNode { const backend = useBackendContext(); const [username, setUsername] = useState(); const [name, setName] = useState(); @@ -168,9 +170,38 @@ function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode { autoCapitalize="none" autoCorrect="off" > +
+ +
+ { + setName(e.currentTarget.value); + }} + /> + +
+
+
void }): VNode {
- +
void }): VNode {
- +
void }): VNode {
-
+
+
diff --git a/packages/taler-util/src/errors.ts b/packages/taler-util/src/errors.ts index 4399dbcf2..07a402413 100644 --- a/packages/taler-util/src/errors.ts +++ b/packages/taler-util/src/errors.ts @@ -78,7 +78,7 @@ export interface DetailsMap { stack?: string; }; [TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE]: { - exchangeProtocolVersion: string; + bankProtocolVersion: string; walletProtocolVersion: string; }; [TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN]: { diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index fb503d75f..2c9c95d4c 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -570,7 +570,7 @@ export async function getBankWithdrawalInfo( throw TalerError.fromDetail( TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE, { - exchangeProtocolVersion: config.version, + bankProtocolVersion: config.version, walletProtocolVersion: WALLET_BANK_INTEGRATION_PROTOCOL_VERSION, }, "bank integration protocol version not compatible with wallet", @@ -813,10 +813,10 @@ async function handleKycRequired( amlStatus === AmlStatus.normal || amlStatus === undefined ? WithdrawalGroupStatus.PendingKyc : amlStatus === AmlStatus.pending - ? WithdrawalGroupStatus.PendingAml - : amlStatus === AmlStatus.fronzen - ? WithdrawalGroupStatus.SuspendedAml - : assertUnreachable(amlStatus); + ? WithdrawalGroupStatus.PendingAml + : amlStatus === AmlStatus.fronzen + ? WithdrawalGroupStatus.SuspendedAml + : assertUnreachable(amlStatus); await tx.withdrawalGroups.put(wg2); const newTxState = computeWithdrawalTransactionStatus(wg2); @@ -1145,8 +1145,7 @@ export async function updateWithdrawalDenoms( denom.verificationStatus === DenominationVerificationStatus.Unverified ) { logger.trace( - `Validating denomination (${current + 1}/${ - denominations.length + `Validating denomination (${current + 1}/${denominations.length }) signature of ${denom.denomPubHash}`, ); let valid = false; @@ -1240,7 +1239,7 @@ async function queryReserve( if ( resp.status === 404 && result.talerErrorResponse.code === - TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN + TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN ) { return { ready: false }; } else { @@ -1775,7 +1774,7 @@ export async function getExchangeWithdrawalInfo( ) { logger.warn( `wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` + - `(exchange has ${exchangeDetails.protocolVersionRange}), checking for updates`, + `(exchange has ${exchangeDetails.protocolVersionRange}), checking for updates`, ); } } diff --git a/packages/taler-wallet-core/src/versions.ts b/packages/taler-wallet-core/src/versions.ts index 8b9177bc3..022f4900d 100644 --- a/packages/taler-wallet-core/src/versions.ts +++ b/packages/taler-wallet-core/src/versions.ts @@ -29,7 +29,7 @@ export const WALLET_EXCHANGE_PROTOCOL_VERSION = "17:0:0"; export const WALLET_MERCHANT_PROTOCOL_VERSION = "2:0:1"; /** - * Protocol version spoken with the merchant. + * Protocol version spoken with the bank. * * Uses libtool's current:revision:age versioning. */ -- cgit v1.2.3 From 256e86fdc00fc950e67a1472e9ba4c15b61d68bb Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 27 Sep 2023 09:22:18 +0200 Subject: add empty migration from previous database version --- packages/taler-harness/package.json | 4 ++-- packages/taler-util/package.json | 4 ++-- packages/taler-wallet-cli/package.json | 4 ++-- packages/taler-wallet-core/package.json | 4 ++-- packages/taler-wallet-core/src/db.ts | 1 + packages/taler-wallet-embedded/package.json | 4 ++-- packages/taler-wallet-webextension/manifest-common.json | 4 ++-- packages/taler-wallet-webextension/package.json | 4 ++-- packages/web-util/package.json | 2 +- 9 files changed, 16 insertions(+), 15 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-harness/package.json b/packages/taler-harness/package.json index 38f168af4..b1a9dc2e5 100644 --- a/packages/taler-harness/package.json +++ b/packages/taler-harness/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-harness", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "", "engines": { "node": ">=0.12.0" @@ -42,4 +42,4 @@ "@gnu-taler/taler-wallet-core": "workspace:*", "tslib": "^2.5.3" } -} +} \ No newline at end of file diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json index 80e99ae0e..6d80e9823 100644 --- a/packages/taler-util/package.json +++ b/packages/taler-util/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-util", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "Generic helper functionality for GNU Taler", "type": "module", "types": "./lib/index.node.d.ts", @@ -82,4 +82,4 @@ "lib/**/*test.js" ] } -} +} \ No newline at end of file diff --git a/packages/taler-wallet-cli/package.json b/packages/taler-wallet-cli/package.json index 382951223..0f1b3ea0c 100644 --- a/packages/taler-wallet-cli/package.json +++ b/packages/taler-wallet-cli/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-cli", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "", "engines": { "node": ">=0.18.0" @@ -41,4 +41,4 @@ "@gnu-taler/taler-wallet-core": "workspace:*", "tslib": "^2.5.3" } -} +} \ No newline at end of file diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json index 668fe4b92..8da42bfdc 100644 --- a/packages/taler-wallet-core/package.json +++ b/packages/taler-wallet-core/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-core", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "", "engines": { "node": ">=0.18.0" @@ -84,4 +84,4 @@ "lib/**/*test.*" ] } -} +} \ No newline at end of file diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index a5ead4d64..156651cc6 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -3092,6 +3092,7 @@ export async function openTalerDatabase( case "taler-wallet-main-v6": case "taler-wallet-main-v7": case "taler-wallet-main-v8": + case "taler-wallet-main-v9": // We consider this a pre-release // development version, no migration is done. await metaDb diff --git a/packages/taler-wallet-embedded/package.json b/packages/taler-wallet-embedded/package.json index 35a4fcffe..fff047d6b 100644 --- a/packages/taler-wallet-embedded/package.json +++ b/packages/taler-wallet-embedded/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-embedded", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "", "engines": { "node": ">=0.18.0" @@ -39,4 +39,4 @@ "@gnu-taler/anastasis-core": "workspace:*", "tslib": "^2.5.3" } -} +} \ No newline at end of file diff --git a/packages/taler-wallet-webextension/manifest-common.json b/packages/taler-wallet-webextension/manifest-common.json index bb752e1b7..9f8a978a3 100644 --- a/packages/taler-wallet-webextension/manifest-common.json +++ b/packages/taler-wallet-webextension/manifest-common.json @@ -2,8 +2,8 @@ "name": "GNU Taler Wallet (git)", "description": "Privacy preserving and transparent payments", "author": "GNU Taler Developers", - "version": "0.9.3.17", - "version_name": "0.9.3-dev.17", + "version": "0.9.3.26", + "version_name": "0.9.3-dev.26", "icons": { "16": "static/img/taler-logo-16.png", "19": "static/img/taler-logo-19.png", diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 23736729c..0b143f90a 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-webextension", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "GNU Taler Wallet browser extension", "main": "./build/index.js", "types": "./build/index.d.ts", @@ -75,4 +75,4 @@ "pogen": { "domain": "taler-wallet-webex" } -} +} \ No newline at end of file diff --git a/packages/web-util/package.json b/packages/web-util/package.json index 2c1b697d8..f09b96038 100644 --- a/packages/web-util/package.json +++ b/packages/web-util/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/web-util", - "version": "0.9.3-dev.17", + "version": "0.9.3-dev.26", "description": "Generic helper functionality for GNU Taler Web Apps", "type": "module", "types": "./lib/index.node.d.ts", -- cgit v1.2.3 From 61424e2cb51dde9a8c7442b20b6621cc8b1d3b26 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 27 Sep 2023 09:22:42 +0200 Subject: bump version --- packages/taler-harness/package.json | 2 +- packages/taler-util/package.json | 2 +- packages/taler-wallet-cli/package.json | 2 +- packages/taler-wallet-core/package.json | 2 +- packages/taler-wallet-embedded/package.json | 2 +- packages/taler-wallet-webextension/manifest-common.json | 4 ++-- packages/taler-wallet-webextension/package.json | 2 +- packages/web-util/package.json | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-harness/package.json b/packages/taler-harness/package.json index b1a9dc2e5..b4896916b 100644 --- a/packages/taler-harness/package.json +++ b/packages/taler-harness/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-harness", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "", "engines": { "node": ">=0.12.0" diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json index 6d80e9823..7fceb9576 100644 --- a/packages/taler-util/package.json +++ b/packages/taler-util/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-util", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "Generic helper functionality for GNU Taler", "type": "module", "types": "./lib/index.node.d.ts", diff --git a/packages/taler-wallet-cli/package.json b/packages/taler-wallet-cli/package.json index 0f1b3ea0c..571371b87 100644 --- a/packages/taler-wallet-cli/package.json +++ b/packages/taler-wallet-cli/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-cli", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "", "engines": { "node": ">=0.18.0" diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json index 8da42bfdc..beef99840 100644 --- a/packages/taler-wallet-core/package.json +++ b/packages/taler-wallet-core/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-core", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "", "engines": { "node": ">=0.18.0" diff --git a/packages/taler-wallet-embedded/package.json b/packages/taler-wallet-embedded/package.json index fff047d6b..442a1f962 100644 --- a/packages/taler-wallet-embedded/package.json +++ b/packages/taler-wallet-embedded/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-embedded", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "", "engines": { "node": ">=0.18.0" diff --git a/packages/taler-wallet-webextension/manifest-common.json b/packages/taler-wallet-webextension/manifest-common.json index 9f8a978a3..0e333c7a8 100644 --- a/packages/taler-wallet-webextension/manifest-common.json +++ b/packages/taler-wallet-webextension/manifest-common.json @@ -2,8 +2,8 @@ "name": "GNU Taler Wallet (git)", "description": "Privacy preserving and transparent payments", "author": "GNU Taler Developers", - "version": "0.9.3.26", - "version_name": "0.9.3-dev.26", + "version": "0.9.3.27", + "version_name": "0.9.3-dev.27", "icons": { "16": "static/img/taler-logo-16.png", "19": "static/img/taler-logo-19.png", diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 0b143f90a..fc91ed4cc 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/taler-wallet-webextension", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "GNU Taler Wallet browser extension", "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/web-util/package.json b/packages/web-util/package.json index f09b96038..5a5203392 100644 --- a/packages/web-util/package.json +++ b/packages/web-util/package.json @@ -1,6 +1,6 @@ { "name": "@gnu-taler/web-util", - "version": "0.9.3-dev.26", + "version": "0.9.3-dev.27", "description": "Generic helper functionality for GNU Taler Web Apps", "type": "module", "types": "./lib/index.node.d.ts", -- cgit v1.2.3 From 779ddae8b8c0e1b544ee370ac4d4b366333e7197 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 29 Sep 2023 14:46:13 -0300 Subject: iban country code should be always uppercased --- packages/taler-util/src/payto.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts index 60c4ba838..85870afcd 100644 --- a/packages/taler-util/src/payto.ts +++ b/packages/taler-util/src/payto.ts @@ -89,12 +89,13 @@ export function buildPayto( return result; } case "iban": { + const uppercased = first.toUpperCase() const result: PaytoUriIBAN = { isKnown: true, targetType: "iban", - iban: first, + iban: uppercased, params: {}, - targetPath: !second ? first : `${second}/${first}`, + targetPath: !second ? uppercased : `${second}/${uppercased}`, }; return result; } @@ -200,13 +201,13 @@ export function parsePaytoUri(s: string): PaytoUri | undefined { let iban: string | undefined = undefined; let bic: string | undefined = undefined; if (parts.length === 1) { - iban = parts[0]; + iban = parts[0].toUpperCase(); } if (parts.length === 2) { bic = parts[0]; - iban = parts[1]; + iban = parts[1].toUpperCase(); } else { - iban = targetPath; + iban = targetPath.toUpperCase(); } return { isKnown: true, -- cgit v1.2.3 From e54df1f167333de654a9a98545bae8ef495d6e52 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 2 Oct 2023 13:53:32 -0300 Subject: match the exchange spec --- packages/taler-util/src/taler-types.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/taler-types.ts b/packages/taler-util/src/taler-types.ts index eaba1ae3d..d8fdc2519 100644 --- a/packages/taler-util/src/taler-types.ts +++ b/packages/taler-util/src/taler-types.ts @@ -1922,22 +1922,13 @@ export interface BatchDepositSuccess { // Array of deposit confirmation signatures from the exchange // Entries must be in the same order the coins were given // in the batch deposit request. - exchange_sigs: DepositConfirmationSignature[]; + exchange_sig: EddsaSignatureString; } -export const codecForDepositConfirmationSignature = - (): Codec => - buildCodecForObject() - .property("exchange_sig", codecForString()) - .build("DepositConfirmationSignature"); - export const codecForBatchDepositSuccess = (): Codec => buildCodecForObject() .property("exchange_pub", codecForString()) - .property( - "exchange_sigs", - codecForList(codecForDepositConfirmationSignature()), - ) + .property("exchange_sig", codecForString()) .property("exchange_timestamp", codecForTimestamp) .property("transaction_base_url", codecOptional(codecForString())) .build("BatchDepositSuccess"); -- cgit v1.2.3 From 671bbf29548e2ec078b29e75e368d77ee7bdb81f Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 2 Oct 2023 22:48:29 +0200 Subject: wallet-core: implement explicit updateExchangeEntry request --- packages/taler-util/src/wallet-types.ts | 9 +++++++++ packages/taler-wallet-core/src/wallet-api-types.ts | 12 ++++++++++++ packages/taler-wallet-core/src/wallet.ts | 9 +++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index c5c2c375c..8fff8ae55 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1601,6 +1601,15 @@ export const codecForAddExchangeRequest = (): Codec => .property("masterPub", codecOptional(codecForString())) .build("AddExchangeRequest"); +export interface UpdateExchangeEntryRequest { + exchangeBaseUrl: string; +} + +export const codecForUpdateExchangeEntryRequest = (): Codec => + buildCodecForObject() + .property("exchangeBaseUrl", codecForString()) + .build("UpdateExchangeEntryRequest"); + export interface ForceExchangeUpdateRequest { exchangeBaseUrl: string; } diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 6d66e7ad3..26e86f43f 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -110,6 +110,7 @@ import { TransactionsRequest, TransactionsResponse, TxIdResponse, + UpdateExchangeEntryRequest, UserAttentionByIdRequest, UserAttentionsCountResponse, UserAttentionsRequest, @@ -222,6 +223,7 @@ export enum WalletApiOperation { CreateStoredBackup = "createStoredBackup", DeleteStoredBackup = "deleteStoredBackup", RecoverStoredBackup = "recoverStoredBackup", + UpdateExchangeEntry = "updateExchangeEntry", } // group: Initialization @@ -557,6 +559,15 @@ export type AddExchangeOp = { response: EmptyObject; }; +/** + * Update an exchange entry. + */ +export type UpdateExchangeEntryOp = { + op: WalletApiOperation.UpdateExchangeEntry; + request: UpdateExchangeEntryRequest; + response: EmptyObject; +}; + export type ListKnownBankAccountsOp = { op: WalletApiOperation.ListKnownBankAccounts; request: ListKnownBankAccountsRequest; @@ -1125,6 +1136,7 @@ export type WalletOperations = { [WalletApiOperation.ListStoredBackups]: ListStoredBackupsOp; [WalletApiOperation.DeleteStoredBackup]: DeleteStoredBackupOp; [WalletApiOperation.RecoverStoredBackup]: RecoverStoredBackupsOp; + [WalletApiOperation.UpdateExchangeEntry]: UpdateExchangeEntryOp; }; export type WalletCoreRequestType< diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 496297021..44076667d 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -128,6 +128,7 @@ import { codecForTestingSetTimetravelRequest, setDangerousTimetravel, TestingWaitTransactionRequest, + codecForUpdateExchangeEntryRequest, } from "@gnu-taler/taler-util"; import type { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; @@ -1071,8 +1072,7 @@ async function dispatchRequestInternal( case WalletApiOperation.WithdrawTestkudos: { await withdrawTestBalance(ws, { amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: - "https://bank.test.taler.net/", + bankAccessApiBaseUrl: "https://bank.test.taler.net/", exchangeBaseUrl: "https://exchange.test.taler.net/", }); return { @@ -1122,6 +1122,11 @@ async function dispatchRequestInternal( }); return {}; } + case WalletApiOperation.UpdateExchangeEntry: { + const req = codecForUpdateExchangeEntryRequest().decode(payload); + await updateExchangeFromUrl(ws, req.exchangeBaseUrl, {}); + return {}; + } case WalletApiOperation.ListExchanges: { return await getExchanges(ws); } -- cgit v1.2.3 From 535b990215bdd861df5cf6215a5f72a47576f89b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 4 Oct 2023 13:41:40 -0300 Subject: currency name up to 11 fractions up to 8 --- packages/taler-util/src/amounts.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts index a8df3679f..04343b8e9 100644 --- a/packages/taler-util/src/amounts.ts +++ b/packages/taler-util/src/amounts.ts @@ -345,9 +345,12 @@ export class Amounts { /** * Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct. + * + * Currency name size limit is 11 of ASCII letters + * Fraction size limit is 8 */ static parse(s: string): AmountJson | undefined { - const res = s.match(/^([a-zA-Z0-9_*-]+):([0-9]+)([.][0-9]+)?$/); + const res = s.match(/^([a-zA-Z]{1,11}):([0-9]+)([.][0-9]{1,8})?$/); if (!res) { return undefined; } -- cgit v1.2.3 From 97d7be7503168f4f3bbd05905d32aa76ca1636b2 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 6 Oct 2023 14:42:32 +0200 Subject: rename to corebank API --- packages/taler-harness/src/bench1.ts | 2 +- packages/taler-harness/src/bench3.ts | 2 +- packages/taler-harness/src/harness/harness.ts | 10 +++++----- packages/taler-harness/src/harness/helpers.ts | 2 +- packages/taler-harness/src/index.ts | 6 +++--- .../src/integrationtests/test-age-restrictions-merchant.ts | 2 +- .../taler-harness/src/integrationtests/test-bank-api.ts | 2 +- .../src/integrationtests/test-exchange-deposit.ts | 2 +- .../src/integrationtests/test-exchange-management.ts | 2 +- .../src/integrationtests/test-exchange-purse.ts | 2 +- .../src/integrationtests/test-forced-selection.ts | 2 +- packages/taler-harness/src/integrationtests/test-kyc.ts | 2 +- .../src/integrationtests/test-libeufin-bank.ts | 2 +- .../src/integrationtests/test-payment-fault.ts | 2 +- .../taler-harness/src/integrationtests/test-tipping.ts | 2 +- .../src/integrationtests/test-wallet-dbless.ts | 2 +- .../src/integrationtests/test-wallet-notifications.ts | 2 +- .../src/integrationtests/test-wallettesting.ts | 6 +++--- .../src/integrationtests/test-withdrawal-abort-bank.ts | 2 +- .../integrationtests/test-withdrawal-bank-integrated.ts | 2 +- .../src/integrationtests/test-withdrawal-fakebank.ts | 2 +- .../src/integrationtests/test-withdrawal-fees.ts | 2 +- .../src/integrationtests/test-withdrawal-huge.ts | 2 +- .../src/integrationtests/test-withdrawal-manual.ts | 2 +- packages/taler-util/src/wallet-types.ts | 14 +++++++------- packages/taler-wallet-cli/src/index.ts | 4 ++-- packages/taler-wallet-core/src/dbless.ts | 6 +++--- packages/taler-wallet-core/src/operations/testing.ts | 14 +++++++------- packages/taler-wallet-core/src/wallet.ts | 2 +- packages/taler-wallet-embedded/src/wallet-qjs.ts | 4 ++-- 30 files changed, 54 insertions(+), 54 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-harness/src/bench1.ts b/packages/taler-harness/src/bench1.ts index f7b42836d..efe162320 100644 --- a/packages/taler-harness/src/bench1.ts +++ b/packages/taler-harness/src/bench1.ts @@ -98,7 +98,7 @@ export async function runBench1(configJson: any): Promise { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { amount: b1conf.currency + ":" + withdrawAmount, - bankAccessApiBaseUrl: b1conf.bank, + corebankApiBaseUrl: b1conf.bank, exchangeBaseUrl: b1conf.exchange, }); diff --git a/packages/taler-harness/src/bench3.ts b/packages/taler-harness/src/bench3.ts index 55cd335f2..bc345aa9e 100644 --- a/packages/taler-harness/src/bench3.ts +++ b/packages/taler-harness/src/bench3.ts @@ -109,7 +109,7 @@ export async function runBench3(configJson: any): Promise { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { amount: b3conf.currency + ":" + withdrawAmount, - bankAccessApiBaseUrl: b3conf.bank, + corebankApiBaseUrl: b3conf.bank, exchangeBaseUrl: b3conf.exchange, }); diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index a57cb4355..e30cbcb54 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -650,7 +650,7 @@ export class FakebankService return `http://localhost:${this.bankConfig.httpPort}/`; } - get bankAccessApiBaseUrl(): string { + get corebankApiBaseUrl(): string { return this.baseUrl; } @@ -691,7 +691,7 @@ export class FakebankService "bank", ); await this.pingUntilAvailable(); - const bankClient = new TalerCorebankApiClient(this.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(this.corebankApiBaseUrl); for (const acc of this.accounts) { await bankClient.registerAccount(acc.accountName, acc.accountPassword); } @@ -798,7 +798,7 @@ export class LibeufinBankService return `http://localhost:${this.bankConfig.httpPort}/`; } - get bankAccessApiBaseUrl(): string { + get corebankApiBaseUrl(): string { return this.baseUrl; } @@ -825,7 +825,7 @@ export class LibeufinBankService "libeufin-bank-httpd", ); await this.pingUntilAvailable(); - const bankClient = new TalerCorebankApiClient(this.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(this.corebankApiBaseUrl); for (const acc of this.accounts) { await bankClient.registerAccount(acc.accountName, acc.accountPassword); } @@ -841,7 +841,7 @@ export class LibeufinBankService const useLibeufinBank = false; export interface BankServiceHandle { - readonly bankAccessApiBaseUrl: string; + readonly corebankApiBaseUrl: string; readonly http: HttpRequestLibrary; } diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 68b7d087c..8c1612457 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -560,7 +560,7 @@ export async function withdrawViaBankV2( ): Promise { const { walletClient: wallet, bank, exchange, amount } = p; - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation(user.username, amount); diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 1f5156b57..82d8e4326 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -312,7 +312,7 @@ deploymentCli const exchangeInfo = await downloadExchangeInfo(exchangeBaseUrl, http); await topupReserveWithDemobank({ amount: "KUDOS:10", - bankAccessApiBaseUrl: + corebankApiBaseUrl: "https://bank.demo.taler.net/", exchangeInfo, http, @@ -341,7 +341,7 @@ deploymentCli const exchangeInfo = await downloadExchangeInfo(exchangeBaseUrl, http); await topupReserveWithDemobank({ amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: + corebankApiBaseUrl: "https://bank.test.taler.net/", exchangeInfo, http, @@ -371,7 +371,7 @@ deploymentCli const exchangeInfo = await downloadExchangeInfo(exchangeBaseUrl, http); await topupReserveWithDemobank({ amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: "http://localhost:8082/taler-bank-access/", + corebankApiBaseUrl: "http://localhost:8082/taler-bank-access/", exchangeInfo, http, reservePub: reserveKeyPair.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 90b08724f..5653e22e2 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -179,7 +179,7 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { // Pay with coin from tipping { - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const mbu = await bankClient.createRandomBankUser(); const tipReserveResp = await merchantClient.createTippingReserve({ exchange_url: exchange.baseUrl, diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index b87a4043b..9c5b06397 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -99,7 +99,7 @@ export async function runBankApiTest(t: GlobalTestState) { console.log("setup done!"); - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const bankUser = await bankClient.registerAccount("user1", "pw1"); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts index 96255f5b5..8ad7daa63 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts @@ -66,7 +66,7 @@ export async function runExchangeDepositTest(t: GlobalTestState) { await topupReserveWithDemobank({ http, amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeInfo, reservePub: reserveKeyPair.pub, }); diff --git a/packages/taler-harness/src/integrationtests/test-exchange-management.ts b/packages/taler-harness/src/integrationtests/test-exchange-management.ts index fbee50385..a7908264d 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-management.ts @@ -263,7 +263,7 @@ export async function runExchangeManagementTest( // Create withdrawal operation - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-exchange-purse.ts b/packages/taler-harness/src/integrationtests/test-exchange-purse.ts index 5a1d02692..33a09ed16 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-purse.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-purse.ts @@ -79,7 +79,7 @@ export async function runExchangePurseTest(t: GlobalTestState) { amount: "TESTKUDOS:10", http, reservePub: reserveKeyPair.pub, - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeInfo, }); diff --git a/packages/taler-harness/src/integrationtests/test-forced-selection.ts b/packages/taler-harness/src/integrationtests/test-forced-selection.ts index 3425dadf1..917ad2025 100644 --- a/packages/taler-harness/src/integrationtests/test-forced-selection.ts +++ b/packages/taler-harness/src/integrationtests/test-forced-selection.ts @@ -38,7 +38,7 @@ export async function runForcedSelectionTest(t: GlobalTestState) { await walletClient.call(WalletApiOperation.WithdrawTestBalance, { exchangeBaseUrl: exchange.baseUrl, amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, forcedDenomSel: { denoms: [ { diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index d646995d6..319e8828f 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -302,7 +302,7 @@ export async function runKycTest(t: GlobalTestState) { // Withdraw digital cash into the wallet. - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const amount = "TESTKUDOS:20"; const user = await bankClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts b/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts index 66b4c0b80..c8c668bed 100644 --- a/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts @@ -126,7 +126,7 @@ export async function runLibeufinBankTest(t: GlobalTestState) { console.log("setup done!"); - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); // register exchange bank account await bankClient.registerAccountExtended({ diff --git a/packages/taler-harness/src/integrationtests/test-payment-fault.ts b/packages/taler-harness/src/integrationtests/test-payment-fault.ts index 63244a4e3..af6751ef4 100644 --- a/packages/taler-harness/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-harness/src/integrationtests/test-payment-fault.ts @@ -127,7 +127,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { // Create withdrawal operation - const bankClient = new TalerCorebankApiClient(bank.bankAccessApiBaseUrl); + const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl); const user = await bankClient.createRandomBankUser(); const wop = await bankClient.createWithdrawalOperation( diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index 3d4ea6663..12cdbae53 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -39,7 +39,7 @@ export async function runTippingTest(t: GlobalTestState) { await createSimpleTestkudosEnvironmentV2(t); const bankAccessApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const mbu = await bankAccessApiClient.createRandomBankUser(); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts b/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts index 153ae93d8..5e6539654 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts @@ -72,7 +72,7 @@ export async function runWalletDblessTest(t: GlobalTestState) { amount: "TESTKUDOS:10", http, reservePub: reserveKeyPair.pub, - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeInfo, }); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts index 0b5bc45ef..c87a9a264 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-notifications.ts @@ -122,7 +122,7 @@ export async function runWalletNotificationsTest(t: GlobalTestState) { }); const bankAccessApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); diff --git a/packages/taler-harness/src/integrationtests/test-wallettesting.ts b/packages/taler-harness/src/integrationtests/test-wallettesting.ts index 6d58ae1f2..e5191aa5b 100644 --- a/packages/taler-harness/src/integrationtests/test-wallettesting.ts +++ b/packages/taler-harness/src/integrationtests/test-wallettesting.ts @@ -120,7 +120,7 @@ export async function runWallettestingTest(t: GlobalTestState) { await wallet.client.call(WalletApiOperation.RunIntegrationTest, { amountToSpend: "TESTKUDOS:5", amountToWithdraw: "TESTKUDOS:10", - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeBaseUrl: exchange.baseUrl, merchantAuthToken: merchantAuthToken, merchantBaseUrl: merchant.makeInstanceBaseUrl(), @@ -143,7 +143,7 @@ export async function runWallettestingTest(t: GlobalTestState) { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeBaseUrl: exchange.baseUrl, }); @@ -168,7 +168,7 @@ export async function runWallettestingTest(t: GlobalTestState) { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeBaseUrl: exchange.baseUrl, }); 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 4a0dd845b..f9f2df0fc 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-abort-bank.ts @@ -34,7 +34,7 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { // Create a withdrawal operation const bankAccessApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); 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 817da5865..76dec50d3 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -42,7 +42,7 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { // Create a withdrawal operation const corebankApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const user = await corebankApiClient.createRandomBankUser(); corebankApiClient.setAuth(user); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts index 84b7b37bf..e3057451e 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fakebank.ts @@ -80,7 +80,7 @@ export async function runWithdrawalFakebankTest(t: GlobalTestState) { }); await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { - bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl, + corebankApiBaseUrl: bank.corebankApiBaseUrl, exchangeBaseUrl: exchange.baseUrl, amount: "TESTKUDOS:10", }); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts index d3df19664..f702376e1 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-fees.ts @@ -108,7 +108,7 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) { const amount = "TESTKUDOS:7.5"; const bankAccessApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); bankAccessApiClient.setAuth(user); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-huge.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-huge.ts index 0dfc77447..893d870e5 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-huge.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-huge.ts @@ -102,7 +102,7 @@ export async function runWithdrawalHugeTest(t: GlobalTestState) { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { exchangeBaseUrl: exchange.baseUrl, amount: "TESTKUDOS:10000", - bankAccessApiBaseUrl: bank.baseUrl, + corebankApiBaseUrl: bank.baseUrl, }); await withdrawalFinishedCond; diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts index 316e3cc18..fa483aa28 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts @@ -42,7 +42,7 @@ export async function runWithdrawalManualTest(t: GlobalTestState) { // Create a withdrawal operation const bankAccessApiClient = new TalerCorebankApiClient( - bank.bankAccessApiBaseUrl, + bank.corebankApiBaseUrl, ); const user = await bankAccessApiClient.createRandomBankUser(); diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 8fff8ae55..4811d674f 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1556,7 +1556,7 @@ export const codecForTestPayArgs = (): Codec => export interface IntegrationTestArgs { exchangeBaseUrl: string; - bankAccessApiBaseUrl: string; + corebankApiBaseUrl: string; merchantBaseUrl: string; merchantAuthToken?: string; amountToWithdraw: string; @@ -1570,12 +1570,12 @@ export const codecForIntegrationTestArgs = (): Codec => .property("merchantAuthToken", codecOptional(codecForString())) .property("amountToSpend", codecForAmountString()) .property("amountToWithdraw", codecForAmountString()) - .property("bankAccessApiBaseUrl", codecForAmountString()) + .property("corebankApiBaseUrl", codecForAmountString()) .build("IntegrationTestArgs"); export interface IntegrationTestV2Args { exchangeBaseUrl: string; - bankAccessApiBaseUrl: string; + corebankApiBaseUrl: string; merchantBaseUrl: string; merchantAuthToken?: string; } @@ -1585,7 +1585,7 @@ export const codecForIntegrationTestV2Args = (): Codec => .property("exchangeBaseUrl", codecForString()) .property("merchantBaseUrl", codecForString()) .property("merchantAuthToken", codecOptional(codecForString())) - .property("bankAccessApiBaseUrl", codecForAmountString()) + .property("corebankApiBaseUrl", codecForAmountString()) .build("IntegrationTestV2Args"); export interface AddExchangeRequest { @@ -1861,9 +1861,9 @@ export interface CoreApiResponseError { export interface WithdrawTestBalanceRequest { amount: string; /** - * Bank access API base URL. + * Corebank API base URL. */ - bankAccessApiBaseUrl: string; + corebankApiBaseUrl: string; exchangeBaseUrl: string; forcedDenomSel?: ForcedDenomSel; } @@ -1936,7 +1936,7 @@ export const codecForWithdrawTestBalance = .property("amount", codecForString()) .property("exchangeBaseUrl", codecForString()) .property("forcedDenomSel", codecForAny()) - .property("bankAccessApiBaseUrl", codecForString()) + .property("corebankApiBaseUrl", codecForString()) .build("WithdrawTestBalanceRequest"); export interface SetCoinSuspendedRequest { diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index bfc259481..f3b205211 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -1280,7 +1280,7 @@ advancedCli await wallet.client.call(WalletApiOperation.RunIntegrationTest, { amountToSpend: "TESTKUDOS:1", amountToWithdraw: "TESTKUDOS:3", - bankAccessApiBaseUrl: "http://localhost:8082/taler-bank-access/", + corebankApiBaseUrl: "http://localhost:8082/taler-bank-access/", exchangeBaseUrl: "http://localhost:8081/", merchantBaseUrl: "http://localhost:8083/", }); @@ -1507,7 +1507,7 @@ testCli.subcommand("withdrawKudos", "withdraw-kudos").action(async (args) => { await withWallet(args, async (wallet) => { await wallet.client.call(WalletApiOperation.WithdrawTestBalance, { amount: "KUDOS:50", - bankAccessApiBaseUrl: + corebankApiBaseUrl: "https://bank.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/", }); diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 0d702a00c..4fc890788 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -109,7 +109,7 @@ export async function checkReserve( export interface TopupReserveWithDemobankArgs { http: HttpRequestLibrary; reservePub: string; - bankAccessApiBaseUrl: string; + corebankApiBaseUrl: string; exchangeInfo: ExchangeInfo; amount: AmountString; } @@ -117,8 +117,8 @@ export interface TopupReserveWithDemobankArgs { export async function topupReserveWithDemobank( args: TopupReserveWithDemobankArgs, ) { - const { http, bankAccessApiBaseUrl, amount, exchangeInfo, reservePub } = args; - const bankClient = new TalerCorebankApiClient(bankAccessApiBaseUrl); + const { http, corebankApiBaseUrl, amount, exchangeInfo, reservePub } = args; + const bankClient = new TalerCorebankApiClient(corebankApiBaseUrl); const bankUser = await bankClient.createRandomBankUser(); const wopi = await bankClient.createWithdrawalOperation( bankUser.username, diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index b21f1992c..607d03470 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -102,13 +102,13 @@ export async function withdrawTestBalance( ): Promise { const amount = req.amount; const exchangeBaseUrl = req.exchangeBaseUrl; - const bankAccessApiBaseUrl = req.bankAccessApiBaseUrl; + const corebankApiBaseUrl = req.corebankApiBaseUrl; logger.trace( - `Registering bank user, bank access base url ${bankAccessApiBaseUrl}`, + `Registering bank user, bank access base url ${corebankApiBaseUrl}`, ); - const corebankClient = new TalerCorebankApiClient(bankAccessApiBaseUrl); + const corebankClient = new TalerCorebankApiClient(corebankApiBaseUrl); const bankUser = await corebankClient.createRandomBankUser(); logger.trace(`Registered bank user ${JSON.stringify(bankUser)}`); @@ -287,7 +287,7 @@ export async function runIntegrationTest( logger.info("withdrawing test balance"); await withdrawTestBalance(ws, { amount: args.amountToWithdraw, - bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + corebankApiBaseUrl: args.corebankApiBaseUrl, exchangeBaseUrl: args.exchangeBaseUrl, }); await waitUntilDone(ws); @@ -315,7 +315,7 @@ export async function runIntegrationTest( await withdrawTestBalance(ws, { amount: Amounts.stringify(withdrawAmountTwo), - bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + corebankApiBaseUrl: args.corebankApiBaseUrl, exchangeBaseUrl: args.exchangeBaseUrl, }); @@ -557,7 +557,7 @@ export async function runIntegrationTest2( logger.info("withdrawing test balance"); await withdrawTestBalance(ws, { amount: Amounts.stringify(amountToWithdraw), - bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + corebankApiBaseUrl: args.corebankApiBaseUrl, exchangeBaseUrl: args.exchangeBaseUrl, }); await waitUntilDone(ws); @@ -590,7 +590,7 @@ export async function runIntegrationTest2( await withdrawTestBalance(ws, { amount: Amounts.stringify(withdrawAmountTwo), - bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + corebankApiBaseUrl: args.corebankApiBaseUrl, exchangeBaseUrl: args.exchangeBaseUrl, }); diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 203adec0f..ead0ee407 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -1073,7 +1073,7 @@ async function dispatchRequestInternal( case WalletApiOperation.WithdrawTestkudos: { await withdrawTestBalance(ws, { amount: "TESTKUDOS:10", - bankAccessApiBaseUrl: "https://bank.test.taler.net/", + corebankApiBaseUrl: "https://bank.test.taler.net/", exchangeBaseUrl: "https://exchange.test.taler.net/", }); return { diff --git a/packages/taler-wallet-embedded/src/wallet-qjs.ts b/packages/taler-wallet-embedded/src/wallet-qjs.ts index e0888aa8a..1b3e3ae81 100644 --- a/packages/taler-wallet-embedded/src/wallet-qjs.ts +++ b/packages/taler-wallet-embedded/src/wallet-qjs.ts @@ -278,7 +278,7 @@ export async function testWithGv() { await w.wallet.client.call(WalletApiOperation.RunIntegrationTest, { amountToSpend: "KUDOS:1", amountToWithdraw: "KUDOS:3", - bankAccessApiBaseUrl: + corebankApiBaseUrl: "https://bank.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/", merchantBaseUrl: "https://backend.demo.taler.net/", @@ -306,7 +306,7 @@ export async function testWithLocal(path: string) { await w.wallet.client.call(WalletApiOperation.RunIntegrationTest, { amountToSpend: "TESTKUDOS:1", amountToWithdraw: "TESTKUDOS:3", - bankAccessApiBaseUrl: "http://localhost:8082/taler-bank-access/", + corebankApiBaseUrl: "http://localhost:8082/taler-bank-access/", exchangeBaseUrl: "http://localhost:8081/", merchantBaseUrl: "http://localhost:8083/", }); -- cgit v1.2.3