make wallet independent of chrome/WX api

This commit is contained in:
Florian Dold 2016-01-06 15:58:18 +01:00
parent abf15268ac
commit 5bb1c95ec5
4 changed files with 99 additions and 77 deletions

View File

@ -28,50 +28,51 @@ interface HttpResponse {
} }
function httpReq(method: string, class BrowserHttpLib {
url: string|uri.URI, req(method: string,
options?: any): Promise<HttpResponse> { url: string|uri.URI,
let urlString: string; options?: any): Promise<HttpResponse> {
if (url instanceof URI) { let urlString: string;
urlString = url.href(); if (url instanceof URI) {
} else if (typeof url === "string") { urlString = url.href();
urlString = url; } else if (typeof url === "string") {
urlString = url;
}
return new Promise((resolve, reject) => {
let myRequest = new XMLHttpRequest();
myRequest.open(method, urlString);
if (options && options.req) {
myRequest.send(options.req);
} else {
myRequest.send();
}
myRequest.addEventListener("readystatechange", (e) => {
if (myRequest.readyState == XMLHttpRequest.DONE) {
let resp = {
status: myRequest.status,
responseText: myRequest.responseText
};
resolve(resp);
}
});
});
} }
return new Promise((resolve, reject) => {
let myRequest = new XMLHttpRequest(); get(url: string|uri.URI) {
myRequest.open(method, urlString); return this.req("get", url);
if (options && options.req) { }
myRequest.send(options.req);
} else {
myRequest.send();
}
myRequest.addEventListener("readystatechange", (e) => {
if (myRequest.readyState == XMLHttpRequest.DONE) {
let resp = {
status: myRequest.status,
responseText: myRequest.responseText
};
resolve(resp);
}
});
});
}
postJson(url: string|uri.URI, body) {
function httpGet(url: string|uri.URI) { return this.req("post", url, {req: JSON.stringify(body)});
return httpReq("get", url); }
}
function httpPostJson(url: string|uri.URI, body) { postForm(url: string|uri.URI, form) {
return httpReq("post", url, {req: JSON.stringify(body)}); return this.req("post", url, {req: form});
} }
function httpPostForm(url: string|uri.URI, form) {
return httpReq("post", url, {req: form});
} }

View File

