From 3cc26d00f85209c804d9f356598c0f749367ea74 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 26 Jan 2023 12:48:35 +0100 Subject: put taler wallet RPC into taler-util, make it cross-platform --- packages/anastasis-core/package.json | 2 +- packages/anastasis-webui/package.json | 2 +- packages/demobank-ui/package.json | 2 +- packages/idb-bridge/package.json | 2 +- packages/merchant-backend-ui/package.json | 2 +- packages/merchant-backoffice-ui/package.json | 2 +- packages/pogen/package.json | 2 +- packages/taler-harness/package.json | 4 +- packages/taler-util/package.json | 11 +- packages/taler-util/tsconfig.json | 8 +- packages/taler-wallet-cli/package.json | 2 +- packages/taler-wallet-cli/src/index.ts | 8 +- packages/taler-wallet-cli/src/rpc.ts | 266 --------------------------- packages/taler-wallet-cli/tsconfig.json | 2 +- packages/taler-wallet-core/package.json | 2 +- packages/taler-wallet-embedded/package.json | 2 +- packages/web-util/package.json | 2 +- 17 files changed, 33 insertions(+), 288 deletions(-) delete mode 100644 packages/taler-wallet-cli/src/rpc.ts (limited to 'packages') diff --git a/packages/anastasis-core/package.json b/packages/anastasis-core/package.json index 33d7898eb..77d10e131 100644 --- a/packages/anastasis-core/package.json +++ b/packages/anastasis-core/package.json @@ -19,7 +19,7 @@ "devDependencies": { "ava": "^4.3.3", "rimraf": "^3.0.2", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/anastasis-webui/package.json b/packages/anastasis-webui/package.json index c01856243..631e75369 100644 --- a/packages/anastasis-webui/package.json +++ b/packages/anastasis-webui/package.json @@ -45,6 +45,6 @@ "jssha": "^3.2.0", "mocha": "^9.2.0", "sass": "1.56.1", - "typescript": "^4.8.4" + "typescript": "^4.9.4" } } \ No newline at end of file diff --git a/packages/demobank-ui/package.json b/packages/demobank-ui/package.json index d915ee31b..cdf457ed4 100644 --- a/packages/demobank-ui/package.json +++ b/packages/demobank-ui/package.json @@ -61,7 +61,7 @@ "po2json": "^0.4.5", "preact-render-to-string": "^5.2.6", "sass": "1.56.1", - "typescript": "4.8.4" + "typescript": "4.9.4" }, "pogen": { "domain": "bank" diff --git a/packages/idb-bridge/package.json b/packages/idb-bridge/package.json index 9a58b8695..63f1a5bbf 100644 --- a/packages/idb-bridge/package.json +++ b/packages/idb-bridge/package.json @@ -27,7 +27,7 @@ "esm": "^3.2.25", "prettier": "^2.5.1", "rimraf": "^3.0.2", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "tslib": "^2.4.0" diff --git a/packages/merchant-backend-ui/package.json b/packages/merchant-backend-ui/package.json index 4789b96e9..ddba985aa 100644 --- a/packages/merchant-backend-ui/package.json +++ b/packages/merchant-backend-ui/package.json @@ -87,6 +87,6 @@ "script-ext-html-webpack-plugin": "^2.1.5", "sirv-cli": "^1.0.11", "tslib": "2.4.0", - "typescript": "4.8.4" + "typescript": "4.9.4" } } diff --git a/packages/merchant-backoffice-ui/package.json b/packages/merchant-backoffice-ui/package.json index 6ea09572b..fa717fc3e 100644 --- a/packages/merchant-backoffice-ui/package.json +++ b/packages/merchant-backoffice-ui/package.json @@ -76,6 +76,6 @@ "sass": "1.56.1", "source-map-support": "^0.5.21", "typedoc": "^0.20.36", - "typescript": "4.8.4" + "typescript": "4.9.4" } } diff --git a/packages/pogen/package.json b/packages/pogen/package.json index 11033c5de..6bb3ac7a8 100644 --- a/packages/pogen/package.json +++ b/packages/pogen/package.json @@ -12,7 +12,7 @@ }, "devDependencies": { "po2json": "^0.4.5", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "@types/node": "^18.11.17", diff --git a/packages/taler-harness/package.json b/packages/taler-harness/package.json index 520df530a..28ea93830 100644 --- a/packages/taler-harness/package.json +++ b/packages/taler-harness/package.json @@ -31,10 +31,10 @@ ], "devDependencies": { "@types/node": "^18.11.17", + "esbuild": "^0.15.13", "prettier": "^2.5.1", "rimraf": "^3.0.2", - "typescript": "^4.8.4", - "esbuild": "^0.15.13" + "typescript": "^4.9.4" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json index 15197c086..005d66123 100644 --- a/packages/taler-util/package.json +++ b/packages/taler-util/package.json @@ -12,6 +12,15 @@ "node": "./lib/index.node.js", "browser": "./lib/index.browser.js", "default": "./lib/index.js" + }, + "./twrpc": { + "default": "./lib/twrpc.js" + } + }, + "imports": { + "#twrpc-impl": { + "node": "./lib/twrpc-impl.node.js", + "default": "./lib/twrpc-impl.missing.js" } }, "scripts": { @@ -27,7 +36,7 @@ "esbuild": "^0.14.21", "prettier": "^2.5.1", "rimraf": "^3.0.2", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "big-integer": "^1.6.51", diff --git a/packages/taler-util/tsconfig.json b/packages/taler-util/tsconfig.json index cbf393f5a..34f35d253 100644 --- a/packages/taler-util/tsconfig.json +++ b/packages/taler-util/tsconfig.json @@ -4,11 +4,11 @@ "composite": true, "declaration": true, "declarationMap": false, - "target": "ES6", - "module": "ESNext", - "moduleResolution": "Node16", + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "node16", "sourceMap": true, - "lib": ["es6"], + "lib": ["ES2020"], "types": ["node"], "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, diff --git a/packages/taler-wallet-cli/package.json b/packages/taler-wallet-cli/package.json index 1e0586afd..2caf3487f 100644 --- a/packages/taler-wallet-cli/package.json +++ b/packages/taler-wallet-cli/package.json @@ -42,7 +42,7 @@ "rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-terser": "^7.0.2", "typedoc": "^0.23.16", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "@gnu-taler/taler-util": "workspace:*", diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index 14000aefd..67d0e3784 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -24,7 +24,6 @@ import { clk, codecForList, codecForString, - CoreApiMessageEnvelope, CoreApiRequestEnvelope, CoreApiResponse, decodeCrock, @@ -45,7 +44,6 @@ import { openPromise, TalerCryptoInterface, TalerError, - WalletCoreResponseType, } from "@gnu-taler/taler-wallet-core"; import { CryptoDispatcher, @@ -64,7 +62,11 @@ import { } from "@gnu-taler/taler-wallet-core"; import fs from "fs"; import os from "os"; -import { connectRpc, JsonMessage, runRpcServer } from "./rpc.js"; +import { + connectRpc, + JsonMessage, + runRpcServer, +} from "@gnu-taler/taler-util/twrpc"; // This module also serves as the entry point for the crypto // thread worker, and thus must expose these two handlers. diff --git a/packages/taler-wallet-cli/src/rpc.ts b/packages/taler-wallet-cli/src/rpc.ts deleted file mode 100644 index 8070b96c5..000000000 --- a/packages/taler-wallet-cli/src/rpc.ts +++ /dev/null @@ -1,266 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2023 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see - */ - -/** - * Implementation for the wallet-core IPC protocol. - * - * Currently the protcol is completely unstable and only used internally - * by the wallet for testing purposes. - */ - -/** - * Imports. - */ -import * as net from "node:net"; -import * as fs from "node:fs"; -import { bytesToString, Logger, typedArrayConcat } from "@gnu-taler/taler-util"; - -const logger = new Logger("rpc.ts"); - -export type JsonMessage = - | string - | number - | boolean - | null - | JsonMessage[] - | { [key: string]: JsonMessage }; - -export interface RpcServerClientHandlers { - onMessage(msg: JsonMessage): void; - onDisconnect(): void; -} - -export interface RpcServerClient { - sendResponse(message: JsonMessage): void; -} - -export interface RpcServerArgs { - socketFilename: string; - onConnect(client: RpcServerClient): RpcServerClientHandlers; -} - -export interface RpcClientServerConnection { - sendMessage(m: JsonMessage): void; - close(): void; -} - -export interface RpcConnectArgs { - socketFilename: string; - onEstablished(connection: RpcClientServerConnection): { - result: T; - onDisconnect(): void; - onMessage(m: JsonMessage): void; - }; -} - -export interface ReadLinewiseArgs { - onLine(lineData: Uint8Array): void; - sock: net.Socket; -} - -function readStreamLinewise(args: ReadLinewiseArgs): void { - let chunks: Uint8Array[] = []; - args.sock.on("data", (buf: Uint8Array) => { - logger.info(`received ${buf.length} bytes`); - // Process all newlines in the newly received buffer - while (1) { - const newlineIdx = buf.indexOf("\n".charCodeAt(0)); - if (newlineIdx >= 0) { - let left = buf.subarray(0, newlineIdx + 1); - let right = buf.subarray(newlineIdx + 1); - chunks.push(left); - const line = typedArrayConcat(chunks); - args.onLine(line); - chunks = []; - buf = right; - } else { - chunks.push(buf); - break; - } - } - }); -} - -export async function connectRpc(args: RpcConnectArgs): Promise { - let sockFilename = args.socketFilename; - return new Promise((resolve, reject) => { - const client = net.createConnection(sockFilename); - client.on("connect", () => { - let parsingBody: string | undefined = undefined; - let bodyChunks: string[] = []; - - logger.info("connected!"); - client.write("%hello-from-client\n"); - const res = args.onEstablished({ - sendMessage(m) { - client.write("%request\n"); - client.write(JSON.stringify(m)); - client.write("\n"); - client.write("%end\n"); - }, - close() { - client.destroy(); - }, - }); - readStreamLinewise({ - sock: client, - onLine(line) { - const lineStr = bytesToString(line); - logger.info(`got line from server: ${lineStr}`); - // Are we currently parsing the body of a request? - if (!parsingBody) { - const strippedLine = lineStr.trim(); - if (strippedLine == "%message") { - logger.info("got message start"); - parsingBody = "message"; - } else if (strippedLine == "%hello-from-server") { - logger.info("got hello from server"); - } else if (strippedLine.startsWith("%error:")) { - logger.info("got error from server, disconnecting"); - client.end(); - res.onDisconnect(); - } else { - logger.info("got unknown request"); - client.write("%error: invalid message\n"); - client.end(); - } - } else if (parsingBody == "message") { - const strippedLine = lineStr.trim(); - if (strippedLine == "%end") { - logger.info("finished request"); - let req = bodyChunks.join(""); - let reqJson: any = undefined; - try { - reqJson = JSON.parse(req); - } catch (e) { - logger.warn("JSON request was invalid"); - } - if (reqJson !== undefined) { - logger.info(`request: ${req}`); - res.onMessage(reqJson); - } else { - client.write("%error: invalid JSON"); - client.end(); - } - bodyChunks = []; - } else { - bodyChunks.push(lineStr); - } - } else { - logger.info("invalid parser state"); - client.write("%error: internal error\n"); - client.end(); - } - }, - }); - client.on("close", () => { - res.onDisconnect(); - }); - client.on("data", () => {}); - resolve(res.result); - }); - }); -} - -export async function runRpcServer(args: RpcServerArgs): Promise { - let sockFilename = args.socketFilename; - try { - fs.unlinkSync(sockFilename); - } catch (e) { - // Do nothing! - } - return new Promise((resolve, reject) => { - const server = net.createServer((sock) => { - // Are we currently parsing the body of a request? - let parsingBody: string | undefined = undefined; - let bodyChunks: string[] = []; - - logger.info("got new connection"); - sock.write("%hello-from-server\n"); - const handlers = args.onConnect({ - sendResponse(message) { - sock.write("%message\n"); - sock.write(JSON.stringify(message)); - sock.write("\n"); - sock.write("%end\n"); - }, - }); - - sock.on("error", (err) => { - logger.info(`connection error: ${err}`); - }); - - function processLine(line: Uint8Array) { - const lineStr = bytesToString(line); - logger.info(`got line: ${lineStr}`); - if (!parsingBody) { - const strippedLine = lineStr.trim(); - if (strippedLine == "%request") { - logger.info("got request start"); - parsingBody = "request"; - } else if (strippedLine === "%hello-from-client") { - console.log("got hello from client"); - } else if (strippedLine.startsWith("%error:")) { - console.log("got error from client"); - sock.end(); - handlers.onDisconnect(); - } else { - logger.info("got unknown request"); - sock.write("%error: invalid request\n"); - sock.end(); - } - } else if (parsingBody == "request") { - const strippedLine = lineStr.trim(); - if (strippedLine == "%end") { - logger.info("finished request"); - let req = bodyChunks.join(""); - let reqJson: any = undefined; - try { - reqJson = JSON.parse(req); - } catch (e) { - logger.warn("JSON request was invalid"); - } - if (reqJson !== undefined) { - logger.info(`request: ${req}`); - handlers.onMessage(reqJson); - } else { - sock.write("%error: invalid JSON"); - sock.end(); - } - bodyChunks = []; - } else { - bodyChunks.push(lineStr); - } - } else { - logger.info("invalid parser state"); - sock.write("%error: internal error\n"); - sock.end(); - } - } - - readStreamLinewise({ - sock, - onLine: processLine, - }); - - sock.on("close", (hadError: boolean) => { - logger.info(`connection closed, hadError=${hadError}`); - handlers.onDisconnect(); - }); - }); - server.listen("wallet-core.sock"); - }); -} diff --git a/packages/taler-wallet-cli/tsconfig.json b/packages/taler-wallet-cli/tsconfig.json index 447d3f946..100339e43 100644 --- a/packages/taler-wallet-cli/tsconfig.json +++ b/packages/taler-wallet-cli/tsconfig.json @@ -21,7 +21,7 @@ "baseUrl": "./src", "typeRoots": ["./node_modules/@types"] }, - "include": ["src/**/*"], + "include": ["src/**/*", "../taler-util/src/twrpc.ts"], "references": [ { "path": "../taler-wallet-core/" diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json index 24ea22d39..a0047a03f 100644 --- a/packages/taler-wallet-core/package.json +++ b/packages/taler-wallet-core/package.json @@ -56,7 +56,7 @@ "prettier": "^2.5.1", "rimraf": "^3.0.2", "typedoc": "^0.23.16", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "@gnu-taler/idb-bridge": "workspace:*", diff --git a/packages/taler-wallet-embedded/package.json b/packages/taler-wallet-embedded/package.json index e79176210..64fb4d604 100644 --- a/packages/taler-wallet-embedded/package.json +++ b/packages/taler-wallet-embedded/package.json @@ -39,7 +39,7 @@ "rollup": "^2.79.0", "rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-terser": "^7.0.2", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "@gnu-taler/idb-bridge": "workspace:*", diff --git a/packages/web-util/package.json b/packages/web-util/package.json index a4589d4ee..1df2852b0 100644 --- a/packages/web-util/package.json +++ b/packages/web-util/package.json @@ -39,7 +39,7 @@ "rimraf": "^3.0.2", "swr": "1.3.0", "tslib": "^2.4.0", - "typescript": "^4.8.4", + "typescript": "^4.9.4", "ws": "7.4.5" } } \ No newline at end of file -- cgit v1.2.3