diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-07-31 01:33:56 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-07-31 01:33:56 +0200 |
commit | cc4e8ddc85d36f29a7385a7f4eb08c77f46b3af6 (patch) | |
tree | 56b7d5a083c5b64a72d0905ad04616b97986538e /src/headless | |
parent | bcefbd7aab5f33f93d626c6421a1a1218c1a91a2 (diff) |
headless wallet WIP
Diffstat (limited to 'src/headless')
-rw-r--r-- | src/headless/taler-wallet-cli.ts | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts new file mode 100644 index 000000000..c57c3ab00 --- /dev/null +++ b/src/headless/taler-wallet-cli.ts @@ -0,0 +1,233 @@ +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 URI = require("urijs"); + +import querystring = require("querystring"); + +class ConsoleNotifier implements Notifier { + notify(): void { + // nothing to do. + } +} + +class ConsoleBadge implements Badge { + startBusy(): void { + console.log("NOTIFICATION: busy"); + } + stopBusy(): void { + console.log("NOTIFICATION: busy end"); + } + showNotification(): void { + console.log("NOTIFICATION: show"); + } + clearNotification(): void { + console.log("NOTIFICATION: cleared"); + } +} + +export class NodeHttpLib implements HttpRequestLibrary { + async get(url: string): Promise<import("../http").HttpResponse> { + console.log("making GET request to", url); + const resp = await Axios({ + method: "get", + url: url, + responseType: "json", + }); + console.log("got response", resp.data); + console.log("resp type", typeof resp.data); + return { + responseJson: resp.data, + status: resp.status, + }; + } + + async postJson( + url: string, + body: any, + ): Promise<import("../http").HttpResponse> { + console.log("making POST request to", url); + const resp = await Axios({ + method: "post", + url: url, + responseType: "json", + data: body, + }); + console.log("got response", resp.data); + console.log("resp type", typeof resp.data); + return { + responseJson: resp.data, + status: resp.status, + }; + } + + async postForm( + url: string, + form: any, + ): Promise<import("../http").HttpResponse> { + console.log("making POST request to", url); + const resp = await Axios({ + method: "post", + url: url, + data: querystring.stringify(form), + responseType: "json", + }); + console.log("got response", resp.data); + 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<BankUser> { + 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, + }, + }); + + if (resp.status != 200) { + throw Error("failed to create bank reserve"); + } +} + +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); + + const reserveResponse = await myWallet.createReserve({ + amount: amounts.parseOrThrow("TESTKUDOS:10.0"), + exchange: exchangeBaseUrl, + }); + + const bankUser = await registerBankUser(bankBaseUrl, myHttpLib); + + console.log("bank user", bankUser); + + const exchangePaytoUri = await myWallet.getExchangePaytoUri( + "https://exchange.test.taler.net/", + ["x-taler-bank"], + ); + + await createBankReserve( + bankBaseUrl, + bankUser, + "TESTKUDOS:10.0", + reserveResponse.reservePub, + exchangePaytoUri, + myHttpLib, + ); + + await myWallet.confirmReserve({ reservePub: reserveResponse.reservePub }); + + //await myWallet.waitForReserveDrained(reserveResponse.reservePub); + + //myWallet.clearNotification(); + + //myWallet.stop(); + + const dbContents = await exportDb(myDb); + + console.log("db:", JSON.stringify(dbContents, null, 2)); +} + +main().catch(err => { + console.error("Failed with exception:"); + console.error(err); +}); |