wallet-core: rename OperationAttempt->TaskRun, do not allow task result values anymore
This commit is contained in:
parent
7523ffa910
commit
d4ee961387
@ -1754,6 +1754,7 @@ export interface CoreApiRequestEnvelope {
|
|||||||
operation: string;
|
operation: string;
|
||||||
args: unknown;
|
args: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CoreApiResponse = CoreApiResponseSuccess | CoreApiResponseError;
|
export type CoreApiResponse = CoreApiResponseSuccess | CoreApiResponseError;
|
||||||
|
|
||||||
export type CoreApiMessageEnvelope = CoreApiResponse | CoreApiNotification;
|
export type CoreApiMessageEnvelope = CoreApiResponse | CoreApiNotification;
|
||||||
|
@ -94,8 +94,8 @@ import {
|
|||||||
} from "../../util/invariants.js";
|
} from "../../util/invariants.js";
|
||||||
import { addAttentionRequest, removeAttentionRequest } from "../attention.js";
|
import { addAttentionRequest, removeAttentionRequest } from "../attention.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
} from "../common.js";
|
} from "../common.js";
|
||||||
import { checkPaymentByProposalId, preparePayForUri } from "../pay-merchant.js";
|
import { checkPaymentByProposalId, preparePayForUri } from "../pay-merchant.js";
|
||||||
@ -250,7 +250,7 @@ function getNextBackupTimestamp(): TalerPreciseTimestamp {
|
|||||||
async function runBackupCycleForProvider(
|
async function runBackupCycleForProvider(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
args: BackupForProviderArgs,
|
args: BackupForProviderArgs,
|
||||||
): Promise<OperationAttemptResult<unknown, { talerUri?: string }>> {
|
): Promise<TaskRunResult> {
|
||||||
const provider = await ws.db
|
const provider = await ws.db
|
||||||
.mktx((x) => [x.backupProviders])
|
.mktx((x) => [x.backupProviders])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -259,10 +259,7 @@ async function runBackupCycleForProvider(
|
|||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
logger.warn("provider disappeared");
|
logger.warn("provider disappeared");
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const backupJson = await exportBackup(ws);
|
const backupJson = await exportBackup(ws);
|
||||||
@ -333,10 +330,7 @@ async function runBackupCycleForProvider(
|
|||||||
type: AttentionType.BackupUnpaid,
|
type: AttentionType.BackupUnpaid,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.status === HttpStatusCode.PaymentRequired) {
|
if (resp.status === HttpStatusCode.PaymentRequired) {
|
||||||
@ -378,10 +372,7 @@ async function runBackupCycleForProvider(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: TaskRunResultType.Pending,
|
||||||
result: {
|
|
||||||
talerUri,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const result = res;
|
const result = res;
|
||||||
@ -415,10 +406,7 @@ async function runBackupCycleForProvider(
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: TaskRunResultType.Pending,
|
||||||
result: {
|
|
||||||
talerUri,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +433,7 @@ async function runBackupCycleForProvider(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Finished,
|
type: TaskRunResultType.Finished,
|
||||||
result: undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +474,7 @@ async function runBackupCycleForProvider(
|
|||||||
const err = await readTalerErrorResponse(resp);
|
const err = await readTalerErrorResponse(resp);
|
||||||
logger.error(`got error response from backup provider: ${j2s(err)}`);
|
logger.error(`got error response from backup provider: ${j2s(err)}`);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: err,
|
errorDetail: err,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -495,7 +482,7 @@ async function runBackupCycleForProvider(
|
|||||||
export async function processBackupForProvider(
|
export async function processBackupForProvider(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
backupProviderBaseUrl: string,
|
backupProviderBaseUrl: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const provider = await ws.db
|
const provider = await ws.db
|
||||||
.mktx((x) => [x.backupProviders])
|
.mktx((x) => [x.backupProviders])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -720,23 +707,24 @@ async function runFirstBackupCycleForProvider(
|
|||||||
): Promise<AddBackupProviderResponse> {
|
): Promise<AddBackupProviderResponse> {
|
||||||
const resp = await runBackupCycleForProvider(ws, args);
|
const resp = await runBackupCycleForProvider(ws, args);
|
||||||
switch (resp.type) {
|
switch (resp.type) {
|
||||||
case OperationAttemptResultType.Error:
|
case TaskRunResultType.Error:
|
||||||
throw TalerError.fromDetail(
|
throw TalerError.fromDetail(
|
||||||
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
||||||
resp.errorDetail as any, //FIXME create an error for backup problems
|
resp.errorDetail as any, //FIXME create an error for backup problems
|
||||||
);
|
);
|
||||||
case OperationAttemptResultType.Finished:
|
case TaskRunResultType.Finished:
|
||||||
return {
|
return {
|
||||||
status: "ok",
|
status: "ok",
|
||||||
};
|
};
|
||||||
case OperationAttemptResultType.Longpoll:
|
case TaskRunResultType.Longpoll:
|
||||||
throw Error(
|
throw Error(
|
||||||
"unexpected runFirstBackupCycleForProvider result (longpoll)",
|
"unexpected runFirstBackupCycleForProvider result (longpoll)",
|
||||||
);
|
);
|
||||||
case OperationAttemptResultType.Pending:
|
case TaskRunResultType.Pending:
|
||||||
return {
|
return {
|
||||||
status: "payment-required",
|
status: "payment-required",
|
||||||
talerUri: resp.result.talerUri,
|
talerUri: "FIXME",
|
||||||
|
//talerUri: resp.result.talerUri,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
assertUnreachable(resp);
|
assertUnreachable(resp);
|
||||||
|
@ -433,25 +433,25 @@ async function storePendingTaskFinished(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runTaskWithErrorReporting<T1, T2>(
|
export async function runTaskWithErrorReporting(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
opId: TaskId,
|
opId: TaskId,
|
||||||
f: () => Promise<OperationAttemptResult<T1, T2>>,
|
f: () => Promise<TaskRunResult>,
|
||||||
): Promise<OperationAttemptResult<T1, T2>> {
|
): Promise<TaskRunResult> {
|
||||||
let maybeError: TalerErrorDetail | undefined;
|
let maybeError: TalerErrorDetail | undefined;
|
||||||
try {
|
try {
|
||||||
const resp = await f();
|
const resp = await f();
|
||||||
switch (resp.type) {
|
switch (resp.type) {
|
||||||
case OperationAttemptResultType.Error:
|
case TaskRunResultType.Error:
|
||||||
await storePendingTaskError(ws, opId, resp.errorDetail);
|
await storePendingTaskError(ws, opId, resp.errorDetail);
|
||||||
return resp;
|
return resp;
|
||||||
case OperationAttemptResultType.Finished:
|
case TaskRunResultType.Finished:
|
||||||
await storePendingTaskFinished(ws, opId);
|
await storePendingTaskFinished(ws, opId);
|
||||||
return resp;
|
return resp;
|
||||||
case OperationAttemptResultType.Pending:
|
case TaskRunResultType.Pending:
|
||||||
await storePendingTaskPending(ws, opId);
|
await storePendingTaskPending(ws, opId);
|
||||||
return resp;
|
return resp;
|
||||||
case OperationAttemptResultType.Longpoll:
|
case TaskRunResultType.Longpoll:
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -459,7 +459,7 @@ export async function runTaskWithErrorReporting<T1, T2>(
|
|||||||
if (ws.stopped) {
|
if (ws.stopped) {
|
||||||
logger.warn("crypto API stopped during shutdown, ignoring error");
|
logger.warn("crypto API stopped during shutdown, ignoring error");
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
||||||
{},
|
{},
|
||||||
@ -474,7 +474,7 @@ export async function runTaskWithErrorReporting<T1, T2>(
|
|||||||
maybeError = e.errorDetail;
|
maybeError = e.errorDetail;
|
||||||
await storePendingTaskError(ws, opId, maybeError!);
|
await storePendingTaskError(ws, opId, maybeError!);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: e.errorDetail,
|
errorDetail: e.errorDetail,
|
||||||
};
|
};
|
||||||
} else if (e instanceof Error) {
|
} else if (e instanceof Error) {
|
||||||
@ -492,7 +492,7 @@ export async function runTaskWithErrorReporting<T1, T2>(
|
|||||||
);
|
);
|
||||||
await storePendingTaskError(ws, opId, maybeError);
|
await storePendingTaskError(ws, opId, maybeError);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: maybeError,
|
errorDetail: maybeError,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -504,7 +504,7 @@ export async function runTaskWithErrorReporting<T1, T2>(
|
|||||||
);
|
);
|
||||||
await storePendingTaskError(ws, opId, maybeError);
|
await storePendingTaskError(ws, opId, maybeError);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: maybeError,
|
errorDetail: maybeError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -654,59 +654,55 @@ export interface TransactionManager {
|
|||||||
abort(): Promise<void>;
|
abort(): Promise<void>;
|
||||||
suspend(): Promise<void>;
|
suspend(): Promise<void>;
|
||||||
resume(): Promise<void>;
|
resume(): Promise<void>;
|
||||||
process(): Promise<OperationAttemptResult>;
|
process(): Promise<TaskRunResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OperationAttemptResultType {
|
export enum TaskRunResultType {
|
||||||
Finished = "finished",
|
Finished = "finished",
|
||||||
Pending = "pending",
|
Pending = "pending",
|
||||||
Error = "error",
|
Error = "error",
|
||||||
Longpoll = "longpoll",
|
Longpoll = "longpoll",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OperationAttemptResult<TSuccess = unknown, TPending = unknown> =
|
export type TaskRunResult =
|
||||||
| OperationAttemptFinishedResult<TSuccess>
|
| TaskRunFinishedResult
|
||||||
| OperationAttemptErrorResult
|
| TaskRunErrorResult
|
||||||
| OperationAttemptLongpollResult
|
| TaskRunLongpollResult
|
||||||
| OperationAttemptPendingResult<TPending>;
|
| TaskRunPendingResult;
|
||||||
|
|
||||||
export namespace OperationAttemptResult {
|
export namespace TaskRunResult {
|
||||||
export function finishedEmpty(): OperationAttemptResult<unknown, unknown> {
|
export function finished(): TaskRunResult {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Finished,
|
type: TaskRunResultType.Finished,
|
||||||
result: undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export function pendingEmpty(): OperationAttemptResult<unknown, unknown> {
|
export function pending(): TaskRunResult {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: TaskRunResultType.Pending,
|
||||||
result: undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export function longpoll(): OperationAttemptResult<unknown, unknown> {
|
export function longpoll(): TaskRunResult {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OperationAttemptFinishedResult<T> {
|
export interface TaskRunFinishedResult {
|
||||||
type: OperationAttemptResultType.Finished;
|
type: TaskRunResultType.Finished;
|
||||||
result: T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OperationAttemptPendingResult<T> {
|
export interface TaskRunPendingResult {
|
||||||
type: OperationAttemptResultType.Pending;
|
type: TaskRunResultType.Pending;
|
||||||
result: T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OperationAttemptErrorResult {
|
export interface TaskRunErrorResult {
|
||||||
type: OperationAttemptResultType.Error;
|
type: TaskRunResultType.Error;
|
||||||
errorDetail: TalerErrorDetail;
|
errorDetail: TalerErrorDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OperationAttemptLongpollResult {
|
export interface TaskRunLongpollResult {
|
||||||
type: OperationAttemptResultType.Longpoll;
|
type: TaskRunResultType.Longpoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RetryInfo {
|
export interface RetryInfo {
|
||||||
@ -942,19 +938,3 @@ export namespace TaskIdentifiers {
|
|||||||
return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushPaymentIncomingId}` as TaskId;
|
return `${PendingTaskType.PeerPushCredit}:${ppi.peerPushPaymentIncomingId}` as TaskId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run an operation handler, expect a success result and extract the success value.
|
|
||||||
*/
|
|
||||||
export async function unwrapOperationHandlerResultOrThrow<T>(
|
|
||||||
res: OperationAttemptResult<T>,
|
|
||||||
): Promise<T> {
|
|
||||||
switch (res.type) {
|
|
||||||
case OperationAttemptResultType.Finished:
|
|
||||||
return res.result;
|
|
||||||
case OperationAttemptResultType.Error:
|
|
||||||
throw TalerError.fromUncheckedDetail(res.errorDetail);
|
|
||||||
default:
|
|
||||||
throw Error(`unexpected operation result (${res.type})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -81,7 +81,7 @@ import { InternalWalletState } from "../internal-wallet-state.js";
|
|||||||
import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http";
|
import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http";
|
||||||
import {
|
import {
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
runLongpollAsync,
|
runLongpollAsync,
|
||||||
spendCoins,
|
spendCoins,
|
||||||
TombstoneTag,
|
TombstoneTag,
|
||||||
@ -462,7 +462,7 @@ async function checkDepositKycStatus(
|
|||||||
async function waitForRefreshOnDepositGroup(
|
async function waitForRefreshOnDepositGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const abortRefreshGroupId = depositGroup.abortRefreshGroupId;
|
const abortRefreshGroupId = depositGroup.abortRefreshGroupId;
|
||||||
checkLogicInvariant(!!abortRefreshGroupId);
|
checkLogicInvariant(!!abortRefreshGroupId);
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
@ -503,13 +503,13 @@ async function waitForRefreshOnDepositGroup(
|
|||||||
});
|
});
|
||||||
|
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refundDepositGroup(
|
async function refundDepositGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const newTxPerCoin = [...depositGroup.transactionPerCoin];
|
const newTxPerCoin = [...depositGroup.transactionPerCoin];
|
||||||
logger.info(`status per coin: ${j2s(depositGroup.transactionPerCoin)}`);
|
logger.info(`status per coin: ${j2s(depositGroup.transactionPerCoin)}`);
|
||||||
for (let i = 0; i < depositGroup.transactionPerCoin.length; i++) {
|
for (let i = 0; i < depositGroup.transactionPerCoin.length; i++) {
|
||||||
@ -614,13 +614,13 @@ async function refundDepositGroup(
|
|||||||
await tx.depositGroups.put(newDg);
|
await tx.depositGroups.put(newDg);
|
||||||
});
|
});
|
||||||
|
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDepositGroupAborting(
|
async function processDepositGroupAborting(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info("processing deposit tx in 'aborting'");
|
logger.info("processing deposit tx in 'aborting'");
|
||||||
const abortRefreshGroupId = depositGroup.abortRefreshGroupId;
|
const abortRefreshGroupId = depositGroup.abortRefreshGroupId;
|
||||||
if (!abortRefreshGroupId) {
|
if (!abortRefreshGroupId) {
|
||||||
@ -634,7 +634,7 @@ async function processDepositGroupAborting(
|
|||||||
async function processDepositGroupPendingKyc(
|
async function processDepositGroupPendingKyc(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { depositGroupId } = depositGroup;
|
const { depositGroupId } = depositGroup;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.Deposit,
|
tag: TransactionType.Deposit,
|
||||||
@ -696,7 +696,7 @@ async function processDepositGroupPendingKyc(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.longpoll();
|
return TaskRunResult.longpoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -709,7 +709,7 @@ async function transitionToKycRequired(
|
|||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
kycInfo: KycPendingInfo,
|
kycInfo: KycPendingInfo,
|
||||||
exchangeUrl: string,
|
exchangeUrl: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { depositGroupId } = depositGroup;
|
const { depositGroupId } = depositGroup;
|
||||||
const userType = "individual";
|
const userType = "individual";
|
||||||
|
|
||||||
@ -728,7 +728,7 @@ async function transitionToKycRequired(
|
|||||||
});
|
});
|
||||||
if (kycStatusReq.status === HttpStatusCode.Ok) {
|
if (kycStatusReq.status === HttpStatusCode.Ok) {
|
||||||
logger.warn("kyc requested, but already fulfilled");
|
logger.warn("kyc requested, but already fulfilled");
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else if (kycStatusReq.status === HttpStatusCode.Accepted) {
|
} else if (kycStatusReq.status === HttpStatusCode.Accepted) {
|
||||||
const kycStatus = await kycStatusReq.json();
|
const kycStatus = await kycStatusReq.json();
|
||||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||||
@ -754,7 +754,7 @@ async function transitionToKycRequired(
|
|||||||
return { oldTxState, newTxState };
|
return { oldTxState, newTxState };
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else {
|
} else {
|
||||||
throw Error(`unexpected response from kyc-check (${kycStatusReq.status})`);
|
throw Error(`unexpected response from kyc-check (${kycStatusReq.status})`);
|
||||||
}
|
}
|
||||||
@ -764,7 +764,7 @@ async function processDepositGroupPendingTrack(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
cancellationToken?: CancellationToken,
|
cancellationToken?: CancellationToken,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { depositGroupId } = depositGroup;
|
const { depositGroupId } = depositGroup;
|
||||||
for (let i = 0; i < depositGroup.depositedPerCoin.length; i++) {
|
for (let i = 0; i < depositGroup.depositedPerCoin.length; i++) {
|
||||||
const coinPub = depositGroup.payCoinSelection.coinPubs[i];
|
const coinPub = depositGroup.payCoinSelection.coinPubs[i];
|
||||||
@ -905,10 +905,10 @@ async function processDepositGroupPendingTrack(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
if (allWired) {
|
if (allWired) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Use long-polling.
|
// FIXME: Use long-polling.
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +916,7 @@ async function processDepositGroupPendingDeposit(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroup: DepositGroupRecord,
|
depositGroup: DepositGroupRecord,
|
||||||
cancellationToken?: CancellationToken,
|
cancellationToken?: CancellationToken,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info("processing deposit group in pending(deposit)");
|
logger.info("processing deposit group in pending(deposit)");
|
||||||
const depositGroupId = depositGroup.depositGroupId;
|
const depositGroupId = depositGroup.depositGroupId;
|
||||||
const contractData = extractContractData(
|
const contractData = extractContractData(
|
||||||
@ -1000,7 +1000,7 @@ async function processDepositGroupPendingDeposit(
|
|||||||
});
|
});
|
||||||
|
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1012,7 +1012,7 @@ export async function processDepositGroup(
|
|||||||
options: {
|
options: {
|
||||||
cancellationToken?: CancellationToken;
|
cancellationToken?: CancellationToken;
|
||||||
} = {},
|
} = {},
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const depositGroup = await ws.db
|
const depositGroup = await ws.db
|
||||||
.mktx((x) => [x.depositGroups])
|
.mktx((x) => [x.depositGroups])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -1020,7 +1020,7 @@ export async function processDepositGroup(
|
|||||||
});
|
});
|
||||||
if (!depositGroup) {
|
if (!depositGroup) {
|
||||||
logger.warn(`deposit group ${depositGroupId} not found`);
|
logger.warn(`deposit group ${depositGroupId} not found`);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (depositGroup.operationStatus) {
|
switch (depositGroup.operationStatus) {
|
||||||
@ -1042,7 +1042,7 @@ export async function processDepositGroup(
|
|||||||
return processDepositGroupAborting(ws, depositGroup);
|
return processDepositGroupAborting(ws, depositGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getExchangeWireFee(
|
async function getExchangeWireFee(
|
||||||
|
@ -76,11 +76,10 @@ import {
|
|||||||
} from "../util/query.js";
|
} from "../util/query.js";
|
||||||
import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "../versions.js";
|
import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "../versions.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResultType,
|
||||||
OperationAttemptResultType,
|
|
||||||
runTaskWithErrorReporting,
|
runTaskWithErrorReporting,
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
unwrapOperationHandlerResultOrThrow,
|
TaskRunResult,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
|
|
||||||
const logger = new Logger("exchanges.ts");
|
const logger = new Logger("exchanges.ts");
|
||||||
@ -559,13 +558,34 @@ export async function updateExchangeFromUrl(
|
|||||||
exchangeDetails: ExchangeDetailsRecord;
|
exchangeDetails: ExchangeDetailsRecord;
|
||||||
}> {
|
}> {
|
||||||
const canonUrl = canonicalizeBaseUrl(baseUrl);
|
const canonUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
return unwrapOperationHandlerResultOrThrow(
|
const res = await runTaskWithErrorReporting(
|
||||||
await runTaskWithErrorReporting(
|
ws,
|
||||||
ws,
|
TaskIdentifiers.forExchangeUpdateFromUrl(canonUrl),
|
||||||
TaskIdentifiers.forExchangeUpdateFromUrl(canonUrl),
|
() => updateExchangeFromUrlHandler(ws, canonUrl, options),
|
||||||
() => updateExchangeFromUrlHandler(ws, canonUrl, options),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
switch (res.type) {
|
||||||
|
case TaskRunResultType.Finished: {
|
||||||
|
const now = AbsoluteTime.now();
|
||||||
|
const { exchange, exchangeDetails } = await ws.db
|
||||||
|
.mktx((x) => [x.exchanges, x.exchangeDetails])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
let exchange = await tx.exchanges.get(canonUrl);
|
||||||
|
const exchangeDetails = await getExchangeDetails(tx, baseUrl);
|
||||||
|
return { exchange, exchangeDetails };
|
||||||
|
});
|
||||||
|
if (!exchange) {
|
||||||
|
throw Error("exchange not found");
|
||||||
|
}
|
||||||
|
if (!exchangeDetails) {
|
||||||
|
throw Error("exchange details not found");
|
||||||
|
}
|
||||||
|
return { exchange, exchangeDetails };
|
||||||
|
}
|
||||||
|
case TaskRunResultType.Error:
|
||||||
|
throw TalerError.fromUncheckedDetail(res.errorDetail);
|
||||||
|
default:
|
||||||
|
throw Error(`unexpected operation result (${res.type})`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -581,12 +601,7 @@ export async function updateExchangeFromUrlHandler(
|
|||||||
forceNow?: boolean;
|
forceNow?: boolean;
|
||||||
cancellationToken?: CancellationToken;
|
cancellationToken?: CancellationToken;
|
||||||
} = {},
|
} = {},
|
||||||
): Promise<
|
): Promise<TaskRunResult> {
|
||||||
OperationAttemptResult<{
|
|
||||||
exchange: ExchangeRecord;
|
|
||||||
exchangeDetails: ExchangeDetailsRecord;
|
|
||||||
}>
|
|
||||||
> {
|
|
||||||
const forceNow = options.forceNow ?? false;
|
const forceNow = options.forceNow ?? false;
|
||||||
logger.trace(
|
logger.trace(
|
||||||
`updating exchange info for ${exchangeBaseUrl}, forced: ${forceNow}`,
|
`updating exchange info for ${exchangeBaseUrl}, forced: ${forceNow}`,
|
||||||
@ -620,10 +635,7 @@ export async function updateExchangeFromUrlHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: { exchange, exchangeDetails },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("updating exchange /keys info");
|
logger.info("updating exchange /keys info");
|
||||||
@ -679,7 +691,7 @@ export async function updateExchangeFromUrlHandler(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail,
|
errorDetail,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -911,13 +923,7 @@ export async function updateExchangeFromUrlHandler(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: {
|
|
||||||
exchange: updated.exchange,
|
|
||||||
exchangeDetails: updated.exchangeDetails,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,8 +112,8 @@ import { checkDbInvariant } from "../util/invariants.js";
|
|||||||
import { GetReadOnlyAccess } from "../util/query.js";
|
import { GetReadOnlyAccess } from "../util/query.js";
|
||||||
import {
|
import {
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
RetryInfo,
|
RetryInfo,
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
@ -325,7 +325,7 @@ export function extractContractData(
|
|||||||
async function processDownloadProposal(
|
async function processDownloadProposal(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const proposal = await ws.db
|
const proposal = await ws.db
|
||||||
.mktx((x) => [x.purchases])
|
.mktx((x) => [x.purchases])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -333,17 +333,11 @@ async function processDownloadProposal(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!proposal) {
|
if (!proposal) {
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proposal.purchaseStatus != PurchaseStatus.PendingDownloadingProposal) {
|
if (proposal.purchaseStatus != PurchaseStatus.PendingDownloadingProposal) {
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
@ -560,10 +554,7 @@ async function processDownloadProposal(
|
|||||||
|
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1065,7 +1056,7 @@ export async function checkPaymentByProposalId(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
// FIXME: What about error handling?! This doesn't properly store errors in the DB.
|
// FIXME: What about error handling?! This doesn't properly store errors in the DB.
|
||||||
const r = await processPurchasePay(ws, proposalId, { forceNow: true });
|
const r = await processPurchasePay(ws, proposalId, { forceNow: true });
|
||||||
if (r.type !== OperationAttemptResultType.Finished) {
|
if (r.type !== TaskRunResultType.Finished) {
|
||||||
// FIXME: This does not surface the original error
|
// FIXME: This does not surface the original error
|
||||||
throw Error("submitting pay failed");
|
throw Error("submitting pay failed");
|
||||||
}
|
}
|
||||||
@ -1253,7 +1244,7 @@ export async function runPayForConfirmPay(
|
|||||||
});
|
});
|
||||||
logger.trace(`processPurchasePay response type ${res.type}`);
|
logger.trace(`processPurchasePay response type ${res.type}`);
|
||||||
switch (res.type) {
|
switch (res.type) {
|
||||||
case OperationAttemptResultType.Finished: {
|
case TaskRunResultType.Finished: {
|
||||||
const purchase = await ws.db
|
const purchase = await ws.db
|
||||||
.mktx((x) => [x.purchases])
|
.mktx((x) => [x.purchases])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -1272,7 +1263,7 @@ export async function runPayForConfirmPay(
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case OperationAttemptResultType.Error: {
|
case TaskRunResultType.Error: {
|
||||||
// We hide transient errors from the caller.
|
// We hide transient errors from the caller.
|
||||||
const opRetry = await ws.db
|
const opRetry = await ws.db
|
||||||
.mktx((x) => [x.operationRetries])
|
.mktx((x) => [x.operationRetries])
|
||||||
@ -1286,7 +1277,7 @@ export async function runPayForConfirmPay(
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case OperationAttemptResultType.Pending:
|
case TaskRunResultType.Pending:
|
||||||
logger.trace("reporting pending as confirmPay response");
|
logger.trace("reporting pending as confirmPay response");
|
||||||
return {
|
return {
|
||||||
type: ConfirmPayResultType.Pending,
|
type: ConfirmPayResultType.Pending,
|
||||||
@ -1296,7 +1287,7 @@ export async function runPayForConfirmPay(
|
|||||||
}),
|
}),
|
||||||
lastError: undefined,
|
lastError: undefined,
|
||||||
};
|
};
|
||||||
case OperationAttemptResultType.Longpoll:
|
case TaskRunResultType.Longpoll:
|
||||||
throw Error("unexpected processPurchasePay result (longpoll)");
|
throw Error("unexpected processPurchasePay result (longpoll)");
|
||||||
default:
|
default:
|
||||||
assertUnreachable(res);
|
assertUnreachable(res);
|
||||||
@ -1456,7 +1447,7 @@ export async function confirmPay(
|
|||||||
export async function processPurchase(
|
export async function processPurchase(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const purchase = await ws.db
|
const purchase = await ws.db
|
||||||
.mktx((x) => [x.purchases])
|
.mktx((x) => [x.purchases])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -1464,7 +1455,7 @@ export async function processPurchase(
|
|||||||
});
|
});
|
||||||
if (!purchase) {
|
if (!purchase) {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: {
|
errorDetail: {
|
||||||
// FIXME: allocate more specific error code
|
// FIXME: allocate more specific error code
|
||||||
code: TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
code: TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
||||||
@ -1504,10 +1495,7 @@ export async function processPurchase(
|
|||||||
case PurchaseStatus.SuspendedQueryingAutoRefund:
|
case PurchaseStatus.SuspendedQueryingAutoRefund:
|
||||||
case PurchaseStatus.SuspendedQueryingRefund:
|
case PurchaseStatus.SuspendedQueryingRefund:
|
||||||
case PurchaseStatus.FailedAbort:
|
case PurchaseStatus.FailedAbort:
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
default:
|
default:
|
||||||
assertUnreachable(purchase.purchaseStatus);
|
assertUnreachable(purchase.purchaseStatus);
|
||||||
// throw Error(`unexpected purchase status (${purchase.purchaseStatus})`);
|
// throw Error(`unexpected purchase status (${purchase.purchaseStatus})`);
|
||||||
@ -1518,7 +1506,7 @@ export async function processPurchasePay(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
options: unknown = {},
|
options: unknown = {},
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const purchase = await ws.db
|
const purchase = await ws.db
|
||||||
.mktx((x) => [x.purchases])
|
.mktx((x) => [x.purchases])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -1526,7 +1514,7 @@ export async function processPurchasePay(
|
|||||||
});
|
});
|
||||||
if (!purchase) {
|
if (!purchase) {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: {
|
errorDetail: {
|
||||||
// FIXME: allocate more specific error code
|
// FIXME: allocate more specific error code
|
||||||
code: TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
code: TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
||||||
@ -1541,7 +1529,7 @@ export async function processPurchasePay(
|
|||||||
case PurchaseStatus.PendingPayingReplay:
|
case PurchaseStatus.PendingPayingReplay:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
logger.trace(`processing purchase pay ${proposalId}`);
|
logger.trace(`processing purchase pay ${proposalId}`);
|
||||||
|
|
||||||
@ -1589,7 +1577,7 @@ export async function processPurchasePay(
|
|||||||
if (resp.status >= 500 && resp.status <= 599) {
|
if (resp.status >= 500 && resp.status <= 599) {
|
||||||
const errDetails = await readUnexpectedResponseDetails(resp);
|
const errDetails = await readUnexpectedResponseDetails(resp);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_PAY_MERCHANT_SERVER_ERROR,
|
TalerErrorCode.WALLET_PAY_MERCHANT_SERVER_ERROR,
|
||||||
{
|
{
|
||||||
@ -1613,10 +1601,7 @@ export async function processPurchasePay(
|
|||||||
|
|
||||||
// FIXME: Should we really consider this to be pending?
|
// FIXME: Should we really consider this to be pending?
|
||||||
|
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Pending,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1677,7 +1662,7 @@ export async function processPurchasePay(
|
|||||||
await unblockBackup(ws, proposalId);
|
await unblockBackup(ws, proposalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function refuseProposal(
|
export async function refuseProposal(
|
||||||
@ -2114,7 +2099,7 @@ export function computePayMerchantTransactionActions(
|
|||||||
async function processPurchaseAutoRefund(
|
async function processPurchaseAutoRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const proposalId = purchase.proposalId;
|
const proposalId = purchase.proposalId;
|
||||||
logger.trace(`processing auto-refund for proposal ${proposalId}`);
|
logger.trace(`processing auto-refund for proposal ${proposalId}`);
|
||||||
|
|
||||||
@ -2130,7 +2115,7 @@ async function processPurchaseAutoRefund(
|
|||||||
|
|
||||||
// FIXME: Put this logic into runLongpollAsync?
|
// FIXME: Put this logic into runLongpollAsync?
|
||||||
if (ws.activeLongpoll[taskId]) {
|
if (ws.activeLongpoll[taskId]) {
|
||||||
return OperationAttemptResult.longpoll();
|
return TaskRunResult.longpoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
const download = await expectProposalDownload(ws, purchase);
|
const download = await expectProposalDownload(ws, purchase);
|
||||||
@ -2215,13 +2200,13 @@ async function processPurchaseAutoRefund(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return OperationAttemptResult.longpoll();
|
return TaskRunResult.longpoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPurchaseAbortingRefund(
|
async function processPurchaseAbortingRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const proposalId = purchase.proposalId;
|
const proposalId = purchase.proposalId;
|
||||||
const download = await expectProposalDownload(ws, purchase);
|
const download = await expectProposalDownload(ws, purchase);
|
||||||
logger.trace(`processing aborting-refund for proposal ${proposalId}`);
|
logger.trace(`processing aborting-refund for proposal ${proposalId}`);
|
||||||
@ -2296,7 +2281,7 @@ async function processPurchaseAbortingRefund(
|
|||||||
async function processPurchaseQueryRefund(
|
async function processPurchaseQueryRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const proposalId = purchase.proposalId;
|
const proposalId = purchase.proposalId;
|
||||||
logger.trace(`processing query-refund for proposal ${proposalId}`);
|
logger.trace(`processing query-refund for proposal ${proposalId}`);
|
||||||
|
|
||||||
@ -2341,7 +2326,7 @@ async function processPurchaseQueryRefund(
|
|||||||
return { oldTxState, newTxState };
|
return { oldTxState, newTxState };
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else {
|
} else {
|
||||||
const refundAwaiting = Amounts.sub(
|
const refundAwaiting = Amounts.sub(
|
||||||
Amounts.parseOrThrow(orderStatus.refund_amount),
|
Amounts.parseOrThrow(orderStatus.refund_amount),
|
||||||
@ -2367,14 +2352,14 @@ async function processPurchaseQueryRefund(
|
|||||||
return { oldTxState, newTxState };
|
return { oldTxState, newTxState };
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPurchaseAcceptRefund(
|
async function processPurchaseAcceptRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const proposalId = purchase.proposalId;
|
const proposalId = purchase.proposalId;
|
||||||
|
|
||||||
const download = await expectProposalDownload(ws, purchase);
|
const download = await expectProposalDownload(ws, purchase);
|
||||||
@ -2472,7 +2457,7 @@ async function storeRefunds(
|
|||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
refunds: MerchantCoinRefundStatus[],
|
refunds: MerchantCoinRefundStatus[],
|
||||||
reason: RefundReason,
|
reason: RefundReason,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info(`storing refunds: ${j2s(refunds)}`);
|
logger.info(`storing refunds: ${j2s(refunds)}`);
|
||||||
|
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
@ -2699,16 +2684,16 @@ async function storeRefunds(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyTransition(ws, transactionId, result.transitionInfo);
|
notifyTransition(ws, transactionId, result.transitionInfo);
|
||||||
|
|
||||||
if (result.numPendingItemsTotal > 0) {
|
if (result.numPendingItemsTotal > 0) {
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeRefundTransactionState(
|
export function computeRefundTransactionState(
|
||||||
|
@ -66,8 +66,8 @@ import { assertUnreachable } from "../util/assertUnreachable.js";
|
|||||||
import { checkDbInvariant } from "../util/invariants.js";
|
import { checkDbInvariant } from "../util/invariants.js";
|
||||||
import {
|
import {
|
||||||
LongpollResult,
|
LongpollResult,
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
runLongpollAsync,
|
runLongpollAsync,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
@ -184,7 +184,7 @@ async function longpollKycStatus(
|
|||||||
exchangeUrl: string,
|
exchangeUrl: string,
|
||||||
kycInfo: KycPendingInfo,
|
kycInfo: KycPendingInfo,
|
||||||
userType: KycUserType,
|
userType: KycUserType,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPullCredit,
|
tag: TransactionType.PeerPullCredit,
|
||||||
pursePub,
|
pursePub,
|
||||||
@ -242,14 +242,14 @@ async function longpollKycStatus(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPullCreditAbortingDeletePurse(
|
async function processPeerPullCreditAbortingDeletePurse(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullIni: PeerPullPaymentInitiationRecord,
|
peerPullIni: PeerPullPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { pursePub, pursePriv } = peerPullIni;
|
const { pursePub, pursePriv } = peerPullIni;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPushDebit,
|
tag: TransactionType.PeerPushDebit,
|
||||||
@ -296,13 +296,13 @@ async function processPeerPullCreditAbortingDeletePurse(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handlePeerPullCreditWithdrawing(
|
async function handlePeerPullCreditWithdrawing(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pullIni: PeerPullPaymentInitiationRecord,
|
pullIni: PeerPullPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
if (!pullIni.withdrawalGroupId) {
|
if (!pullIni.withdrawalGroupId) {
|
||||||
throw Error("invalid db state (withdrawing, but no withdrawal group ID");
|
throw Error("invalid db state (withdrawing, but no withdrawal group ID");
|
||||||
}
|
}
|
||||||
@ -346,17 +346,17 @@ async function handlePeerPullCreditWithdrawing(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
if (finished) {
|
if (finished) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Return indicator that we depend on the other operation!
|
// FIXME: Return indicator that we depend on the other operation!
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handlePeerPullCreditCreatePurse(
|
async function handlePeerPullCreditCreatePurse(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pullIni: PeerPullPaymentInitiationRecord,
|
pullIni: PeerPullPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const purseFee = Amounts.stringify(Amounts.zeroOfAmount(pullIni.amount));
|
const purseFee = Amounts.stringify(Amounts.zeroOfAmount(pullIni.amount));
|
||||||
const pursePub = pullIni.pursePub;
|
const pursePub = pullIni.pursePub;
|
||||||
const mergeReserve = await ws.db
|
const mergeReserve = await ws.db
|
||||||
@ -447,16 +447,13 @@ async function handlePeerPullCreditCreatePurse(
|
|||||||
await tx.peerPullPaymentInitiations.put(pi2);
|
await tx.peerPullPaymentInitiations.put(pi2);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processPeerPullCredit(
|
export async function processPeerPullCredit(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pursePub: string,
|
pursePub: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const pullIni = await ws.db
|
const pullIni = await ws.db
|
||||||
.mktx((x) => [x.peerPullPaymentInitiations])
|
.mktx((x) => [x.peerPullPaymentInitiations])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -475,7 +472,7 @@ export async function processPeerPullCredit(
|
|||||||
if (ws.activeLongpoll[retryTag]) {
|
if (ws.activeLongpoll[retryTag]) {
|
||||||
logger.info("peer-pull-credit already in long-polling, returning!");
|
logger.info("peer-pull-credit already in long-polling, returning!");
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,10 +480,7 @@ export async function processPeerPullCredit(
|
|||||||
|
|
||||||
switch (pullIni.status) {
|
switch (pullIni.status) {
|
||||||
case PeerPullPaymentInitiationStatus.Done: {
|
case PeerPullPaymentInitiationStatus.Done: {
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
case PeerPullPaymentInitiationStatus.PendingReady:
|
case PeerPullPaymentInitiationStatus.PendingReady:
|
||||||
runLongpollAsync(ws, retryTag, async (cancellationToken) =>
|
runLongpollAsync(ws, retryTag, async (cancellationToken) =>
|
||||||
@ -496,7 +490,7 @@ export async function processPeerPullCredit(
|
|||||||
"returning early from processPeerPullCredit for long-polling in background",
|
"returning early from processPeerPullCredit for long-polling in background",
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: {
|
case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: {
|
||||||
if (!pullIni.kycInfo) {
|
if (!pullIni.kycInfo) {
|
||||||
@ -528,14 +522,14 @@ export async function processPeerPullCredit(
|
|||||||
assertUnreachable(pullIni.status);
|
assertUnreachable(pullIni.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPullCreditKycRequired(
|
async function processPeerPullCreditKycRequired(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerIni: PeerPullPaymentInitiationRecord,
|
peerIni: PeerPullPaymentInitiationRecord,
|
||||||
kycPending: WalletKycUuid,
|
kycPending: WalletKycUuid,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPullCredit,
|
tag: TransactionType.PeerPullCredit,
|
||||||
pursePub: peerIni.pursePub,
|
pursePub: peerIni.pursePub,
|
||||||
@ -560,10 +554,7 @@ async function processPeerPullCreditKycRequired(
|
|||||||
kycStatusRes.status === HttpStatusCode.NoContent
|
kycStatusRes.status === HttpStatusCode.NoContent
|
||||||
) {
|
) {
|
||||||
logger.warn("kyc requested, but already fulfilled");
|
logger.warn("kyc requested, but already fulfilled");
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
} else if (kycStatusRes.status === HttpStatusCode.Accepted) {
|
} else if (kycStatusRes.status === HttpStatusCode.Accepted) {
|
||||||
const kycStatus = await kycStatusRes.json();
|
const kycStatus = await kycStatusRes.json();
|
||||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||||
@ -574,7 +565,7 @@ async function processPeerPullCreditKycRequired(
|
|||||||
if (!peerInc) {
|
if (!peerInc) {
|
||||||
return {
|
return {
|
||||||
transitionInfo: undefined,
|
transitionInfo: undefined,
|
||||||
result: OperationAttemptResult.finishedEmpty(),
|
result: TaskRunResult.finished(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const oldTxState = computePeerPullCreditTransactionState(peerInc);
|
const oldTxState = computePeerPullCreditTransactionState(peerInc);
|
||||||
@ -589,8 +580,8 @@ async function processPeerPullCreditKycRequired(
|
|||||||
await tx.peerPullPaymentInitiations.put(peerInc);
|
await tx.peerPullPaymentInitiations.put(peerInc);
|
||||||
// We'll remove this eventually! New clients should rely on the
|
// We'll remove this eventually! New clients should rely on the
|
||||||
// kycUrl field of the transaction, not the error code.
|
// kycUrl field of the transaction, not the error code.
|
||||||
const res: OperationAttemptResult = {
|
const res: TaskRunResult = {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
|
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
|
||||||
{
|
{
|
||||||
@ -604,10 +595,7 @@ async function processPeerPullCreditKycRequired(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Pending,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
throw Error(`unexpected response from kyc-check (${kycStatusRes.status})`);
|
throw Error(`unexpected response from kyc-check (${kycStatusRes.status})`);
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ import {
|
|||||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
import { checkLogicInvariant } from "../util/invariants.js";
|
import { checkLogicInvariant } from "../util/invariants.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
runTaskWithErrorReporting,
|
runTaskWithErrorReporting,
|
||||||
@ -89,12 +89,12 @@ async function handlePurseCreationConflict(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullInc: PeerPullPaymentIncomingRecord,
|
peerPullInc: PeerPullPaymentIncomingRecord,
|
||||||
resp: HttpResponse,
|
resp: HttpResponse,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const pursePub = peerPullInc.pursePub;
|
const pursePub = peerPullInc.pursePub;
|
||||||
const errResp = await readTalerErrorResponse(resp);
|
const errResp = await readTalerErrorResponse(resp);
|
||||||
if (errResp.code !== TalerErrorCode.EXCHANGE_GENERIC_INSUFFICIENT_FUNDS) {
|
if (errResp.code !== TalerErrorCode.EXCHANGE_GENERIC_INSUFFICIENT_FUNDS) {
|
||||||
await failPeerPullDebitTransaction(ws, pursePub);
|
await failPeerPullDebitTransaction(ws, pursePub);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Properly parse!
|
// FIXME: Properly parse!
|
||||||
@ -167,13 +167,13 @@ async function handlePurseCreationConflict(
|
|||||||
}
|
}
|
||||||
await tx.peerPullPaymentIncoming.put(myPpi);
|
await tx.peerPullPaymentIncoming.put(myPpi);
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPullDebitPendingDeposit(
|
async function processPeerPullDebitPendingDeposit(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullInc: PeerPullPaymentIncomingRecord,
|
peerPullInc: PeerPullPaymentIncomingRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId;
|
const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId;
|
||||||
const pursePub = peerPullInc.pursePub;
|
const pursePub = peerPullInc.pursePub;
|
||||||
|
|
||||||
@ -299,21 +299,18 @@ async function processPeerPullDebitPendingDeposit(
|
|||||||
default: {
|
default: {
|
||||||
const errResp = await readTalerErrorResponse(httpResp);
|
const errResp = await readTalerErrorResponse(httpResp);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: errResp,
|
errorDetail: errResp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPullDebitAbortingRefresh(
|
async function processPeerPullDebitAbortingRefresh(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullInc: PeerPullPaymentIncomingRecord,
|
peerPullInc: PeerPullPaymentIncomingRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId;
|
const peerPullPaymentIncomingId = peerPullInc.peerPullPaymentIncomingId;
|
||||||
const abortRefreshGroupId = peerPullInc.abortRefreshGroupId;
|
const abortRefreshGroupId = peerPullInc.abortRefreshGroupId;
|
||||||
checkLogicInvariant(!!abortRefreshGroupId);
|
checkLogicInvariant(!!abortRefreshGroupId);
|
||||||
@ -357,13 +354,13 @@ async function processPeerPullDebitAbortingRefresh(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
// FIXME: Shouldn't this be finished in some cases?!
|
// FIXME: Shouldn't this be finished in some cases?!
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processPeerPullDebit(
|
export async function processPeerPullDebit(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullPaymentIncomingId: string,
|
peerPullPaymentIncomingId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const peerPullInc = await ws.db
|
const peerPullInc = await ws.db
|
||||||
.mktx((x) => [x.peerPullPaymentIncoming])
|
.mktx((x) => [x.peerPullPaymentIncoming])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -379,10 +376,7 @@ export async function processPeerPullDebit(
|
|||||||
case PeerPullDebitRecordStatus.AbortingRefresh:
|
case PeerPullDebitRecordStatus.AbortingRefresh:
|
||||||
return await processPeerPullDebitAbortingRefresh(ws, peerPullInc);
|
return await processPeerPullDebitAbortingRefresh(ws, peerPullInc);
|
||||||
}
|
}
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function confirmPeerPullDebit(
|
export async function confirmPeerPullDebit(
|
||||||
|
@ -62,8 +62,8 @@ import {
|
|||||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
import { checkDbInvariant } from "../util/invariants.js";
|
import { checkDbInvariant } from "../util/invariants.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
runLongpollAsync,
|
runLongpollAsync,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
@ -233,7 +233,7 @@ async function longpollKycStatus(
|
|||||||
exchangeUrl: string,
|
exchangeUrl: string,
|
||||||
kycInfo: KycPendingInfo,
|
kycInfo: KycPendingInfo,
|
||||||
userType: KycUserType,
|
userType: KycUserType,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPushCredit,
|
tag: TransactionType.PeerPushCredit,
|
||||||
peerPushPaymentIncomingId,
|
peerPushPaymentIncomingId,
|
||||||
@ -293,7 +293,7 @@ async function longpollKycStatus(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ async function processPeerPushCreditKycRequired(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerInc: PeerPushPaymentIncomingRecord,
|
peerInc: PeerPushPaymentIncomingRecord,
|
||||||
kycPending: WalletKycUuid,
|
kycPending: WalletKycUuid,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPushCredit,
|
tag: TransactionType.PeerPushCredit,
|
||||||
peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId,
|
peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId,
|
||||||
@ -326,10 +326,7 @@ async function processPeerPushCreditKycRequired(
|
|||||||
kycStatusRes.status === HttpStatusCode.NoContent
|
kycStatusRes.status === HttpStatusCode.NoContent
|
||||||
) {
|
) {
|
||||||
logger.warn("kyc requested, but already fulfilled");
|
logger.warn("kyc requested, but already fulfilled");
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
} else if (kycStatusRes.status === HttpStatusCode.Accepted) {
|
} else if (kycStatusRes.status === HttpStatusCode.Accepted) {
|
||||||
const kycStatus = await kycStatusRes.json();
|
const kycStatus = await kycStatusRes.json();
|
||||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||||
@ -342,7 +339,7 @@ async function processPeerPushCreditKycRequired(
|
|||||||
if (!peerInc) {
|
if (!peerInc) {
|
||||||
return {
|
return {
|
||||||
transitionInfo: undefined,
|
transitionInfo: undefined,
|
||||||
result: OperationAttemptResult.finishedEmpty(),
|
result: TaskRunResult.finished(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const oldTxState = computePeerPushCreditTransactionState(peerInc);
|
const oldTxState = computePeerPushCreditTransactionState(peerInc);
|
||||||
@ -356,8 +353,8 @@ async function processPeerPushCreditKycRequired(
|
|||||||
await tx.peerPushPaymentIncoming.put(peerInc);
|
await tx.peerPushPaymentIncoming.put(peerInc);
|
||||||
// We'll remove this eventually! New clients should rely on the
|
// We'll remove this eventually! New clients should rely on the
|
||||||
// kycUrl field of the transaction, not the error code.
|
// kycUrl field of the transaction, not the error code.
|
||||||
const res: OperationAttemptResult = {
|
const res: TaskRunResult = {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
|
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED,
|
||||||
{
|
{
|
||||||
@ -381,7 +378,7 @@ async function handlePendingMerge(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerInc: PeerPushPaymentIncomingRecord,
|
peerInc: PeerPushPaymentIncomingRecord,
|
||||||
contractTerms: PeerContractTerms,
|
contractTerms: PeerContractTerms,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { peerPushPaymentIncomingId } = peerInc;
|
const { peerPushPaymentIncomingId } = peerInc;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPushCredit,
|
tag: TransactionType.PeerPushCredit,
|
||||||
@ -506,16 +503,13 @@ async function handlePendingMerge(
|
|||||||
);
|
);
|
||||||
notifyTransition(ws, transactionId, txRes?.peerPushCreditTransition);
|
notifyTransition(ws, transactionId, txRes?.peerPushCreditTransition);
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handlePendingWithdrawing(
|
async function handlePendingWithdrawing(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerInc: PeerPushPaymentIncomingRecord,
|
peerInc: PeerPushPaymentIncomingRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
if (!peerInc.withdrawalGroupId) {
|
if (!peerInc.withdrawalGroupId) {
|
||||||
throw Error("invalid db state (withdrawing, but no withdrawal group ID");
|
throw Error("invalid db state (withdrawing, but no withdrawal group ID");
|
||||||
}
|
}
|
||||||
@ -561,17 +555,17 @@ async function handlePendingWithdrawing(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
if (finished) {
|
if (finished) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Return indicator that we depend on the other operation!
|
// FIXME: Return indicator that we depend on the other operation!
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processPeerPushCredit(
|
export async function processPeerPushCredit(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushPaymentIncomingId: string,
|
peerPushPaymentIncomingId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
let peerInc: PeerPushPaymentIncomingRecord | undefined;
|
let peerInc: PeerPushPaymentIncomingRecord | undefined;
|
||||||
let contractTerms: PeerContractTerms | undefined;
|
let contractTerms: PeerContractTerms | undefined;
|
||||||
await ws.db
|
await ws.db
|
||||||
@ -617,7 +611,7 @@ export async function processPeerPushCredit(
|
|||||||
return handlePendingWithdrawing(ws, peerInc);
|
return handlePendingWithdrawing(ws, peerInc);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ import { PendingTaskType } from "../pending-types.js";
|
|||||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
import { checkLogicInvariant } from "../util/invariants.js";
|
import { checkLogicInvariant } from "../util/invariants.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
runLongpollAsync,
|
runLongpollAsync,
|
||||||
spendCoins,
|
spendCoins,
|
||||||
@ -110,12 +110,12 @@ async function handlePurseCreationConflict(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
resp: HttpResponse,
|
resp: HttpResponse,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const pursePub = peerPushInitiation.pursePub;
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
const errResp = await readTalerErrorResponse(resp);
|
const errResp = await readTalerErrorResponse(resp);
|
||||||
if (errResp.code !== TalerErrorCode.EXCHANGE_GENERIC_INSUFFICIENT_FUNDS) {
|
if (errResp.code !== TalerErrorCode.EXCHANGE_GENERIC_INSUFFICIENT_FUNDS) {
|
||||||
await failPeerPushDebitTransaction(ws, pursePub);
|
await failPeerPushDebitTransaction(ws, pursePub);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Properly parse!
|
// FIXME: Properly parse!
|
||||||
@ -176,13 +176,13 @@ async function handlePurseCreationConflict(
|
|||||||
}
|
}
|
||||||
await tx.peerPushPaymentInitiations.put(myPpi);
|
await tx.peerPushPaymentInitiations.put(myPpi);
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPushDebitCreateReserve(
|
async function processPeerPushDebitCreateReserve(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info("processing peer-push-debit pending(create-reserve)");
|
logger.info("processing peer-push-debit pending(create-reserve)");
|
||||||
const pursePub = peerPushInitiation.pursePub;
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
const purseExpiration = peerPushInitiation.purseExpiration;
|
const purseExpiration = peerPushInitiation.purseExpiration;
|
||||||
@ -264,7 +264,7 @@ async function processPeerPushDebitCreateReserve(
|
|||||||
case HttpStatusCode.Forbidden: {
|
case HttpStatusCode.Forbidden: {
|
||||||
// FIXME: Store this error!
|
// FIXME: Store this error!
|
||||||
await failPeerPushDebitTransaction(ws, pursePub);
|
await failPeerPushDebitTransaction(ws, pursePub);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
case HttpStatusCode.Conflict: {
|
case HttpStatusCode.Conflict: {
|
||||||
// Handle double-spending
|
// Handle double-spending
|
||||||
@ -273,7 +273,7 @@ async function processPeerPushDebitCreateReserve(
|
|||||||
default: {
|
default: {
|
||||||
const errResp = await readTalerErrorResponse(httpResp);
|
const errResp = await readTalerErrorResponse(httpResp);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: errResp,
|
errorDetail: errResp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -289,13 +289,13 @@ async function processPeerPushDebitCreateReserve(
|
|||||||
stTo: PeerPushPaymentInitiationStatus.PendingReady,
|
stTo: PeerPushPaymentInitiationStatus.PendingReady,
|
||||||
});
|
});
|
||||||
|
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPeerPushDebitAbortingDeletePurse(
|
async function processPeerPushDebitAbortingDeletePurse(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { pursePub, pursePriv } = peerPushInitiation;
|
const { pursePub, pursePriv } = peerPushInitiation;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.PeerPushDebit,
|
tag: TransactionType.PeerPushDebit,
|
||||||
@ -364,7 +364,7 @@ async function processPeerPushDebitAbortingDeletePurse(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SimpleTransition {
|
interface SimpleTransition {
|
||||||
@ -406,7 +406,7 @@ async function transitionPeerPushDebitTransaction(
|
|||||||
async function processPeerPushDebitAbortingRefresh(
|
async function processPeerPushDebitAbortingRefresh(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const pursePub = peerPushInitiation.pursePub;
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
const abortRefreshGroupId = peerPushInitiation.abortRefreshGroupId;
|
const abortRefreshGroupId = peerPushInitiation.abortRefreshGroupId;
|
||||||
checkLogicInvariant(!!abortRefreshGroupId);
|
checkLogicInvariant(!!abortRefreshGroupId);
|
||||||
@ -448,7 +448,7 @@ async function processPeerPushDebitAbortingRefresh(
|
|||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
// FIXME: Shouldn't this be finished in some cases?!
|
// FIXME: Shouldn't this be finished in some cases?!
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -457,7 +457,7 @@ async function processPeerPushDebitAbortingRefresh(
|
|||||||
async function processPeerPushDebitReady(
|
async function processPeerPushDebitReady(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info("processing peer-push-debit pending(ready)");
|
logger.info("processing peer-push-debit pending(ready)");
|
||||||
const pursePub = peerPushInitiation.pursePub;
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
const retryTag = constructTaskIdentifier({
|
const retryTag = constructTaskIdentifier({
|
||||||
@ -520,14 +520,14 @@ async function processPeerPushDebitReady(
|
|||||||
"returning early from peer-push-debit for long-polling in background",
|
"returning early from peer-push-debit for long-polling in background",
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processPeerPushDebit(
|
export async function processPeerPushDebit(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pursePub: string,
|
pursePub: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const peerPushInitiation = await ws.db
|
const peerPushInitiation = await ws.db
|
||||||
.mktx((x) => [x.peerPushPaymentInitiations])
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
@ -546,7 +546,7 @@ export async function processPeerPushDebit(
|
|||||||
if (ws.activeLongpoll[retryTag]) {
|
if (ws.activeLongpoll[retryTag]) {
|
||||||
logger.info("peer-push-debit task already in long-polling, returning!");
|
logger.info("peer-push-debit task already in long-polling, returning!");
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,10 +567,7 @@ export async function processPeerPushDebit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +55,7 @@ import { checkDbInvariant } from "../util/invariants.js";
|
|||||||
import { GetReadWriteAccess } from "../util/query.js";
|
import { GetReadWriteAccess } from "../util/query.js";
|
||||||
import { createRefreshGroup, processRefreshGroup } from "./refresh.js";
|
import { createRefreshGroup, processRefreshGroup } from "./refresh.js";
|
||||||
import { internalCreateWithdrawalGroup } from "./withdraw.js";
|
import { internalCreateWithdrawalGroup } from "./withdraw.js";
|
||||||
import { OperationAttemptResult } from "./common.js";
|
import { TaskRunResult } from "./common.js";
|
||||||
|
|
||||||
const logger = new Logger("operations/recoup.ts");
|
const logger = new Logger("operations/recoup.ts");
|
||||||
|
|
||||||
@ -289,18 +289,18 @@ async function recoupRefreshCoin(
|
|||||||
export async function processRecoupGroup(
|
export async function processRecoupGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
recoupGroupId: string,
|
recoupGroupId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
let recoupGroup = await ws.db
|
let recoupGroup = await ws.db
|
||||||
.mktx((x) => [x.recoupGroups])
|
.mktx((x) => [x.recoupGroups])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
return tx.recoupGroups.get(recoupGroupId);
|
return tx.recoupGroups.get(recoupGroupId);
|
||||||
});
|
});
|
||||||
if (!recoupGroup) {
|
if (!recoupGroup) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
if (recoupGroup.timestampFinished) {
|
if (recoupGroup.timestampFinished) {
|
||||||
logger.trace("recoup group finished");
|
logger.trace("recoup group finished");
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
const ps = recoupGroup.coinPubs.map(async (x, i) => {
|
const ps = recoupGroup.coinPubs.map(async (x, i) => {
|
||||||
try {
|
try {
|
||||||
@ -318,12 +318,12 @@ export async function processRecoupGroup(
|
|||||||
return tx.recoupGroups.get(recoupGroupId);
|
return tx.recoupGroups.get(recoupGroupId);
|
||||||
});
|
});
|
||||||
if (!recoupGroup) {
|
if (!recoupGroup) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const b of recoupGroup.recoupFinishedPerCoin) {
|
for (const b of recoupGroup.recoupFinishedPerCoin) {
|
||||||
if (!b) {
|
if (!b) {
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +408,7 @@ export async function processRecoupGroup(
|
|||||||
}
|
}
|
||||||
await tx.recoupGroups.put(rg2);
|
await tx.recoupGroups.put(rg2);
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createRecoupGroup(
|
export async function createRecoupGroup(
|
||||||
|
@ -89,8 +89,8 @@ import {
|
|||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
makeCoinAvailable,
|
makeCoinAvailable,
|
||||||
makeCoinsVisible,
|
makeCoinsVisible,
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||||
import {
|
import {
|
||||||
@ -770,23 +770,17 @@ export async function processRefreshGroup(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
refreshGroupId: string,
|
refreshGroupId: string,
|
||||||
options: Record<string, never> = {},
|
options: Record<string, never> = {},
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info(`processing refresh group ${refreshGroupId}`);
|
logger.info(`processing refresh group ${refreshGroupId}`);
|
||||||
|
|
||||||
const refreshGroup = await ws.db
|
const refreshGroup = await ws.db
|
||||||
.mktx((x) => [x.refreshGroups])
|
.mktx((x) => [x.refreshGroups])
|
||||||
.runReadOnly(async (tx) => tx.refreshGroups.get(refreshGroupId));
|
.runReadOnly(async (tx) => tx.refreshGroups.get(refreshGroupId));
|
||||||
if (!refreshGroup) {
|
if (!refreshGroup) {
|
||||||
return {
|
return TaskRunResult.finished()
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (refreshGroup.timestampFinished) {
|
if (refreshGroup.timestampFinished) {
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// Process refresh sessions of the group in parallel.
|
// Process refresh sessions of the group in parallel.
|
||||||
logger.trace("processing refresh sessions for old coins");
|
logger.trace("processing refresh sessions for old coins");
|
||||||
@ -823,14 +817,11 @@ export async function processRefreshGroup(
|
|||||||
logger.warn(`exception: ${e}`);
|
logger.warn(`exception: ${e}`);
|
||||||
}
|
}
|
||||||
if (inShutdown) {
|
if (inShutdown) {
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Pending,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_REFRESH_GROUP_INCOMPLETE,
|
TalerErrorCode.WALLET_REFRESH_GROUP_INCOMPLETE,
|
||||||
{
|
{
|
||||||
@ -841,10 +832,7 @@ export async function processRefreshGroup(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processRefreshSession(
|
async function processRefreshSession(
|
||||||
@ -1122,7 +1110,7 @@ function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime {
|
|||||||
export async function autoRefresh(
|
export async function autoRefresh(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
exchangeBaseUrl: string,
|
exchangeBaseUrl: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.info(`doing auto-refresh check for '${exchangeBaseUrl}'`);
|
logger.info(`doing auto-refresh check for '${exchangeBaseUrl}'`);
|
||||||
|
|
||||||
// We must make sure that the exchange is up-to-date so that
|
// We must make sure that the exchange is up-to-date so that
|
||||||
@ -1204,7 +1192,7 @@ export async function autoRefresh(
|
|||||||
AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
|
AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
|
||||||
await tx.exchanges.put(exchange);
|
await tx.exchanges.put(exchange);
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeRefreshTransactionState(
|
export function computeRefreshTransactionState(
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
Duration,
|
Duration,
|
||||||
IntegrationTestV2Args,
|
IntegrationTestV2Args,
|
||||||
Logger,
|
Logger,
|
||||||
|
NotificationType,
|
||||||
stringToBytes,
|
stringToBytes,
|
||||||
TestPayResult,
|
TestPayResult,
|
||||||
WithdrawTestBalanceRequest,
|
WithdrawTestBalanceRequest,
|
||||||
@ -64,6 +65,7 @@ import {
|
|||||||
confirmPeerPushCredit,
|
confirmPeerPushCredit,
|
||||||
} from "./pay-peer-push-credit.js";
|
} from "./pay-peer-push-credit.js";
|
||||||
import { initiatePeerPushDebit } from "./pay-peer-push-debit.js";
|
import { initiatePeerPushDebit } from "./pay-peer-push-debit.js";
|
||||||
|
import { OpenedPromise, openPromise } from "../index.js";
|
||||||
|
|
||||||
const logger = new Logger("operations/testing.ts");
|
const logger = new Logger("operations/testing.ts");
|
||||||
|
|
||||||
@ -445,6 +447,18 @@ export async function runIntegrationTest(
|
|||||||
logger.trace("integration test: all done!");
|
logger.trace("integration test: all done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function waitUntilDone(ws: InternalWalletState): Promise<void> {
|
||||||
|
let p: OpenedPromise<void> | undefined = undefined;
|
||||||
|
ws.addNotificationListener((notif) => {
|
||||||
|
if (!p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (notif.type === NotificationType.TransactionStateTransition) {
|
||||||
|
p.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function runIntegrationTest2(
|
export async function runIntegrationTest2(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
args: IntegrationTestV2Args,
|
args: IntegrationTestV2Args,
|
||||||
|
@ -62,8 +62,8 @@ import {
|
|||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
makeCoinAvailable,
|
makeCoinAvailable,
|
||||||
makeCoinsVisible,
|
makeCoinsVisible,
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
} from "./common.js";
|
} from "./common.js";
|
||||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||||
import {
|
import {
|
||||||
@ -241,17 +241,14 @@ export async function prepareTip(
|
|||||||
export async function processTip(
|
export async function processTip(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
walletTipId: string,
|
walletTipId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const tipRecord = await ws.db
|
const tipRecord = await ws.db
|
||||||
.mktx((x) => [x.tips])
|
.mktx((x) => [x.tips])
|
||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
return tx.tips.get(walletTipId);
|
return tx.tips.get(walletTipId);
|
||||||
});
|
});
|
||||||
if (!tipRecord) {
|
if (!tipRecord) {
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tipRecord.status) {
|
switch (tipRecord.status) {
|
||||||
@ -259,10 +256,7 @@ export async function processTip(
|
|||||||
case TipRecordStatus.DialogAccept:
|
case TipRecordStatus.DialogAccept:
|
||||||
case TipRecordStatus.Done:
|
case TipRecordStatus.Done:
|
||||||
case TipRecordStatus.SuspendidPickup:
|
case TipRecordStatus.SuspendidPickup:
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
@ -324,7 +318,7 @@ export async function processTip(
|
|||||||
logger.trace(`got transient tip error`);
|
logger.trace(`got transient tip error`);
|
||||||
// FIXME: wrap in another error code that indicates a transient error
|
// FIXME: wrap in another error code that indicates a transient error
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
|
TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
|
||||||
getHttpResponseErrorDetails(merchantResp),
|
getHttpResponseErrorDetails(merchantResp),
|
||||||
@ -376,7 +370,7 @@ export async function processTip(
|
|||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_TIPPING_COIN_SIGNATURE_INVALID,
|
TalerErrorCode.WALLET_TIPPING_COIN_SIGNATURE_INVALID,
|
||||||
{},
|
{},
|
||||||
@ -430,10 +424,7 @@ export async function processTip(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
ws.notify({ type: NotificationType.BalanceChange });
|
ws.notify({ type: NotificationType.BalanceChange });
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function acceptTip(
|
export async function acceptTip(
|
||||||
|
@ -90,8 +90,8 @@ import {
|
|||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
TaskRunResult,
|
||||||
OperationAttemptResultType,
|
TaskRunResultType,
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
constructTaskIdentifier,
|
constructTaskIdentifier,
|
||||||
makeCoinAvailable,
|
makeCoinAvailable,
|
||||||
@ -1326,7 +1326,7 @@ export interface WithdrawalGroupContext {
|
|||||||
async function processWithdrawalGroupAbortingBank(
|
async function processWithdrawalGroupAbortingBank(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalGroup: WithdrawalGroupRecord,
|
withdrawalGroup: WithdrawalGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { withdrawalGroupId } = withdrawalGroup;
|
const { withdrawalGroupId } = withdrawalGroup;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.Withdrawal,
|
tag: TransactionType.Withdrawal,
|
||||||
@ -1363,10 +1363,7 @@ async function processWithdrawalGroupAbortingBank(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1413,7 +1410,7 @@ async function transitionKycSatisfied(
|
|||||||
async function processWithdrawalGroupPendingKyc(
|
async function processWithdrawalGroupPendingKyc(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalGroup: WithdrawalGroupRecord,
|
withdrawalGroup: WithdrawalGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const userType = "individual";
|
const userType = "individual";
|
||||||
const kycInfo = withdrawalGroup.kycPending;
|
const kycInfo = withdrawalGroup.kycPending;
|
||||||
if (!kycInfo) {
|
if (!kycInfo) {
|
||||||
@ -1456,13 +1453,13 @@ async function processWithdrawalGroupPendingKyc(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.longpoll();
|
return TaskRunResult.longpoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processWithdrawalGroupPendingReady(
|
async function processWithdrawalGroupPendingReady(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalGroup: WithdrawalGroupRecord,
|
withdrawalGroup: WithdrawalGroupRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
const { withdrawalGroupId } = withdrawalGroup;
|
const { withdrawalGroupId } = withdrawalGroup;
|
||||||
const transactionId = constructTransactionIdentifier({
|
const transactionId = constructTransactionIdentifier({
|
||||||
tag: TransactionType.Withdrawal,
|
tag: TransactionType.Withdrawal,
|
||||||
@ -1494,7 +1491,7 @@ async function processWithdrawalGroupPendingReady(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
const numTotalCoins = withdrawalGroup.denomsSel.selectedDenoms
|
const numTotalCoins = withdrawalGroup.denomsSel.selectedDenoms
|
||||||
@ -1608,7 +1605,7 @@ async function processWithdrawalGroupPendingReady(
|
|||||||
|
|
||||||
if (numPlanchetErrors > 0) {
|
if (numPlanchetErrors > 0) {
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Error,
|
type: TaskRunResultType.Error,
|
||||||
errorDetail: makeErrorDetail(
|
errorDetail: makeErrorDetail(
|
||||||
TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE,
|
TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE,
|
||||||
{
|
{
|
||||||
@ -1619,16 +1616,13 @@ async function processWithdrawalGroupPendingReady(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processWithdrawalGroup(
|
export async function processWithdrawalGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalGroupId: string,
|
withdrawalGroupId: string,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
logger.trace("processing withdrawal group", withdrawalGroupId);
|
logger.trace("processing withdrawal group", withdrawalGroupId);
|
||||||
const withdrawalGroup = await ws.db
|
const withdrawalGroup = await ws.db
|
||||||
.mktx((x) => [x.withdrawalGroups])
|
.mktx((x) => [x.withdrawalGroups])
|
||||||
@ -1646,7 +1640,7 @@ export async function processWithdrawalGroup(
|
|||||||
if (ws.activeLongpoll[retryTag]) {
|
if (ws.activeLongpoll[retryTag]) {
|
||||||
logger.info("withdrawal group already in long-polling, returning!");
|
logger.info("withdrawal group already in long-polling, returning!");
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,7 +1657,7 @@ export async function processWithdrawalGroup(
|
|||||||
"returning early from withdrawal for long-polling in background",
|
"returning early from withdrawal for long-polling in background",
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: TaskRunResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.PendingWaitConfirmBank: {
|
case WithdrawalGroupStatus.PendingWaitConfirmBank: {
|
||||||
@ -1671,15 +1665,9 @@ export async function processWithdrawalGroup(
|
|||||||
switch (res.status) {
|
switch (res.status) {
|
||||||
case BankStatusResultCode.Aborted:
|
case BankStatusResultCode.Aborted:
|
||||||
case BankStatusResultCode.Done:
|
case BankStatusResultCode.Done:
|
||||||
return {
|
return TaskRunResult.finished();
|
||||||
type: OperationAttemptResultType.Finished,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
case BankStatusResultCode.Waiting: {
|
case BankStatusResultCode.Waiting: {
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Pending,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1687,14 +1675,11 @@ export async function processWithdrawalGroup(
|
|||||||
case WithdrawalGroupStatus.Finished:
|
case WithdrawalGroupStatus.Finished:
|
||||||
case WithdrawalGroupStatus.FailedBankAborted: {
|
case WithdrawalGroupStatus.FailedBankAborted: {
|
||||||
// FIXME
|
// FIXME
|
||||||
return {
|
return TaskRunResult.pending();
|
||||||
type: OperationAttemptResultType.Pending,
|
|
||||||
result: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.PendingAml:
|
case WithdrawalGroupStatus.PendingAml:
|
||||||
// FIXME: Handle this case, withdrawal doesn't support AML yet.
|
// FIXME: Handle this case, withdrawal doesn't support AML yet.
|
||||||
return OperationAttemptResult.pendingEmpty();
|
return TaskRunResult.pending();
|
||||||
case WithdrawalGroupStatus.PendingKyc:
|
case WithdrawalGroupStatus.PendingKyc:
|
||||||
return processWithdrawalGroupPendingKyc(ws, withdrawalGroup);
|
return processWithdrawalGroupPendingKyc(ws, withdrawalGroup);
|
||||||
case WithdrawalGroupStatus.PendingReady:
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
@ -1713,7 +1698,7 @@ export async function processWithdrawalGroup(
|
|||||||
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
||||||
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return TaskRunResult.finished();
|
||||||
default:
|
default:
|
||||||
assertUnreachable(withdrawalGroup.status);
|
assertUnreachable(withdrawalGroup.status);
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,7 @@ import {
|
|||||||
import { setWalletDeviceId } from "./operations/backup/state.js";
|
import { setWalletDeviceId } from "./operations/backup/state.js";
|
||||||
import { getBalanceDetail, getBalances } from "./operations/balance.js";
|
import { getBalanceDetail, getBalances } from "./operations/balance.js";
|
||||||
import {
|
import {
|
||||||
|
TaskRunResult,
|
||||||
getExchangeTosStatus,
|
getExchangeTosStatus,
|
||||||
makeExchangeListItem,
|
makeExchangeListItem,
|
||||||
runTaskWithErrorReporting,
|
runTaskWithErrorReporting,
|
||||||
@ -287,7 +288,6 @@ import {
|
|||||||
GetReadWriteAccess,
|
GetReadWriteAccess,
|
||||||
} from "./util/query.js";
|
} from "./util/query.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
|
||||||
TaskIdentifiers,
|
TaskIdentifiers,
|
||||||
} from "./operations/common.js";
|
} from "./operations/common.js";
|
||||||
import { TimerAPI, TimerGroup } from "./util/timer.js";
|
import { TimerAPI, TimerGroup } from "./util/timer.js";
|
||||||
@ -320,7 +320,7 @@ const logger = new Logger("wallet.ts");
|
|||||||
async function callOperationHandler(
|
async function callOperationHandler(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pending: PendingTaskInfo,
|
pending: PendingTaskInfo,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<TaskRunResult> {
|
||||||
switch (pending.type) {
|
switch (pending.type) {
|
||||||
case PendingTaskType.ExchangeUpdate:
|
case PendingTaskType.ExchangeUpdate:
|
||||||
return await updateExchangeFromUrlHandler(ws, pending.exchangeBaseUrl);
|
return await updateExchangeFromUrlHandler(ws, pending.exchangeBaseUrl);
|
||||||
|
@ -54,6 +54,11 @@ setPRNG(function (x: Uint8Array, n: number) {
|
|||||||
|
|
||||||
const logger = new Logger("taler-wallet-embedded/index.ts");
|
const logger = new Logger("taler-wallet-embedded/index.ts");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends JSON to the host application, i.e. the process that
|
||||||
|
* runs the JavaScript interpreter (quickjs / qtart) to run
|
||||||
|
* the embedded wallet.
|
||||||
|
*/
|
||||||
function sendNativeMessage(ev: CoreApiMessageEnvelope): void {
|
function sendNativeMessage(ev: CoreApiMessageEnvelope): void {
|
||||||
const m = JSON.stringify(ev);
|
const m = JSON.stringify(ev);
|
||||||
qjsOs.postMessageToHost(m);
|
qjsOs.postMessageToHost(m);
|
||||||
@ -183,21 +188,25 @@ export function installNativeWalletListener(): void {
|
|||||||
const id = msg.id;
|
const id = msg.id;
|
||||||
logger.info(`native listener: got request for ${operation} (${id})`);
|
logger.info(`native listener: got request for ${operation} (${id})`);
|
||||||
|
|
||||||
let respMsg: CoreApiResponse;
|
if (operation === "anastasisReduce") {
|
||||||
try {
|
sendNativeMessage(respMsg);
|
||||||
respMsg = await handler.handleMessage(operation, id, msg.args ?? {});
|
} else {
|
||||||
} catch (e) {
|
let respMsg: CoreApiResponse;
|
||||||
respMsg = {
|
try {
|
||||||
type: "error",
|
respMsg = await handler.handleMessage(operation, id, msg.args ?? {});
|
||||||
id,
|
} catch (e) {
|
||||||
operation,
|
respMsg = {
|
||||||
error: getErrorDetailFromException(e),
|
type: "error",
|
||||||
};
|
id,
|
||||||
|
operation,
|
||||||
|
error: getErrorDetailFromException(e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
logger.info(
|
||||||
|
`native listener: sending back ${respMsg.type} message for operation ${operation} (${id})`,
|
||||||
|
);
|
||||||
|
sendNativeMessage(respMsg);
|
||||||
}
|
}
|
||||||
logger.info(
|
|
||||||
`native listener: sending back ${respMsg.type} message for operation ${operation} (${id})`,
|
|
||||||
);
|
|
||||||
sendNativeMessage(respMsg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
qjsOs.setMessageFromHostHandler((m) => onMessage(m));
|
qjsOs.setMessageFromHostHandler((m) => onMessage(m));
|
||||||
|
Loading…
Reference in New Issue
Block a user