From 3263d05ce957a3f81234749eb9eefc0bce7ff645 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 16 Aug 2019 23:29:29 +0200 Subject: [PATCH] version bump / imports --- README | 4 +- package.json | 2 +- packages/idb-bridge/package.json | 2 +- packages/idb-bridge/src/MemoryBackend.test.ts | 1 + packages/idb-bridge/src/util/FakeEvent.ts | 2 +- packages/idb-bridge/src/util/types.ts | 1 + packages/idb-bridge/tsconfig.json | 1 - src/headless/taler-wallet-cli.ts | 367 ++---------------- src/index.ts | 2 +- src/webex/wxBackend.ts | 8 +- tsconfig.json | 6 +- yarn.lock | 32 +- 12 files changed, 79 insertions(+), 349 deletions(-) diff --git a/README b/README index 78c70dc00..ece8c2fba 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ -GNU Taler WebExtension Wallet -============================= +GNU Taler Wallet +================ Cross-browser GNU Taler wallet written for the WebExtensions API. diff --git a/package.json b/package.json index e080cae49..6bdf9c9a5 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@types/urijs": "^1.19.3", "axios": "^0.19.0", "commander": "^2.20.0", - "idb-bridge": "0.0.3", + "idb-bridge": "^0.0.5", "source-map-support": "^0.5.12", "urijs": "^1.18.10" } diff --git a/packages/idb-bridge/package.json b/packages/idb-bridge/package.json index 5816b7172..750c282ec 100644 --- a/packages/idb-bridge/package.json +++ b/packages/idb-bridge/package.json @@ -1,6 +1,6 @@ { "name": "idb-bridge", - "version": "0.0.5", + "version": "0.0.6", "description": "IndexedDB implementation that uses SQLite3 as storage", "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/idb-bridge/src/MemoryBackend.test.ts b/packages/idb-bridge/src/MemoryBackend.test.ts index 7f9c1440d..a48fafb1e 100644 --- a/packages/idb-bridge/src/MemoryBackend.test.ts +++ b/packages/idb-bridge/src/MemoryBackend.test.ts @@ -345,5 +345,6 @@ test("export", async t => { t.deepEqual(exportedData, exportedData2); t.is(exportedData.databases["library"].schema.databaseVersion, 42); + t.is(exportedData2.databases["library"].schema.databaseVersion, 42); t.pass(); }); \ No newline at end of file diff --git a/packages/idb-bridge/src/util/FakeEvent.ts b/packages/idb-bridge/src/util/FakeEvent.ts index bf17f7e72..ae62401c3 100644 --- a/packages/idb-bridge/src/util/FakeEvent.ts +++ b/packages/idb-bridge/src/util/FakeEvent.ts @@ -18,7 +18,7 @@ import FakeEventTarget from "./FakeEventTarget"; import { EventType } from "./types"; -class Event { +export class Event { public eventPath: FakeEventTarget[] = []; public type: EventType; diff --git a/packages/idb-bridge/src/util/types.ts b/packages/idb-bridge/src/util/types.ts index 7aea22ab1..9bf80366d 100644 --- a/packages/idb-bridge/src/util/types.ts +++ b/packages/idb-bridge/src/util/types.ts @@ -19,6 +19,7 @@ import BridgeIDBRequest from "../BridgeIDBRequest"; import BridgeIDBKeyRange from "../BridgeIDBKeyRange"; import BridgeIDBIndex from "../BridgeIDBIndex"; import BridgeIBObjectStore from "../BridgeIDBObjectStore"; +import { Event } from "../util/FakeEvent"; interface EventInCallback extends Event { target: any; diff --git a/packages/idb-bridge/tsconfig.json b/packages/idb-bridge/tsconfig.json index 8baf78ac1..017afdae1 100644 --- a/packages/idb-bridge/tsconfig.json +++ b/packages/idb-bridge/tsconfig.json @@ -10,7 +10,6 @@ "strict": true, "incremental": true, "sourceMap": true, - "typeRoots": ["./node_modules"], "types": [] }, "include": ["src/**/*"] diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts index 49cc608d9..26f4521c5 100644 --- a/src/headless/taler-wallet-cli.ts +++ b/src/headless/taler-wallet-cli.ts @@ -14,347 +14,52 @@ TALER; see the file COPYING. If not, see */ -import { MemoryBackend, BridgeIDBFactory, shimIndexedDB } from "idb-bridge"; -import { Wallet } from "../wallet"; -import { Notifier, Badge } from "../walletTypes"; -import { openTalerDb, exportDb } from "../db"; -import { HttpRequestLibrary } from "../http"; -import * as amounts from "../amounts"; -import Axios from "axios"; +import commander = require("commander"); +import os = require("os"); +import { getDefaultNodeWallet, withdrawTestBalance } from "./helpers"; -import URI = require("urijs"); +const program = new commander.Command(); +program.version("0.0.1"); -import querystring = require("querystring"); -import { CheckPaymentResponse } from "../talerTypes"; -import { SynchronousCryptoWorkerFactory } from "../crypto/synchronousWorker"; +const walletDbPath = os.homedir + "/" + ".talerwalletdb.json"; -const enableTracing = false; - -class ConsoleNotifier implements Notifier { - notify(): void { - // nothing to do. - } -} - -class ConsoleBadge implements Badge { - startBusy(): void { - enableTracing && console.log("NOTIFICATION: busy"); - } - stopBusy(): void { - enableTracing && console.log("NOTIFICATION: busy end"); - } - showNotification(): void { - enableTracing && console.log("NOTIFICATION: show"); - } - clearNotification(): void { - enableTracing && console.log("NOTIFICATION: cleared"); - } -} - -export class NodeHttpLib implements HttpRequestLibrary { - async get(url: string): Promise { - enableTracing && console.log("making GET request to", url); - const resp = await Axios({ - method: "get", - url: url, - responseType: "json", +program + .command("test-withdraw") + .description("withdraw test currency from the test bank") + .action(async () => { + console.log("test-withdraw command called"); + const wallet = await getDefaultNodeWallet({ + persistentStoragePath: walletDbPath, }); - enableTracing && console.log("got response", resp.data); - enableTracing && console.log("resp type", typeof resp.data); - return { - responseJson: resp.data, - status: resp.status, - }; - } - - async postJson( - url: string, - body: any, - ): Promise { - enableTracing && console.log("making POST request to", url); - const resp = await Axios({ - method: "post", - url: url, - responseType: "json", - data: body, - }); - enableTracing && console.log("got response", resp.data); - enableTracing && console.log("resp type", typeof resp.data); - return { - responseJson: resp.data, - status: resp.status, - }; - } - - async postForm( - url: string, - form: any, - ): Promise { - enableTracing && console.log("making POST request to", url); - const resp = await Axios({ - method: "post", - url: url, - data: querystring.stringify(form), - responseType: "json", - }); - enableTracing && console.log("got response", resp.data); - enableTracing && console.log("resp type", typeof resp.data); - return { - responseJson: resp.data, - status: resp.status, - }; - } -} - -interface BankUser { - username: string; - password: string; -} - -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; -} - -async function registerBankUser( - bankBaseUrl: string, - httpLib: HttpRequestLibrary, -): Promise { - const reqUrl = new URI("register").absoluteTo(bankBaseUrl).href(); - const randId = makeId(8); - const bankUser: BankUser = { - username: `testuser-${randId}`, - password: `testpw-${randId}`, - }; - const result = await httpLib.postForm(reqUrl, bankUser); - if (result.status != 200) { - throw Error("could not register bank user"); - } - return bankUser; -} - -async function createBankReserve( - bankBaseUrl: string, - bankUser: BankUser, - amount: string, - reservePub: string, - exchangePaytoUri: string, - httpLib: HttpRequestLibrary, -) { - const reqUrl = new URI("taler/withdraw").absoluteTo(bankBaseUrl).href(); - - const body = { - auth: { type: "basic" }, - username: bankUser, - amount, - reserve_pub: reservePub, - exchange_wire_detail: exchangePaytoUri, - }; - - const resp = await Axios({ - method: "post", - url: reqUrl, - data: body, - responseType: "json", - headers: { - "X-Taler-Bank-Username": bankUser.username, - "X-Taler-Bank-Password": bankUser.password, - }, + await withdrawTestBalance(wallet); + process.exit(0); }); - if (resp.status != 200) { - throw Error("failed to create bank reserve"); - } -} - -class MerchantBackendConnection { - constructor( - public merchantBaseUrl: string, - public merchantInstance: string, - public apiKey: string, - ) {} - - async createOrder( - amount: string, - summary: string, - fulfillmentUrl: string, - ): Promise<{ orderId: string }> { - const reqUrl = new URI("order").absoluteTo(this.merchantBaseUrl).href(); - const orderReq = { - order: { - amount, - summary, - fulfillment_url: fulfillmentUrl, - instance: this.merchantInstance, - }, - }; - const resp = await Axios({ - method: "post", - url: reqUrl, - data: orderReq, - responseType: "json", - headers: { - Authorization: `ApiKey ${this.apiKey}`, - }, +program + .command("balance", undefined, { isDefault: true }) + .description("show wallet balance") + .action(async () => { + console.log("balance command called"); + const wallet = await getDefaultNodeWallet({ + persistentStoragePath: walletDbPath, }); - if (resp.status != 200) { - throw Error("failed to create bank reserve"); - } - const orderId = resp.data.order_id; - if (!orderId) { - throw Error("no order id in response"); - } - return { orderId }; - } - - async checkPayment(orderId: string): Promise { - const reqUrl = new URI("check-payment") - .absoluteTo(this.merchantBaseUrl) - .href(); - const resp = await Axios({ - method: "get", - url: reqUrl, - params: { order_id: orderId, instance: this.merchantInstance }, - responseType: "json", - headers: { - Authorization: `ApiKey ${this.apiKey}`, - }, - }); - if (resp.status != 200) { - throw Error("failed to check payment"); - } - return CheckPaymentResponse.checked(resp.data); - } -} - -export async function main() { - const myNotifier = new ConsoleNotifier(); - - const myBadge = new ConsoleBadge(); - - const myBackend = new MemoryBackend(); - - myBackend.enableTracing = false; - - BridgeIDBFactory.enableTracing = false; - - const myBridgeIdbFactory = new BridgeIDBFactory(myBackend); - const myIdbFactory: IDBFactory = (myBridgeIdbFactory as any) as IDBFactory; - - const myHttpLib = new NodeHttpLib(); - - const myVersionChange = () => { - console.error("version change requested, should not happen"); - throw Error(); - }; - - const myUnsupportedUpgrade = () => { - console.error("unsupported database migration"); - throw Error(); - }; - - shimIndexedDB(myBridgeIdbFactory); - - const exchangeBaseUrl = "https://exchange.test.taler.net/"; - const bankBaseUrl = "https://bank.test.taler.net/"; - - const myDb = await openTalerDb( - myIdbFactory, - myVersionChange, - myUnsupportedUpgrade, - ); - - const myWallet = new Wallet(myDb, myHttpLib, myBadge, myNotifier, new SynchronousCryptoWorkerFactory()); - //const myWallet = new Wallet(myDb, myHttpLib, myBadge, myNotifier, new NodeCryptoWorkerFactory()); - - const reserveResponse = await myWallet.createReserve({ - amount: amounts.parseOrThrow("TESTKUDOS:10.0"), - exchange: exchangeBaseUrl, + const balance = await wallet.getBalances(); + console.log(JSON.stringify(balance, undefined, 2)); + process.exit(0); }); - const bankUser = await registerBankUser(bankBaseUrl, myHttpLib); - - console.log("bank user", bankUser); - - const exchangePaytoUri = await myWallet.getExchangePaytoUri( - "https://exchange.test.taler.net/", - ["x-taler-bank"], +// error on unknown commands +program.on("command:*", function() { + console.error( + "Invalid command: %s\nSee --help for a list of available commands.", + program.args.join(" "), ); + process.exit(1); +}); - await createBankReserve( - bankBaseUrl, - bankUser, - "TESTKUDOS:10.0", - reserveResponse.reservePub, - exchangePaytoUri, - myHttpLib, - ); +program.parse(process.argv); - await myWallet.confirmReserve({ reservePub: reserveResponse.reservePub }); - - await myWallet.processReserve(reserveResponse.reservePub); - - console.log("process reserve returned"); - - const balance = await myWallet.getBalances(); - - console.log(JSON.stringify(balance, null, 2)); - - const myMerchant = new MerchantBackendConnection( - "https://backend.test.taler.net/", - "default", - "sandbox", - ); - - const orderResp = await myMerchant.createOrder( - "TESTKUDOS:5", - "hello world", - "https://example.com/", - ); - - console.log("created order with orderId", orderResp.orderId); - - const paymentStatus = await myMerchant.checkPayment(orderResp.orderId); - - console.log("payment status", paymentStatus); - - const contractUrl = paymentStatus.contract_url; - if (!contractUrl) { - throw Error("no contract URL in payment response"); - } - - const proposalId = await myWallet.downloadProposal(contractUrl); - - console.log("proposal id", proposalId); - - const checkPayResult = await myWallet.checkPay(proposalId); - - console.log("check pay result", checkPayResult); - - const confirmPayResult = await myWallet.confirmPay(proposalId, undefined); - - console.log("confirmPayResult", confirmPayResult); - - const paymentStatus2 = await myMerchant.checkPayment(orderResp.orderId); - - console.log("payment status after wallet payment:", paymentStatus2); - - if (!paymentStatus2.paid) { - throw Error("payment did not succeed"); - } - - myWallet.stop(); -} - - -if (require.main === module) { - main().catch(err => { - console.error("Failed with exception:"); - console.error(err); - }); +if (process.argv.length <= 2) { + console.error("Error: No command given."); + program.help(); } diff --git a/src/index.ts b/src/index.ts index bfd25c6a0..44f030d71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,4 +20,4 @@ export { Wallet } from "./wallet"; -export { main as runIntegrationTest } from "./headless/taler-wallet-cli"; +export { main as runIntegrationTest } from "./headless/taler-wallet-testing"; diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts index 831495359..e7ce39ecf 100644 --- a/src/webex/wxBackend.ts +++ b/src/webex/wxBackend.ts @@ -471,7 +471,7 @@ function setBadgeText(options: chrome.browserAction.BadgeTextDetails) { function waitMs(timeoutMs: number): Promise { return new Promise((resolve, reject) => { - chrome.extension.getBackgroundPage().setTimeout(() => resolve(), timeoutMs); + chrome.extension.getBackgroundPage()!.setTimeout(() => resolve(), timeoutMs); }); } @@ -780,7 +780,7 @@ export async function wxMain() { chrome.tabs.onRemoved.addListener((tabId, changeInfo) => { const tt = tabTimers[tabId] || []; for (const t of tt) { - chrome.extension.getBackgroundPage().clearTimeout(t); + chrome.extension.getBackgroundPage()!.clearTimeout(t); } }); chrome.tabs.onUpdated.addListener((tabId, changeInfo) => { @@ -790,7 +790,7 @@ export async function wxMain() { const timers: number[] = []; const addRun = (dt: number) => { - const id = chrome.extension.getBackgroundPage().setTimeout(run, dt); + const id = chrome.extension.getBackgroundPage()!.setTimeout(run, dt); timers.push(id); }; @@ -827,7 +827,7 @@ export async function wxMain() { tabTimers[tabId] = timers; }); - chrome.extension.getBackgroundPage().setInterval(clearRateLimitCache, 5000); + chrome.extension.getBackgroundPage()!.setInterval(clearRateLimitCache, 5000); reinitWallet(); diff --git a/tsconfig.json b/tsconfig.json index c833ef9a3..3e6a0aa14 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,9 +22,6 @@ "incremental": true }, "files": [ - "decl/chrome/chrome.d.ts", - "decl/jed.d.ts", - "decl/urijs.d.ts", "src/amounts.ts", "src/checkable.ts", "src/crypto/browserWorkerEntry.ts", @@ -40,7 +37,10 @@ "src/crypto/synchronousWorker.ts", "src/db.ts", "src/dbTypes.ts", + "src/headless/bank.ts", + "src/headless/helpers.ts", "src/headless/taler-wallet-cli.ts", + "src/headless/taler-wallet-testing.ts", "src/helpers-test.ts", "src/helpers.ts", "src/http.ts", diff --git a/yarn.lock b/yarn.lock index c61d6fd2d..01452d3c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -325,6 +325,13 @@ dependencies: arrify "^1.0.1" +"@types/chrome@^0.0.88": + version "0.0.88" + resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.88.tgz#0041a101d69f78008910927c5b3299a00d8660db" + integrity sha512-JBsIrBZ2adJhlXvJ+1j0xLbcfOfwee/WAg7Lp2NE+Wf3m0vXMJFWv/PPjqNk5ZUXDeY/qDxPHe+PUjxnl8HWFg== + dependencies: + "@types/filesystem" "*" + "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" @@ -335,6 +342,18 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/filesystem@*": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.29.tgz#ee3748eb5be140dcf980c3bd35f11aec5f7a3748" + integrity sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.28" + resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3" + integrity sha1-wFTor02d11205jq8dviFFocU1LM= + "@types/fs-extra@^5.0.3": version "5.0.5" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.5.tgz#080d90a792f3fa2c5559eb44bd8ef840aae9104b" @@ -423,6 +442,11 @@ "@types/glob" "*" "@types/node" "*" +"@types/urijs@^1.19.3": + version "1.19.3" + resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.3.tgz#ed90d38baf3eff1627544ad6ed3bcdeb79ef3533" + integrity sha512-L5tP2dEIV+OMVEVRhf8PCFMNMyO5ZBodrXpEqnGczky60lcv8l5Kl9Yi4J1yxhSVfHUe+Pr2nXJfDM+rUYNs3w== + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -3216,10 +3240,10 @@ iconv-lite@^0.4.4, iconv-lite@~0.4.13: dependencies: safer-buffer ">= 2.1.2 < 3" -idb-bridge@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/idb-bridge/-/idb-bridge-0.0.2.tgz#daa46d75060bd6a116b26155c314446bea355570" - integrity sha512-PEfZmdbIQUV4vxJRSSXhan7niclJDJGPGUSJ2WlHCYCgdFK6n25UD8z/lsLoqWKfcp+xPuL+9MI+h9Ql8XFzkw== +idb-bridge@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/idb-bridge/-/idb-bridge-0.0.5.tgz#fb26ddc3183229ae54f31c4b8709312b57735fed" + integrity sha512-ya5Hf5R6S0Pimeg6+8iL4MYR7duwywtZ2Dxm/HIdY4JIee9cITfuNIRRXOEQhxUxZdbYQeqjNYIRnK5bAQSUUw== ieee754@^1.1.4: version "1.1.13"