@ -57,48 +57,61 @@ function makeHandlers(wallet) {
amount_str: detail.amount_str amount_str: detail.amount_str
}; };
wallet.confirmReserve(req) wallet.confirmReserve(req)
.then((resp) => { .then((resp) => {
if (resp.success) { if (resp.success) {
resp.backlink = chrome.extension.getURL("pages/reserve-success.html"); resp.backlink = chrome.extension.getURL(
} "pages/reserve-success.html");
sendResponse(resp); }
}); sendResponse(resp);
});
return true; return true;
}, },
["confirm-pay"]: function(db, detail, sendResponse) { ["confirm-pay"]: function(db, detail, sendResponse) {
wallet.confirmPay(detail.offer, detail.merchantPageUrl) wallet.confirmPay(detail.offer, detail.merchantPageUrl)
.then(() => { .then(() => {
sendResponse({success: true}) sendResponse({success: true})
}) })
.catch((e) => { .catch((e) => {
sendResponse({error: e.message}); sendResponse({error: e.message});
}); });
return true; return true;
}, },
["execute-payment"]: function(db, detail, sendResponse) { ["execute-payment"]: function(db, detail, sendResponse) {
wallet.doPayment(detail.H_contract) wallet.doPayment(detail.H_contract)
.then((r) => { .then((r) => {
sendResponse({ sendResponse({
success: true, success: true,
payUrl: r.payUrl, payUrl: r.payUrl,
payReq: r.payReq payReq: r.payReq
}); });
}) })
.catch((e) => { .catch((e) => {
sendResponse({success: false, error: e.message}); sendResponse({success: false, error: e.message});
}); });
// async sendResponse // async sendResponse
return true; return true;
} }
}; };
} }
class ChromeBadge {
setText(s: string) {
chrome.browserAction.setBadgeText({text: s});
}
setColor(c: string) {
chrome.browserAction.setBadgeBackgroundColor({color: c});
}
}
function wxMain() { function wxMain() {
chrome.browserAction.setBadgeText({text: ""}); chrome.browserAction.setBadgeText({text: ""});
openTalerDb().then((db) => { openTalerDb().then((db) => {
let wallet = new Wallet(db, undefined, undefined); let http = new BrowserHttpLib();
let badge = new ChromeBadge();
let wallet = new Wallet(db, http, badge);
let handlers = makeHandlers(wallet); let handlers = makeHandlers(wallet);
wallet.updateBadge(); wallet.updateBadge();
chrome.runtime.onMessage.addListener( chrome.runtime.onMessage.addListener(

View File

@ -20,7 +20,6 @@
* @author Florian Dold * @author Florian Dold
*/ */
/// <reference path="../decl/urijs/URIjs.d.ts" /> /// <reference path="../decl/urijs/URIjs.d.ts" />
/// <reference path="../decl/chrome/chrome.d.ts" />
"use strict"; "use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -264,7 +263,7 @@ class Wallet {
form.append(req.field_mint, req.mint); form.append(req.field_mint, req.mint);
// TODO: set bank-specified fields. // TODO: set bank-specified fields.
let mintBaseUrl = canonicalizeBaseUrl(req.mint); let mintBaseUrl = canonicalizeBaseUrl(req.mint);
return httpPostForm(req.post_url, form) return this.http.postForm(req.post_url, form)
.then((hresp) => { .then((hresp) => {
let resp = { let resp = {
status: hresp.status, status: hresp.status,
@ -351,7 +350,7 @@ class Wallet {
wd.reserve_sig = pc.withdrawSig; wd.reserve_sig = pc.withdrawSig;
wd.coin_ev = pc.coinEv; wd.coin_ev = pc.coinEv;
let reqUrl = URI("reserve/withdraw").absoluteTo(r.mint_base_url); let reqUrl = URI("reserve/withdraw").absoluteTo(r.mint_base_url);
return httpPostJson(reqUrl, wd); return this.http.postJson(reqUrl, wd);
}) })
.then(resp => { .then(resp => {
if (resp.status != 200) { if (resp.status != 200) {
@ -381,8 +380,8 @@ class Wallet {
return n; return n;
} }
function doBadge(n) { function doBadge(n) {
chrome.browserAction.setBadgeText({ text: "" + n }); this.badge.setText(n.toString());
chrome.browserAction.setBadgeBackgroundColor({ color: "#0F0" }); this.badge.setColor("#0F0");
} }
Query(this.db) Query(this.db)
.iter("coins") .iter("coins")
@ -447,7 +446,7 @@ class Wallet {
.then((reserve) => { .then((reserve) => {
let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl); let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl);
reqUrl.query({ 'reserve_pub': reservePubStr }); reqUrl.query({ 'reserve_pub': reservePubStr });
return httpGet(reqUrl).then(resp => { return this.http.get(reqUrl).then(resp => {
if (resp.status != 200) { if (resp.status != 200) {
throw Error(); throw Error();
} }
@ -470,7 +469,7 @@ class Wallet {
*/ */
updateMintFromUrl(baseUrl) { updateMintFromUrl(baseUrl) {
let reqUrl = URI("keys").absoluteTo(baseUrl); let reqUrl = URI("keys").absoluteTo(baseUrl);
return httpGet(reqUrl).then((resp) => { return this.http.get(reqUrl).then((resp) => {
if (resp.status != 200) { if (resp.status != 200) {
throw Error("/keys request failed"); throw Error("/keys request failed");
} }

View File

@ -23,7 +23,6 @@
/// <reference path="../decl/urijs/URIjs.d.ts" /> /// <reference path="../decl/urijs/URIjs.d.ts" />
/// <reference path="../decl/chrome/chrome.d.ts" />
"use strict"; "use strict";
@Checkable.Class @Checkable.Class
@ -196,12 +195,22 @@ function canonicalizeBaseUrl(url) {
return x.href() return x.href()
} }
interface HttpRequestLibrary {
interface HttpRequestLibrary {
req(method: string,
url: string|uri.URI,
options?: any): Promise<HttpResponse>;
get(url: string|uri.URI): Promise<HttpResponse>;
postJson(url: string|uri.URI, body): Promise<HttpResponse>;
postForm(url: string|uri.URI, form): Promise<HttpResponse>;
} }
interface Badge { interface Badge {
setText(s: string): void;
setColor(c: string): void;
} }
@ -435,7 +444,7 @@ class Wallet {
// TODO: set bank-specified fields. // TODO: set bank-specified fields.
let mintBaseUrl = canonicalizeBaseUrl(req.mint); let mintBaseUrl = canonicalizeBaseUrl(req.mint);
return httpPostForm(req.post_url, form) return this.http.postForm(req.post_url, form)
.then((hresp) => { .then((hresp) => {
let resp: ConfirmReserveResponse = { let resp: ConfirmReserveResponse = {
status: hresp.status, status: hresp.status,
@ -537,7 +546,7 @@ class Wallet {
wd.reserve_sig = pc.withdrawSig; wd.reserve_sig = pc.withdrawSig;
wd.coin_ev = pc.coinEv; wd.coin_ev = pc.coinEv;
let reqUrl = URI("reserve/withdraw").absoluteTo(r.mint_base_url); let reqUrl = URI("reserve/withdraw").absoluteTo(r.mint_base_url);
return httpPostJson(reqUrl, wd); return this.http.postJson(reqUrl, wd);
}) })
.then(resp => { .then(resp => {
if (resp.status != 200) { if (resp.status != 200) {
@ -572,8 +581,8 @@ class Wallet {
} }
function doBadge(n) { function doBadge(n) {
chrome.browserAction.setBadgeText({text: "" + n}); this.badge.setText(n.toString());
chrome.browserAction.setBadgeBackgroundColor({color: "#0F0"}); this.badge.setColor("#0F0");
} }
Query(this.db) Query(this.db)
@ -647,7 +656,7 @@ class Wallet {
.then((reserve) => { .then((reserve) => {
let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl); let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl);
reqUrl.query({'reserve_pub': reservePubStr}); reqUrl.query({'reserve_pub': reservePubStr});
return httpGet(reqUrl).then(resp => { return this.http.get(reqUrl).then(resp => {
if (resp.status != 200) { if (resp.status != 200) {
throw Error(); throw Error();
} }
@ -671,7 +680,7 @@ class Wallet {
*/ */
updateMintFromUrl(baseUrl) { updateMintFromUrl(baseUrl) {
let reqUrl = URI("keys").absoluteTo(baseUrl); let reqUrl = URI("keys").absoluteTo(baseUrl);
return httpGet(reqUrl).then((resp) => { return this.http.get(reqUrl).then((resp) => {
if (resp.status != 200) { if (resp.status != 200) {
throw Error("/keys request failed"); throw Error("/keys request failed");
} }