summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-06-21 18:19:27 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-06-21 18:19:27 +0530
commit39035139130925bf596175ad8a3419a4cea401a8 (patch)
tree0181b085abd76d60279ed709e53d07d413dd62a3
parentc60b10ac827b564f999c401c013b55e123de3b5f (diff)
downloadwallet-core-39035139130925bf596175ad8a3419a4cea401a8.tar.gz
wallet-core-39035139130925bf596175ad8a3419a4cea401a8.tar.bz2
wallet-core-39035139130925bf596175ad8a3419a4cea401a8.zip
implement manual withdrawal
-rw-r--r--src/headless/taler-wallet-cli.ts37
-rw-r--r--src/util/payto.ts19
2 files changed, 53 insertions, 3 deletions
diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts
index b45b0eae8..839ee9992 100644
--- a/src/headless/taler-wallet-cli.ts
+++ b/src/headless/taler-wallet-cli.ts
@@ -34,6 +34,7 @@ import { setDangerousTimetravel } from "../util/time";
import { makeCodecForList, codecForString } from "../util/codec";
import { NodeHttpLib } from "./NodeHttpLib";
import * as nacl from "../crypto/primitives/nacl-fast";
+import { addPaytoQueryParams } from "../util/payto";
const logger = new Logger("taler-wallet-cli.ts");
@@ -367,6 +368,42 @@ advancedCli
fs.writeFileSync(1, decodeCrock(enc.trim()));
});
+
+advancedCli
+.subcommand("withdrawManually", "withdraw-manually", {
+ help: "Withdraw manually from an exchange.",
+})
+.requiredOption("exchange", ["--exchange"], clk.STRING, {
+ help: "Base URL of the exchange.",
+})
+.requiredOption("amount", ["--amount"], clk.STRING, {
+ help: "Amount to withdraw",
+})
+.action(async (args) => {
+ await withWallet(args, async (wallet) => {
+ const exchange = await wallet.updateExchangeFromUrl(args.withdrawManually.exchange);
+ const acct = exchange.wireInfo?.accounts[0];
+ if (!acct) {
+ console.log("exchange has no accounts");
+ return;
+ }
+ const reserve = await wallet.createReserve({
+ amount: Amounts.parseOrThrow(args.withdrawManually.amount),
+ exchangeWire: acct.payto_uri,
+ exchange: exchange.baseUrl,
+ });
+ await wallet.confirmReserve({
+ reservePub: reserve.reservePub,
+ });
+ const completePaytoUri = addPaytoQueryParams(acct.payto_uri, {
+ amount: args.withdrawManually.amount,
+ message: `Taler top-up ${reserve.reservePub}`,
+ });
+ console.log("Created reserve", reserve.reservePub);
+ console.log("Payto URI", completePaytoUri);
+ });
+});
+
const reservesCli = advancedCli.subcommand("reserves", "reserves", {
help: "Manage reserves.",
});
diff --git a/src/util/payto.ts b/src/util/payto.ts
index ac5bc0c7f..0f624de67 100644
--- a/src/util/payto.ts
+++ b/src/util/payto.ts
@@ -20,13 +20,26 @@ interface PaytoUri {
params: { [name: string]: string };
}
+const paytoPfx = "payto://";
+
+/**
+ * Add query parameters to a payto URI
+ */
+export function addPaytoQueryParams(s: string, params: { [name: string]: string }): string {
+ const [acct, search] = s.slice(paytoPfx.length).split("?");
+ const searchParams = new URLSearchParams(search || "");
+ for (let k of Object.keys(params)) {
+ searchParams.set(k, params[k]);
+ }
+ return paytoPfx + acct + "?" + searchParams.toString();
+}
+
export function parsePaytoUri(s: string): PaytoUri | undefined {
- const pfx = "payto://";
- if (!s.startsWith(pfx)) {
+ if (!s.startsWith(paytoPfx)) {
return undefined;
}
- const [acct, search] = s.slice(pfx.length).split("?");
+ const [acct, search] = s.slice(paytoPfx.length).split("?");
const firstSlashPos = acct.indexOf("/");