implement manual withdrawal
This commit is contained in:
parent
c60b10ac82
commit
3903513913
@ -34,6 +34,7 @@ import { setDangerousTimetravel } from "../util/time";
|
|||||||
import { makeCodecForList, codecForString } from "../util/codec";
|
import { makeCodecForList, codecForString } from "../util/codec";
|
||||||
import { NodeHttpLib } from "./NodeHttpLib";
|
import { NodeHttpLib } from "./NodeHttpLib";
|
||||||
import * as nacl from "../crypto/primitives/nacl-fast";
|
import * as nacl from "../crypto/primitives/nacl-fast";
|
||||||
|
import { addPaytoQueryParams } from "../util/payto";
|
||||||
|
|
||||||
const logger = new Logger("taler-wallet-cli.ts");
|
const logger = new Logger("taler-wallet-cli.ts");
|
||||||
|
|
||||||
@ -367,6 +368,42 @@ advancedCli
|
|||||||
fs.writeFileSync(1, decodeCrock(enc.trim()));
|
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", {
|
const reservesCli = advancedCli.subcommand("reserves", "reserves", {
|
||||||
help: "Manage reserves.",
|
help: "Manage reserves.",
|
||||||
});
|
});
|
||||||
|
@ -20,13 +20,26 @@ interface PaytoUri {
|
|||||||
params: { [name: string]: string };
|
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 {
|
export function parsePaytoUri(s: string): PaytoUri | undefined {
|
||||||
const pfx = "payto://";
|
if (!s.startsWith(paytoPfx)) {
|
||||||
if (!s.startsWith(pfx)) {
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [acct, search] = s.slice(pfx.length).split("?");
|
const [acct, search] = s.slice(paytoPfx.length).split("?");
|
||||||
|
|
||||||
const firstSlashPos = acct.indexOf("/");
|
const firstSlashPos = acct.indexOf("/");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user