summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-01-15 17:34:19 -0300
committerSebastian <sebasjm@gmail.com>2024-01-15 17:36:48 -0300
commit2e2cf4049a771c82fcc520686de3ace7603baa05 (patch)
tree620ab22d4fc0f621d0a574c8f98d1c49f1d67804 /packages/taler-wallet-core/src/operations
parentef0bb60f23c0c755814f648b8d71a29a843e066c (diff)
downloadwallet-core-2e2cf4049a771c82fcc520686de3ace7603baa05.tar.gz
wallet-core-2e2cf4049a771c82fcc520686de3ace7603baa05.tar.bz2
wallet-core-2e2cf4049a771c82fcc520686de3ace7603baa05.zip
fixes #8083
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts62
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts75
2 files changed, 103 insertions, 34 deletions
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index 908aa540a..d93396ca5 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -41,7 +41,9 @@ import {
TransactionsResponse,
TransactionState,
TransactionType,
+ TransactionWithdrawal,
WalletContractData,
+ WithdrawalTransactionByURIRequest,
WithdrawalType,
} from "@gnu-taler/taler-util";
import {
@@ -520,7 +522,7 @@ function buildTransactionForPeerPullCredit(
const silentWithdrawalErrorForInvoice =
wsrOrt?.lastError &&
wsrOrt.lastError.code ===
- TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE &&
+ TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE &&
Object.values(wsrOrt.lastError.errorsPerCoin ?? {}).every((e) => {
return (
e.code === TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR &&
@@ -550,10 +552,10 @@ function buildTransactionForPeerPullCredit(
kycUrl: pullCredit.kycUrl,
...(wsrOrt?.lastError
? {
- error: silentWithdrawalErrorForInvoice
- ? undefined
- : wsrOrt.lastError,
- }
+ error: silentWithdrawalErrorForInvoice
+ ? undefined
+ : wsrOrt.lastError,
+ }
: {}),
};
}
@@ -641,7 +643,7 @@ function buildTransactionForPeerPushCredit(
function buildTransactionForBankIntegratedWithdraw(
wgRecord: WithdrawalGroupRecord,
ort?: OperationRetryRecord,
-): Transaction {
+): TransactionWithdrawal {
if (wgRecord.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated)
throw Error("");
@@ -676,7 +678,7 @@ function buildTransactionForManualWithdraw(
withdrawalGroup: WithdrawalGroupRecord,
exchangeDetails: ExchangeWireDetails,
ort?: OperationRetryRecord,
-): Transaction {
+): TransactionWithdrawal {
if (withdrawalGroup.wgInfo.withdrawalType !== WithdrawalRecordType.BankManual)
throw Error("");
@@ -948,6 +950,52 @@ async function buildTransactionForPurchase(
};
}
+export async function getWithdrawalTransactionByUri(
+ ws: InternalWalletState,
+ request: WithdrawalTransactionByURIRequest,
+): Promise<TransactionWithdrawal | undefined> {
+ return await ws.db
+ .mktx((x) => [
+ x.withdrawalGroups,
+ x.exchangeDetails,
+ x.exchanges,
+ x.operationRetries,
+ ])
+ .runReadWrite(async (tx) => {
+ const withdrawalGroupRecord = await tx.withdrawalGroups.indexes.byTalerWithdrawUri.get(
+ request.talerWithdrawUri,
+ );
+
+ if (!withdrawalGroupRecord) {
+ return undefined;
+ }
+
+ const opId = TaskIdentifiers.forWithdrawal(withdrawalGroupRecord);
+ const ort = await tx.operationRetries.get(opId);
+
+ if (
+ withdrawalGroupRecord.wgInfo.withdrawalType ===
+ WithdrawalRecordType.BankIntegrated
+ ) {
+ return buildTransactionForBankIntegratedWithdraw(
+ withdrawalGroupRecord,
+ ort,
+ );
+ }
+ const exchangeDetails = await getExchangeWireDetailsInTx(
+ tx,
+ withdrawalGroupRecord.exchangeBaseUrl,
+ );
+ if (!exchangeDetails) throw Error("not exchange details");
+
+ return buildTransactionForManualWithdraw(
+ withdrawalGroupRecord,
+ exchangeDetails,
+ ort,
+ );
+ });
+}
+
/**
* Retrieve the full event history for this wallet.
*/
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 58df75964..6c7e8c37a 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -45,6 +45,7 @@ import {
LibtoolVersion,
Logger,
NotificationType,
+ TalerBankIntegrationHttpClient,
TalerError,
TalerErrorCode,
TalerErrorDetail,
@@ -556,19 +557,11 @@ export async function getBankWithdrawalInfo(
throw Error(`can't parse URL ${talerWithdrawUri}`);
}
- const configReqUrl = new URL("config", uriResult.bankIntegrationApiBaseUrl);
+ const bankApi = new TalerBankIntegrationHttpClient(uriResult.bankIntegrationApiBaseUrl, http);
- const configResp = await http.fetch(configReqUrl.href);
- const config = await readSuccessResponseJsonOrThrow(
- configResp,
- codecForIntegrationBankConfig(),
- );
+ const { body: config } = await bankApi.getConfig()
- const versionRes = LibtoolVersion.compare(
- WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
- config.version,
- );
- if (versionRes?.compatible != true) {
+ if (!bankApi.isCompatible(config.version)) {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE,
{
@@ -579,29 +572,24 @@ export async function getBankWithdrawalInfo(
);
}
- const reqUrl = new URL(
- `withdrawal-operation/${uriResult.withdrawalOperationId}`,
- uriResult.bankIntegrationApiBaseUrl,
- );
-
- logger.info(`bank withdrawal status URL: ${reqUrl.href}}`);
+ const resp = await bankApi.getWithdrawalOperationById(uriResult.withdrawalOperationId)
- const resp = await http.fetch(reqUrl.href);
- const status = await readSuccessResponseJsonOrThrow(
- resp,
- codecForWithdrawOperationStatusResponse(),
- );
+ if (resp.type === "fail") {
+ throw TalerError.fromUncheckedDetail(resp.detail);
+ }
+ const { body: status } = resp
logger.info(`bank withdrawal operation status: ${j2s(status)}`);
return {
+ operationId: uriResult.withdrawalOperationId,
+ apiBaseUrl: uriResult.bankIntegrationApiBaseUrl,
amount: Amounts.parseOrThrow(status.amount),
confirmTransferUrl: status.confirm_transfer_url,
- selectionDone: status.selection_done,
senderWire: status.sender_wire,
suggestedExchange: status.suggested_exchange,
- transferDone: status.transfer_done,
wireTypes: status.wire_types,
+ status: status.status,
};
}
@@ -1226,8 +1214,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;
@@ -1872,7 +1859,7 @@ export async function getExchangeWithdrawalInfo(
) {
logger.warn(
`wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
- `(exchange has ${exchange.protocolVersionRange}), checking for updates`,
+ `(exchange has ${exchange.protocolVersionRange}), checking for updates`,
);
}
}
@@ -1915,6 +1902,7 @@ export async function getExchangeWithdrawalInfo(
export interface GetWithdrawalDetailsForUriOpts {
restrictAge?: number;
+ notifyChangeFromPendingTimeoutMs?: number;
}
/**
@@ -1957,7 +1945,40 @@ export async function getWithdrawalDetailsForUri(
);
});
+ if (info.status === "pending" && opts.notifyChangeFromPendingTimeoutMs !== undefined) {
+ const bankApi = new TalerBankIntegrationHttpClient(info.apiBaseUrl, ws.http);
+ console.log(
+ `waiting operation (${info.operationId}) to change from pending`,
+ );
+ bankApi.getWithdrawalOperationById(info.operationId, {
+ old_state: "pending",
+ timeoutMs: opts.notifyChangeFromPendingTimeoutMs
+ }).then(resp => {
+ console.log(
+ `operation (${info.operationId}) to change to ${JSON.stringify(resp, undefined, 2)}`,
+ );
+ if (resp.type === "fail") {
+ //not found, this is rare since the previous request succeed
+ ws.notify({
+ type: NotificationType.WithdrawalOperationTransition,
+ operationId: info.operationId,
+ state: info.status,
+ })
+ return;
+ }
+
+ ws.notify({
+ type: NotificationType.WithdrawalOperationTransition,
+ operationId: info.operationId,
+ state: resp.body.status,
+ });
+ })
+ }
+
return {
+ operationId: info.operationId,
+ confirmTransferUrl: info.confirmTransferUrl,
+ status: info.status,
amount: Amounts.stringify(info.amount),
defaultExchangeBaseUrl: info.suggestedExchange,
possibleExchanges,