wallet-core: skeleton for dev-experiments

This commit is contained in:
Florian Dold 2022-10-12 21:19:09 +02:00
parent 8bfa77200e
commit 3da1e82a24
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
7 changed files with 100 additions and 2 deletions

View File

@ -21,7 +21,6 @@
// Defines whether an open brace is put onto a new line for control blocks or not
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": false,
"typescript.preferences.autoImportFileExcludePatterns": [
"index.js",
"index.*.js",
"index.ts",
"index.*.ts"

View File

@ -50,6 +50,10 @@ export interface PayPullUriResult {
contractPriv: string;
}
export interface DevExperimentUri {
devExperimentId: string;
}
/**
* Parse a taler[+http]://withdraw URI.
* Return undefined if not passed a valid URI.
@ -91,6 +95,7 @@ export enum TalerUriType {
TalerNotifyReserve = "taler-notify-reserve",
TalerPayPush = "taler-pay-push",
TalerPayPull = "taler-pay-pull",
TalerDevExperiment = "taler-dev-experiment",
Unknown = "unknown",
}
@ -141,6 +146,9 @@ export function classifyTalerUri(s: string): TalerUriType {
if (sl.startsWith("taler://notify-reserve/")) {
return TalerUriType.TalerNotifyReserve;
}
if (sl.startsWith("taler://dev-experiment/")) {
return TalerUriType.TalerDevExperiment;
}
return TalerUriType.Unknown;
}
@ -300,6 +308,19 @@ export function parseRefundUri(s: string): RefundUriResult | undefined {
};
}
export function parseDevExperimentUri(s: string): DevExperimentUri | undefined {
const pi = parseProtoInfo(s, "dev-experiment");
const c = pi?.rest.split("?");
if (!c) {
return undefined;
}
// const q = new URLSearchParams(c[1] ?? "");
const parts = c[0].split("/");
return {
devExperimentId: parts[0],
};
}
export function constructPayPushUri(args: {
exchangeBaseUrl: string;
contractPriv: string;

View File

@ -1683,6 +1683,16 @@ export interface AcceptPeerPullPaymentRequest {
peerPullPaymentIncomingId: string;
}
export interface ApplyDevExperimentRequest {
devExperimentUri: string;
}
export const codecForApplyDevExperiment =
(): Codec<ApplyDevExperimentRequest> =>
buildCodecForObject<ApplyDevExperimentRequest>()
.property("devExperimentUri", codecForString())
.build("ApplyDevExperimentRequest");
export const codecForAcceptPeerPullPaymentRequest =
(): Codec<AcceptPeerPullPaymentRequest> =>
buildCodecForObject<AcceptPeerPullPaymentRequest>()

View File

@ -43,6 +43,7 @@ import {
setDangerousTimetravel,
setGlobalLogLevelFromString,
TalerUriType,
parseDevExperimentUri,
} from "@gnu-taler/taler-util";
import {
CryptoDispatcher,
@ -67,6 +68,7 @@ import { runEnv1 } from "./env1.js";
import { GlobalTestState, runTestWithState } from "./harness/harness.js";
import { getTestInfo, runTests } from "./integrationtests/testrunner.js";
import { lintExchangeDeployment } from "./lint.js";
import { checkLogicInvariant } from "@gnu-taler/taler-wallet-core/src/util/invariants.js";
// @ts-ignore
global.TextEncoder = TextEncoder;
// @ts-ignore
@ -498,6 +500,12 @@ walletCli
console.log("accept withdrawal response", res);
}
break;
case TalerUriType.TalerDevExperiment: {
await wallet.client.call(WalletApiOperation.ApplyDevExperiment, {
devExperimentUri: uri,
});
break;
}
default:
console.log(`URI type (${uriType}) not handled`);
break;

View File

@ -0,0 +1,38 @@
/*
This file is part of GNU Taler
(C) 2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* Implementation of dev experiments, i.e. scenarios
* triggered by taler://dev-experiment URIs.
*
* @author Florian Dold <dold@taler.net>
*/
/**
* Imports.
*/
import { Logger } from "@gnu-taler/taler-util";
import { InternalWalletState } from "./internal-wallet-state.js";
const logger = new Logger("dev-experiments.ts");
export async function applyDevExperiment(
ws: InternalWalletState,
uri: string,
): Promise<void> {
logger.info(`applying dev experiment ${uri}`);
}

View File

@ -80,6 +80,7 @@ import {
WithdrawTestBalanceRequest,
WithdrawUriInfoResponse,
} from "@gnu-taler/taler-util";
import { ApplyDevExperimentRequest } from "@gnu-taler/taler-util";
import {
AddBackupProviderRequest,
BackupInfo,
@ -139,6 +140,7 @@ export enum WalletApiOperation {
AcceptPeerPullPayment = "acceptPeerPullPayment",
ClearDb = "clearDb",
Recycle = "recycle",
ApplyDevExperiment = "applyDevExperiment",
}
// group: Initialization
@ -487,7 +489,7 @@ export type AcceptPeerPullPaymentOp = {
// group: Database Management
/**
* Exoport the wallet database's contents to JSON.
* Export the wallet database's contents to JSON.
*/
export type ExportDbOp = {
op: WalletApiOperation.ExportDb;
@ -515,6 +517,18 @@ export type RecycleOp = {
// group: Testing and Debugging
/**
* Apply a developer experiment to the current wallet state.
*
* This allows UI developers / testers to play around without
* an elaborate test environment.
*/
export type ApplyDevExperimentOp = {
op: WalletApiOperation.ApplyDevExperiment;
request: ApplyDevExperimentRequest;
response: {};
};
/**
* Run a simple integration test on a test deployment
* of the exchange and merchant.
@ -661,6 +675,7 @@ export type WalletOperations = {
[WalletApiOperation.AcceptPeerPullPayment]: AcceptPeerPullPaymentOp;
[WalletApiOperation.ClearDb]: ClearDbOp;
[WalletApiOperation.Recycle]: RecycleOp;
[WalletApiOperation.ApplyDevExperiment]: ApplyDevExperimentOp;
};
export type RequestType<

View File

@ -90,6 +90,7 @@ import {
parsePaytoUri,
RefreshReason,
TalerErrorCode,
codecForApplyDevExperiment,
URL,
WalletCoreVersion,
WalletNotification,
@ -109,6 +110,7 @@ import {
importDb,
WalletStoresV1,
} from "./db.js";
import { applyDevExperiment } from "./dev-experiments.js";
import { getErrorDetailFromException, TalerError } from "./errors.js";
import {
ActiveLongpollInfo,
@ -1325,6 +1327,11 @@ async function dispatchRequestInternal(
const req = codecForAcceptPeerPullPaymentRequest().decode(payload);
return await acceptPeerPullPayment(ws, req);
}
case "applyDevExperiment": {
const req = codecForApplyDevExperiment().decode(payload);
await applyDevExperiment(ws, req.devExperimentUri);
return {};
}
case "getVersion": {
const version: WalletCoreVersion = {
hash: GIT_HASH,