refactoring; make wallet follow new bank protocol
This commit is contained in:
parent
47f2084706
commit
164d5f20c3
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import {AmountJson} from "./wallet";
|
||||
import {AmountJson} from "./types";
|
||||
import * as EmscWrapper from "../emscripten/emsc";
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,13 @@
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import {AmountJson} from "./wallet/wallet";
|
||||
|
||||
/**
|
||||
* Smaller helper functions that do not depend
|
||||
* on the emscripten machinery.
|
||||
*/
|
||||
|
||||
import {AmountJson} from "./types";
|
||||
|
||||
export function substituteFulfillmentUrl(url: string, vars) {
|
||||
url = url.replace("${H_contract}", vars.H_contract);
|
||||
@ -22,7 +28,38 @@ export function substituteFulfillmentUrl(url: string, vars) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
export function amountToPretty(amount: AmountJson): string {
|
||||
let x = amount.value + amount.fraction / 1e6;
|
||||
return `${x} ${amount.currency}`;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Canonicalize a base url, typically for the mint.
|
||||
*
|
||||
* See http://api.taler.net/wallet.html#general
|
||||
*/
|
||||
export function canonicalizeBaseUrl(url) {
|
||||
let x = new URI(url);
|
||||
if (!x.protocol()) {
|
||||
x.protocol("https");
|
||||
}
|
||||
x.path(x.path() + "/").normalizePath();
|
||||
x.fragment();
|
||||
x.query();
|
||||
return x.href()
|
||||
}
|
||||
|
||||
|
||||
export function parsePrettyAmount(pretty: string): AmountJson {
|
||||
const res = /([0-9]+)(.[0-9]+)?\s*(\w+)/.exec(pretty);
|
||||
if (!res) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
value: parseInt(res[1], 10),
|
||||
fraction: res[2] ? (parseFloat(`0.${res[2]}`) * 1e-6) : 0,
|
||||
currency: res[3]
|
||||
}
|
||||
}
|
56
extension/lib/wallet/types.ts
Normal file
56
extension/lib/wallet/types.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2015 GNUnet e.V.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Common types that are used by Taler.
|
||||
*
|
||||
* Note most types are defined in wallet.ts, types that
|
||||
* are defined in types.ts are intended to be used by components
|
||||
* that do not depend on the whole wallet implementation (which depends on
|
||||
* emscripten).
|
||||
*/
|
||||
|
||||
import {Checkable} from "./checkable";
|
||||
|
||||
@Checkable.Class
|
||||
export class AmountJson {
|
||||
@Checkable.Number
|
||||
value: number;
|
||||
|
||||
@Checkable.Number
|
||||
fraction: number;
|
||||
|
||||
@Checkable.String
|
||||
currency: string;
|
||||
|
||||
static checked: (obj: any) => AmountJson;
|
||||
}
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class CreateReserveResponse {
|
||||
/**
|
||||
* Mint URL where the bank should create the reserve.
|
||||
* The URL is canonicalized in the response.
|
||||
*/
|
||||
@Checkable.String
|
||||
mint: string;
|
||||
|
||||
@Checkable.String
|
||||
reservePub: string;
|
||||
|
||||
static checked: (obj: any) => CreateReserveResponse;
|
||||
}
|
@ -22,9 +22,11 @@
|
||||
*/
|
||||
|
||||
import * as native from "./emscriptif";
|
||||
import {AmountJson, CreateReserveResponse} from "./types";
|
||||
import {HttpResponse, RequestException} from "./http";
|
||||
import {Query} from "./query";
|
||||
import {Checkable} from "./checkable";
|
||||
import {canonicalizeBaseUrl} from "./helpers";
|
||||
|
||||
"use strict";
|
||||
|
||||
@ -73,21 +75,6 @@ export interface Coin {
|
||||
}
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class AmountJson {
|
||||
@Checkable.Number
|
||||
value: number;
|
||||
|
||||
@Checkable.Number
|
||||
fraction: number;
|
||||
|
||||
@Checkable.String
|
||||
currency: string;
|
||||
|
||||
static checked: (obj: any) => AmountJson;
|
||||
}
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class CreateReserveRequest {
|
||||
/**
|
||||
@ -106,22 +93,6 @@ export class CreateReserveRequest {
|
||||
}
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class CreateReserveResponse {
|
||||
/**
|
||||
* Mint URL where the bank should create the reserve.
|
||||
* The URL is canonicalized in the response.
|
||||
*/
|
||||
@Checkable.String
|
||||
mint: string;
|
||||
|
||||
@Checkable.String
|
||||
reservePub: string;
|
||||
|
||||
static checked: (obj: any) => CreateReserveResponse;
|
||||
}
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class ConfirmReserveRequest {
|
||||
/**
|
||||
@ -270,34 +241,6 @@ function isWithdrawableDenom(d: Denomination) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See http://api.taler.net/wallet.html#general
|
||||
*/
|
||||
function canonicalizeBaseUrl(url) {
|
||||
let x = new URI(url);
|
||||
if (!x.protocol()) {
|
||||
x.protocol("https");
|
||||
}
|
||||
x.path(x.path() + "/").normalizePath();
|
||||
x.fragment();
|
||||
x.query();
|
||||
return x.href()
|
||||
}
|
||||
|
||||
|
||||
function parsePrettyAmount(pretty: string): AmountJson {
|
||||
const res = /([0-9]+)(.[0-9]+)?\s*(\w+)/.exec(pretty);
|
||||
if (!res) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
value: parseInt(res[1], 10),
|
||||
fraction: res[2] ? (parseFloat(`0.${res[2]}`) * 1e-6) : 0,
|
||||
currency: res[3]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface HttpRequestLibrary {
|
||||
req(method: string,
|
||||
url: string|uri.URI,
|
||||
@ -619,7 +562,7 @@ export class Wallet {
|
||||
reservePub: reserveRecord.reserve_pub,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return Query(this.db)
|
||||
.put("reserves", reserveRecord)
|
||||
.put("history", historyEntry)
|
||||
|
@ -13,11 +13,11 @@
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
System.register(["../lib/web-common"], function(exports_1, context_1) {
|
||||
System.register(["../lib/wallet/helpers"], function(exports_1, context_1) {
|
||||
/// <reference path="../lib/decl/handlebars/handlebars.d.ts" />
|
||||
"use strict";
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
var web_common_1;
|
||||
var helpers_1;
|
||||
function prettyAmount(amount) {
|
||||
var v = amount.value + amount.fraction / 1e6;
|
||||
return v.toFixed(2) + " " + amount.currency;
|
||||
@ -55,15 +55,15 @@ System.register(["../lib/web-common"], function(exports_1, context_1) {
|
||||
}
|
||||
var c = d.offer.contract;
|
||||
console.log("contract", c);
|
||||
document.location.href = web_common_1.substituteFulfillmentUrl(c.fulfillment_url, offer);
|
||||
document.location.href = helpers_1.substituteFulfillmentUrl(c.fulfillment_url, offer);
|
||||
});
|
||||
}
|
||||
}
|
||||
exports_1("main", main);
|
||||
return {
|
||||
setters:[
|
||||
function (web_common_1_1) {
|
||||
web_common_1 = web_common_1_1;
|
||||
function (helpers_1_1) {
|
||||
helpers_1 = helpers_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
/// <reference path="../lib/decl/handlebars/handlebars.d.ts" />
|
||||
"use strict";
|
||||
|
||||
import {substituteFulfillmentUrl} from "../lib/web-common";
|
||||
import {substituteFulfillmentUrl} from "../lib/wallet/helpers";
|
||||
|
||||
declare var m: any;
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
<head>
|
||||
<title>Taler Wallet: Select Taler Provider</title>
|
||||
<script src="../lib/vendor/URI.js"></script>
|
||||
<script src="../lib/i18n.js"></script>
|
||||
<script src="../lib/vendor/mithril.js"></script>
|
||||
<script src="../lib/vendor/system-csp-production.src.js"></script>
|
||||
<script src="../lib/module-trampoline.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../style/wallet.css">
|
||||
@ -22,27 +24,7 @@
|
||||
<section id="main">
|
||||
|
||||
<article>
|
||||
<p>
|
||||
You asked to withdraw <span id="show-amount">(loading...)</span> from your
|
||||
bank account.
|
||||
</p>
|
||||
<p>
|
||||
Please specify the base URL of the Taler mint you want to use. The Taler
|
||||
mint will process the payments, possibly for a fee. The mint underwrites
|
||||
electronic coins and will hold matching funds in reserve in its bank
|
||||
account. Mints are expected to be regularly audited by a trusted party to
|
||||
ensure that they have sufficient reserves to cover all outstanding
|
||||
obligations.
|
||||
</p>
|
||||
|
||||
<div class="formish">
|
||||
<div class="form-row">
|
||||
<label for="mint-url">Mint URL</label>
|
||||
<input class="url" id="mint-url" type="text"
|
||||
value="http://mint.demo.taler.net/"/>
|
||||
</div>
|
||||
<button id="confirm">Confirm Mint Selection</button>
|
||||
</div>
|
||||
<div id="mint-selection"></div>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
@ -13,69 +13,176 @@
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
System.register(["../lib/web-common", "../lib/wallet/wallet"], function(exports_1, context_1) {
|
||||
System.register(["../lib/wallet/helpers", "../lib/wallet/types"], function(exports_1, context_1) {
|
||||
"use strict";
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
var web_common_1, wallet_1;
|
||||
var helpers_1, types_1;
|
||||
var DelayTimer, Controller;
|
||||
function main() {
|
||||
function updateAmount() {
|
||||
var showAmount = document.getElementById("show-amount");
|
||||
console.log("Query is " + JSON.stringify(query));
|
||||
var amount = wallet_1.AmountJson.checked(JSON.parse(query.amount));
|
||||
showAmount.textContent = web_common_1.amountToPretty(amount);
|
||||
}
|
||||
var url = URI(document.location.href);
|
||||
var query = URI.parseQuery(url.query());
|
||||
updateAmount();
|
||||
document.getElementById("confirm").addEventListener("click", function (e) {
|
||||
var d = {
|
||||
mint: document.getElementById('mint-url').value,
|
||||
amount: JSON.parse(query.amount)
|
||||
};
|
||||
if (!d.mint) {
|
||||
// FIXME: indicate error instead!
|
||||
throw Error("mint missing");
|
||||
}
|
||||
if (!d.amount) {
|
||||
// FIXME: indicate error instead!
|
||||
throw Error("amount missing");
|
||||
}
|
||||
var cb = function (rawResp) {
|
||||
if (!rawResp) {
|
||||
throw Error("empty response");
|
||||
}
|
||||
if (!rawResp.error) {
|
||||
var resp = wallet_1.CreateReserveResponse.checked(rawResp);
|
||||
var q = {
|
||||
mint: resp.mint,
|
||||
reserve_pub: resp.reservePub,
|
||||
amount: query.amount,
|
||||
};
|
||||
var url_1 = URI(query.callback_url).addQuery(q);
|
||||
if (!url_1.is("absolute")) {
|
||||
throw Error("callback url is not absolute");
|
||||
var amount = types_1.AmountJson.checked(JSON.parse(query.amount));
|
||||
var callback_url = query.callback_url;
|
||||
var MintSelection = {
|
||||
controller: function () { return new Controller(); },
|
||||
view: function (ctrl) {
|
||||
var controls = [];
|
||||
var mx = function () {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i - 0] = arguments[_i];
|
||||
}
|
||||
document.location.href = url_1.href();
|
||||
return controls.push(m.apply(void 0, args));
|
||||
};
|
||||
mx("p", (_a = ["The bank wants to create a reserve over ", "."], _a.raw = ["The bank wants to create a reserve over ", "."], i18n(_a, helpers_1.amountToPretty(amount))));
|
||||
mx("input.url", {
|
||||
type: "text",
|
||||
spellcheck: false,
|
||||
oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)),
|
||||
});
|
||||
if (ctrl.isValidMint) {
|
||||
mx("button", {
|
||||
onclick: function () { return ctrl.confirmReserve(ctrl.url, amount, callback_url); }
|
||||
}, "Confirm mint selection");
|
||||
}
|
||||
else {
|
||||
document.body.innerHTML =
|
||||
"Oops, something went wrong. It looks like the bank could not\n transfer funds to the mint. Please go back to your bank's website\n to check what happened.";
|
||||
if (ctrl.errorString) {
|
||||
mx("p", ctrl.errorString);
|
||||
}
|
||||
};
|
||||
chrome.runtime.sendMessage({ type: 'create-reserve', detail: d }, cb);
|
||||
});
|
||||
return m("div", controls);
|
||||
var _a;
|
||||
}
|
||||
};
|
||||
m.mount(document.getElementById("mint-selection"), MintSelection);
|
||||
}
|
||||
exports_1("main", main);
|
||||
return {
|
||||
setters:[
|
||||
function (web_common_1_1) {
|
||||
web_common_1 = web_common_1_1;
|
||||
function (helpers_1_1) {
|
||||
helpers_1 = helpers_1_1;
|
||||
},
|
||||
function (wallet_1_1) {
|
||||
wallet_1 = wallet_1_1;
|
||||
function (types_1_1) {
|
||||
types_1 = types_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
"use strict";
|
||||
/**
|
||||
* Execute something after a delay, with the possibility
|
||||
* to reset the delay.
|
||||
*/
|
||||
DelayTimer = (function () {
|
||||
function DelayTimer(ms, f) {
|
||||
this.timerId = null;
|
||||
this.f = f;
|
||||
this.ms = ms;
|
||||
}
|
||||
DelayTimer.prototype.bump = function () {
|
||||
var _this = this;
|
||||
if (this.timerId !== null) {
|
||||
window.clearTimeout(this.timerId);
|
||||
}
|
||||
var handler = function () {
|
||||
_this.f();
|
||||
};
|
||||
this.timerId = window.setTimeout(handler, this.ms);
|
||||
};
|
||||
return DelayTimer;
|
||||
}());
|
||||
Controller = (function () {
|
||||
function Controller() {
|
||||
var _this = this;
|
||||
this.url = null;
|
||||
this.errorString = null;
|
||||
this.isValidMint = false;
|
||||
this.update();
|
||||
this.timer = new DelayTimer(800, function () { return _this.update(); });
|
||||
}
|
||||
Controller.prototype.update = function () {
|
||||
var _this = this;
|
||||
var doUpdate = function () {
|
||||
if (!_this.url) {
|
||||
_this.errorString = (_a = ["Please enter a URL"], _a.raw = ["Please enter a URL"], i18n(_a));
|
||||
return;
|
||||
}
|
||||
_this.errorString = null;
|
||||
var parsedUrl = URI(_this.url);
|
||||
if (parsedUrl.is("relative")) {
|
||||
_this.errorString = (_b = ["The URL you've entered is not valid (must be absolute)"], _b.raw = ["The URL you've entered is not valid (must be absolute)"], i18n(_b));
|
||||
return;
|
||||
}
|
||||
var keysUrl = URI("/keys").absoluteTo(helpers_1.canonicalizeBaseUrl(_this.url));
|
||||
console.log("requesting keys from '" + keysUrl + "'");
|
||||
_this.request = new XMLHttpRequest();
|
||||
_this.request.onreadystatechange = function () {
|
||||
if (_this.request.readyState == XMLHttpRequest.DONE) {
|
||||
switch (_this.request.status) {
|
||||
case 200:
|
||||
_this.isValidMint = true;
|
||||
break;
|
||||
case 0:
|
||||
_this.errorString = "unknown request error";
|
||||
break;
|
||||
default:
|
||||
_this.errorString = "request failed with status " + _this.request.status;
|
||||
break;
|
||||
}
|
||||
m.redraw();
|
||||
}
|
||||
};
|
||||
_this.request.open("get", keysUrl.href());
|
||||
_this.request.send();
|
||||
var _a, _b;
|
||||
};
|
||||
doUpdate();
|
||||
m.redraw();
|
||||
console.log("got update");
|
||||
};
|
||||
Controller.prototype.reset = function () {
|
||||
this.isValidMint = false;
|
||||
this.errorString = null;
|
||||
if (this.request) {
|
||||
this.request.abort();
|
||||
this.request = null;
|
||||
}
|
||||
m.redraw();
|
||||
};
|
||||
Controller.prototype.confirmReserve = function (mint, amount, callback_url) {
|
||||
var _this = this;
|
||||
var d = { mint: mint, amount: amount };
|
||||
var cb = function (rawResp) {
|
||||
if (!rawResp) {
|
||||
throw Error("empty response");
|
||||
}
|
||||
if (!rawResp.error) {
|
||||
var resp = types_1.CreateReserveResponse.checked(rawResp);
|
||||
var q = {
|
||||
mint: resp.mint,
|
||||
reserve_pub: resp.reservePub,
|
||||
amount_value: amount.value,
|
||||
amount_fraction: amount.fraction,
|
||||
amount_currency: amount.currency,
|
||||
};
|
||||
var url = URI(callback_url).addQuery(q);
|
||||
if (!url.is("absolute")) {
|
||||
throw Error("callback url is not absolute");
|
||||
}
|
||||
console.log("going to", url.href());
|
||||
document.location.href = url.href();
|
||||
}
|
||||
else {
|
||||
_this.reset();
|
||||
_this.errorString = ("Oops, something went wrong." +
|
||||
("The wallet responded with error status (" + rawResp.error + ")."));
|
||||
}
|
||||
};
|
||||
chrome.runtime.sendMessage({ type: 'create-reserve', detail: d }, cb);
|
||||
};
|
||||
Controller.prototype.onUrlChanged = function (url) {
|
||||
this.reset();
|
||||
this.url = url;
|
||||
this.timer.bump();
|
||||
};
|
||||
return Controller;
|
||||
}());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -14,40 +14,107 @@
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import {amountToPretty} from "../lib/web-common";
|
||||
import {AmountJson, CreateReserveResponse} from "../lib/wallet/wallet";
|
||||
import {amountToPretty, canonicalizeBaseUrl} from "../lib/wallet/helpers";
|
||||
import {AmountJson, CreateReserveResponse} from "../lib/wallet/types";
|
||||
|
||||
"use strict";
|
||||
|
||||
declare var m: any;
|
||||
|
||||
export function main() {
|
||||
function updateAmount() {
|
||||
let showAmount = document.getElementById("show-amount");
|
||||
console.log("Query is " + JSON.stringify(query));
|
||||
let amount = AmountJson.checked(JSON.parse(query.amount));
|
||||
showAmount.textContent = amountToPretty(amount);
|
||||
|
||||
/**
|
||||
* Execute something after a delay, with the possibility
|
||||
* to reset the delay.
|
||||
*/
|
||||
class DelayTimer {
|
||||
ms: number;
|
||||
f;
|
||||
timerId: number = null;
|
||||
|
||||
constructor(ms: number, f) {
|
||||
this.f = f;
|
||||
this.ms = ms;
|
||||
}
|
||||
|
||||
let url = URI(document.location.href);
|
||||
let query: any = URI.parseQuery(url.query());
|
||||
bump() {
|
||||
if (this.timerId !== null) {
|
||||
window.clearTimeout(this.timerId);
|
||||
}
|
||||
const handler = () => {
|
||||
this.f();
|
||||
};
|
||||
this.timerId = window.setTimeout(handler, this.ms);
|
||||
}
|
||||
}
|
||||
|
||||
updateAmount();
|
||||
|
||||
document.getElementById("confirm").addEventListener("click", (e) => {
|
||||
const d = {
|
||||
mint: (document.getElementById('mint-url') as HTMLInputElement).value,
|
||||
amount: JSON.parse(query.amount)
|
||||
class Controller {
|
||||
url = null;
|
||||
errorString = null;
|
||||
isValidMint = false;
|
||||
private timer: DelayTimer;
|
||||
private request: XMLHttpRequest;
|
||||
|
||||
constructor() {
|
||||
this.update();
|
||||
this.timer = new DelayTimer(800, () => this.update());
|
||||
}
|
||||
|
||||
update() {
|
||||
const doUpdate = () => {
|
||||
if (!this.url) {
|
||||
this.errorString = i18n`Please enter a URL`;
|
||||
return;
|
||||
}
|
||||
this.errorString = null;
|
||||
let parsedUrl = URI(this.url);
|
||||
if (parsedUrl.is("relative")) {
|
||||
this.errorString = i18n`The URL you've entered is not valid (must be absolute)`;
|
||||
return;
|
||||
}
|
||||
|
||||
const keysUrl = URI("/keys").absoluteTo(canonicalizeBaseUrl(this.url));
|
||||
|
||||
console.log(`requesting keys from '${keysUrl}'`);
|
||||
|
||||
this.request = new XMLHttpRequest();
|
||||
this.request.onreadystatechange = () => {
|
||||
if (this.request.readyState == XMLHttpRequest.DONE) {
|
||||
switch (this.request.status) {
|
||||
case 200:
|
||||
this.isValidMint = true;
|
||||
break;
|
||||
case 0:
|
||||
this.errorString = `unknown request error`;
|
||||
break;
|
||||
default:
|
||||
this.errorString = `request failed with status ${this.request.status}`;
|
||||
break;
|
||||
}
|
||||
m.redraw();
|
||||
}
|
||||
};
|
||||
this.request.open("get", keysUrl.href());
|
||||
this.request.send();
|
||||
};
|
||||
|
||||
if (!d.mint) {
|
||||
// FIXME: indicate error instead!
|
||||
throw Error("mint missing");
|
||||
}
|
||||
doUpdate();
|
||||
m.redraw();
|
||||
console.log("got update");
|
||||
}
|
||||
|
||||
if (!d.amount) {
|
||||
// FIXME: indicate error instead!
|
||||
throw Error("amount missing");
|
||||
reset() {
|
||||
this.isValidMint = false;
|
||||
this.errorString = null;
|
||||
if (this.request) {
|
||||
this.request.abort();
|
||||
this.request = null;
|
||||
}
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
confirmReserve(mint: string, amount: AmountJson, callback_url: string) {
|
||||
const d = {mint, amount};
|
||||
const cb = (rawResp) => {
|
||||
if (!rawResp) {
|
||||
throw Error("empty response");
|
||||
@ -57,20 +124,72 @@ export function main() {
|
||||
let q = {
|
||||
mint: resp.mint,
|
||||
reserve_pub: resp.reservePub,
|
||||
amount: query.amount,
|
||||
amount_value: amount.value,
|
||||
amount_fraction: amount.fraction,
|
||||
amount_currency: amount.currency,
|
||||
};
|
||||
let url = URI(query.callback_url).addQuery(q);
|
||||
let url = URI(callback_url).addQuery(q);
|
||||
if (!url.is("absolute")) {
|
||||
throw Error("callback url is not absolute");
|
||||
}
|
||||
console.log("going to", url.href());
|
||||
document.location.href = url.href();
|
||||
} else {
|
||||
document.body.innerHTML =
|
||||
`Oops, something went wrong. It looks like the bank could not
|
||||
transfer funds to the mint. Please go back to your bank's website
|
||||
to check what happened.`;
|
||||
this.reset();
|
||||
this.errorString = (
|
||||
`Oops, something went wrong.` +
|
||||
`The wallet responded with error status (${rawResp.error}).`);
|
||||
}
|
||||
};
|
||||
chrome.runtime.sendMessage({type: 'create-reserve', detail: d}, cb);
|
||||
});
|
||||
}
|
||||
|
||||
onUrlChanged(url: string) {
|
||||
this.reset();
|
||||
this.url = url;
|
||||
this.timer.bump();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
const url = URI(document.location.href);
|
||||
const query: any = URI.parseQuery(url.query());
|
||||
const amount = AmountJson.checked(JSON.parse(query.amount));
|
||||
const callback_url = query.callback_url;
|
||||
|
||||
var MintSelection = {
|
||||
controller: () => new Controller(),
|
||||
view(ctrl: Controller) {
|
||||
let controls = [];
|
||||
let mx = (...args) => controls.push(m(...args));
|
||||
|
||||
mx("p",
|
||||
i18n`The bank wants to create a reserve over ${amountToPretty(
|
||||
amount)}.`);
|
||||
mx("input.url",
|
||||
{
|
||||
type: "text",
|
||||
spellcheck: false,
|
||||
oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)),
|
||||
});
|
||||
|
||||
if (ctrl.isValidMint) {
|
||||
mx("button", {
|
||||
onclick: () => ctrl.confirmReserve(ctrl.url,
|
||||
amount,
|
||||
callback_url)
|
||||
},
|
||||
"Confirm mint selection");
|
||||
}
|
||||
|
||||
if (ctrl.errorString) {
|
||||
mx("p", ctrl.errorString);
|
||||
}
|
||||
|
||||
return m("div", controls);
|
||||
}
|
||||
};
|
||||
|
||||
m.mount(document.getElementById("mint-selection"), MintSelection);
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import {substituteFulfillmentUrl} from "../lib/web-common";
|
||||
import {substituteFulfillmentUrl} from "../lib/wallet/helpers";
|
||||
|
||||
declare var m: any;
|
||||
declare var i18n: any;
|
||||
|
@ -12,12 +12,13 @@
|
||||
"files": [
|
||||
"lib/i18n.ts",
|
||||
"lib/refs.ts",
|
||||
"lib/web-common.ts",
|
||||
"lib/wallet/checkable.ts",
|
||||
"lib/wallet/db.ts",
|
||||
"lib/wallet/emscriptif.ts",
|
||||
"lib/wallet/helpers.ts",
|
||||
"lib/wallet/http.ts",
|
||||
"lib/wallet/query.ts",
|
||||
"lib/wallet/types.ts",
|
||||
"lib/wallet/wallet.ts",
|
||||
"lib/wallet/wxmessaging.ts",
|
||||
"background/main.ts",
|
||||
|
Loading…
Reference in New Issue
Block a user