aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-embedded
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-02-15 23:32:42 +0100
committerFlorian Dold <florian@dold.me>2023-02-16 02:50:29 +0100
commit825d2c4352022e7397854b2bd9ba7d3589873c07 (patch)
treed23530bf8408367439e6b3820ea0c4269bfeb39a /packages/taler-wallet-embedded
parentcb2f4c21d85707abb0221cbf2a859a98836b2d44 (diff)
downloadwallet-core-825d2c4352022e7397854b2bd9ba7d3589873c07.tar.xz
make wallet-cli runnable under qtart
Diffstat (limited to 'packages/taler-wallet-embedded')
-rwxr-xr-xpackages/taler-wallet-embedded/build.mjs1
-rw-r--r--packages/taler-wallet-embedded/src/index.ts28
-rw-r--r--packages/taler-wallet-embedded/src/wallet-qjs.ts237
3 files changed, 28 insertions, 238 deletions
diff --git a/packages/taler-wallet-embedded/build.mjs b/packages/taler-wallet-embedded/build.mjs
index 537a4fbc0..28351e6e5 100755
--- a/packages/taler-wallet-embedded/build.mjs
+++ b/packages/taler-wallet-embedded/build.mjs
@@ -55,6 +55,7 @@ export const buildConfig = {
format: 'esm',
platform: 'neutral',
mainFields: ["module", "main"],
+ conditions: ["qtart"],
sourcemap: true,
define: {
'__VERSION__': `"${_package.version}"`,
diff --git a/packages/taler-wallet-embedded/src/index.ts b/packages/taler-wallet-embedded/src/index.ts
index b505a2d9d..e0a13390d 100644
--- a/packages/taler-wallet-embedded/src/index.ts
+++ b/packages/taler-wallet-embedded/src/index.ts
@@ -18,27 +18,25 @@
* Imports.
*/
import {
+ createNativeWalletHost,
DefaultNodeWalletArgs,
- getDefaultNodeWallet,
- getErrorDetailFromException,
handleWorkerError,
handleWorkerMessage,
- Headers,
- HttpRequestLibrary,
- HttpRequestOptions,
- HttpResponse,
- NodeHttpLib,
OpenedPromise,
openPromise,
Wallet,
- WALLET_EXCHANGE_PROTOCOL_VERSION,
- WALLET_MERCHANT_PROTOCOL_VERSION,
} from "@gnu-taler/taler-wallet-core";
import {
CoreApiMessageEnvelope,
CoreApiResponse,
CoreApiResponseSuccess,
+ createPlatformHttpLib,
+ getErrorDetailFromException,
+ Headers,
+ HttpRequestLibrary,
+ HttpRequestOptions,
+ HttpResponse,
Logger,
WalletNotification,
} from "@gnu-taler/taler-util";
@@ -51,7 +49,7 @@ const logger = new Logger("taler-wallet-embedded/index.ts");
export class NativeHttpLib implements HttpRequestLibrary {
useNfcTunnel = false;
- private nodeHttpLib: HttpRequestLibrary = new NodeHttpLib();
+ private httpLib: HttpRequestLibrary = createPlatformHttpLib();
private requestId = 1;
@@ -62,7 +60,7 @@ export class NativeHttpLib implements HttpRequestLibrary {
constructor(private sendMessage: (m: string) => void) {}
fetch(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
- return this.nodeHttpLib.fetch(url, opt);
+ return this.httpLib.fetch(url, opt);
}
get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
@@ -83,7 +81,7 @@ export class NativeHttpLib implements HttpRequestLibrary {
);
return p.promise;
} else {
- return this.nodeHttpLib.get(url, opt);
+ return this.httpLib.get(url, opt);
}
}
@@ -106,7 +104,7 @@ export class NativeHttpLib implements HttpRequestLibrary {
);
return p.promise;
} else {
- return this.nodeHttpLib.postJson(url, body, opt);
+ return this.httpLib.postJson(url, body, opt);
}
}
@@ -158,7 +156,7 @@ class NativeWalletMessageHandler {
walletArgs: DefaultNodeWalletArgs | undefined;
maybeWallet: Wallet | undefined;
wp = openPromise<Wallet>();
- httpLib = new NodeHttpLib();
+ httpLib = createPlatformHttpLib();
/**
* Handle a request from the native wallet.
@@ -181,7 +179,7 @@ class NativeWalletMessageHandler {
const reinit = async () => {
logger.info("in reinit");
- const w = await getDefaultNodeWallet(this.walletArgs);
+ const w = await createNativeWalletHost(this.walletArgs);
this.maybeWallet = w;
const resp = await w.handleCoreApiRequest(
"initWallet",
diff --git a/packages/taler-wallet-embedded/src/wallet-qjs.ts b/packages/taler-wallet-embedded/src/wallet-qjs.ts
index f7b73711c..77d166095 100644
--- a/packages/taler-wallet-embedded/src/wallet-qjs.ts
+++ b/packages/taler-wallet-embedded/src/wallet-qjs.ts
@@ -18,43 +18,25 @@
* Imports.
*/
import {
- AccessStats,
- DefaultNodeWalletArgs,
- getErrorDetailFromException,
- Headers,
- HttpRequestLibrary,
- HttpRequestOptions,
- HttpResponse,
- openPromise,
- openTalerDatabase,
- SetTimeoutTimerAPI,
- SynchronousCryptoWorkerFactoryPlain,
- Wallet,
- WalletApiOperation,
-} from "@gnu-taler/taler-wallet-core";
-
-import {
CoreApiMessageEnvelope,
CoreApiResponse,
CoreApiResponseSuccess,
+ createPlatformHttpLib,
+ getErrorDetailFromException,
InitRequest,
- j2s,
Logger,
setGlobalLogLevelFromString,
setPRNG,
WalletNotification,
} from "@gnu-taler/taler-util";
-import { BridgeIDBFactory } from "@gnu-taler/idb-bridge";
-import { MemoryBackend } from "@gnu-taler/idb-bridge";
-import { shimIndexedDB } from "@gnu-taler/idb-bridge";
-import { IDBFactory } from "@gnu-taler/idb-bridge";
-
-import * as _qjsOsImp from "os";
-// @ts-ignore
-import * as _qjsStdImp from "std";
-
-const textDecoder = new TextDecoder();
-const textEncoder = new TextEncoder();
+import { qjsOs } from "@gnu-taler/taler-util/qtart";
+import {
+ createNativeWalletHost2,
+ DefaultNodeWalletArgs,
+ openPromise,
+ Wallet,
+ WalletApiOperation,
+} from "@gnu-taler/taler-wallet-core";
setGlobalLogLevelFromString("trace");
@@ -66,210 +48,19 @@ setPRNG(function (x: Uint8Array, n: number) {
for (let i = 0; i < v.length; i++) v[i] = 0;
});
-export interface QjsHttpResp {
- status: number;
- data: ArrayBuffer;
-}
-
-export interface QjsHttpOptions {
- method: string;
- debug?: boolean;
- data?: ArrayBuffer;
- headers?: string[];
-}
-
-export interface QjsOsLib {
- fetchHttp(url: string, options?: QjsHttpOptions): Promise<QjsHttpResp>;
- postMessageToHost(s: string): void;
- setMessageFromHostHandler(h: (s: string) => void): void;
- rename(oldPath: string, newPath: string): number;
-}
-
-export interface QjsStdLib {
- writeFile(filename: string, contents: string): void;
- loadFile(filename: string): string;
-}
-
-// This is not the nodejs "os" module, but the qjs "os" module.
-const qjsOs: QjsOsLib = _qjsOsImp as any;
-
-const qjsStd: QjsStdLib = _qjsStdImp as any;
-
const logger = new Logger("taler-wallet-embedded/index.ts");
-export class NativeHttpLib implements HttpRequestLibrary {
- get(
- url: string,
- opt?: HttpRequestOptions | undefined,
- ): Promise<HttpResponse> {
- return this.fetch(url, {
- method: "GET",
- ...opt,
- });
- }
- postJson(
- url: string,
- body: any,
- opt?: HttpRequestOptions | undefined,
- ): Promise<HttpResponse> {
- return this.fetch(url, {
- method: "POST",
- body,
- ...opt,
- });
- }
- async fetch(
- url: string,
- opt?: HttpRequestOptions | undefined,
- ): Promise<HttpResponse> {
- const method = opt?.method ?? "GET";
- let data: ArrayBuffer | undefined = undefined;
- let headers: string[] = [];
- if (opt?.headers) {
- for (let headerName of Object.keys(opt.headers)) {
- headers.push(`${headerName}: ${opt.headers[headerName]}`);
- }
- }
- if (method.toUpperCase() === "POST") {
- if (opt?.body) {
- if (typeof opt.body === "string") {
- data = textEncoder.encode(opt.body).buffer;
- } else if (ArrayBuffer.isView(opt.body)) {
- data = opt.body.buffer;
- } else if (opt.body instanceof ArrayBuffer) {
- data = opt.body;
- } else if (typeof opt.body === "object") {
- data = textEncoder.encode(JSON.stringify(opt.body)).buffer;
- }
- } else {
- data = new ArrayBuffer(0);
- }
- }
- const res = await qjsOs.fetchHttp(url, {
- method,
- data,
- headers,
- });
- return {
- requestMethod: method,
- headers: new Headers(),
- async bytes() {
- return res.data;
- },
- json() {
- const text = textDecoder.decode(res.data);
- return JSON.parse(text);
- },
- async text() {
- const text = textDecoder.decode(res.data);
- return text;
- },
- requestUrl: url,
- status: res.status,
- };
- }
-}
-
function sendNativeMessage(ev: CoreApiMessageEnvelope): void {
const m = JSON.stringify(ev);
qjsOs.postMessageToHost(m);
}
-/**
- * Generate a random alphanumeric ID. Does *not* use cryptographically
- * secure randomness.
- */
-function makeId(length: number): string {
- let result = "";
- const characters =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- for (let i = 0; i < length; i++) {
- result += characters.charAt(Math.floor(Math.random() * characters.length));
- }
- return result;
-}
-
-export async function getWallet(args: DefaultNodeWalletArgs = {}): Promise<{
- wallet: Wallet;
- getDbStats: () => AccessStats;
-}> {
- BridgeIDBFactory.enableTracing = false;
- const myBackend = new MemoryBackend();
- myBackend.enableTracing = false;
-
- const storagePath = args.persistentStoragePath;
- if (storagePath) {
- const dbContentStr = qjsStd.loadFile(storagePath);
- if (dbContentStr != null) {
- const dbContent = JSON.parse(dbContentStr);
- myBackend.importDump(dbContent);
- }
-
- myBackend.afterCommitCallback = async () => {
- logger.trace("committing database");
- // Allow caller to stop persisting the wallet.
- if (args.persistentStoragePath === undefined) {
- return;
- }
- const tmpPath = `${args.persistentStoragePath}-${makeId(5)}.tmp`;
- const dbContent = myBackend.exportDump();
- qjsStd.writeFile(tmpPath, JSON.stringify(dbContent, undefined, 2));
- // Atomically move the temporary file onto the DB path.
- const res = qjsOs.rename(tmpPath, args.persistentStoragePath);
- if (res != 0) {
- throw Error("db commit failed at rename");
- }
- logger.trace("committing database done");
- };
- }
-
- console.log("done processing storage path");
-
- BridgeIDBFactory.enableTracing = false;
-
- const myBridgeIdbFactory = new BridgeIDBFactory(myBackend);
- const myIdbFactory: IDBFactory = myBridgeIdbFactory as any as IDBFactory;
-
- let myHttpLib;
- if (args.httpLib) {
- myHttpLib = args.httpLib;
- } else {
- myHttpLib = new NativeHttpLib();
- }
-
- const myVersionChange = (): Promise<void> => {
- logger.error("version change requested, should not happen");
- throw Error(
- "BUG: wallet DB version change event can't happen with memory IDB",
- );
- };
-
- shimIndexedDB(myBridgeIdbFactory);
-
- const myDb = await openTalerDatabase(myIdbFactory, myVersionChange);
-
- let workerFactory;
- workerFactory = new SynchronousCryptoWorkerFactoryPlain();
-
- const timer = new SetTimeoutTimerAPI();
-
- const w = await Wallet.create(myDb, myHttpLib, timer, workerFactory);
-
- if (args.notifyHandler) {
- w.addNotificationListener(args.notifyHandler);
- }
- return {
- wallet: w,
- getDbStats: () => myBackend.accessStats,
- };
-}
-
class NativeWalletMessageHandler {
walletArgs: DefaultNodeWalletArgs | undefined;
initRequest: InitRequest = {};
maybeWallet: Wallet | undefined;
wp = openPromise<Wallet>();
- httpLib = new NativeHttpLib();
+ httpLib = createPlatformHttpLib();
/**
* Handle a request from the native wallet.
@@ -292,7 +83,7 @@ class NativeWalletMessageHandler {
const reinit = async () => {
logger.info("in reinit");
- const wR = await getWallet(this.walletArgs);
+ const wR = await createNativeWalletHost2(this.walletArgs);
const w = wR.wallet;
this.maybeWallet = w;
const resp = await w.handleCoreApiRequest("initWallet", "native-init", {
@@ -422,7 +213,7 @@ globalThis.installNativeWalletListener = installNativeWalletListener;
globalThis.makeWallet = getWallet;
export async function testWithGv() {
- const w = await getWallet();
+ const w = await createNativeWalletHost2();
await w.wallet.client.call(WalletApiOperation.InitWallet, {});
await w.wallet.client.call(WalletApiOperation.RunIntegrationTest, {
amountToSpend: "KUDOS:1",
@@ -438,7 +229,7 @@ export async function testWithGv() {
export async function testWithLocal() {
console.log("running local test");
- const w = await getWallet({
+ const w = await createNativeWalletHost2({
persistentStoragePath: "walletdb.json",
});
console.log("created wallet");