Merge branch 'master' of ssh://taler.net/var/git/wallet
This commit is contained in:
commit
34b039de45
@ -1,220 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var DB = function () {
|
||||
let DB = {}; // returned object with exported functions
|
||||
|
||||
let DB_NAME = "taler";
|
||||
let DB_VERSION = 1;
|
||||
|
||||
let db = null;
|
||||
let is_ready = null;
|
||||
|
||||
DB.open = function (onsuccess, onerror)
|
||||
{
|
||||
is_ready = false;
|
||||
|
||||
let req = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
req.onerror = onerror;
|
||||
req.onsuccess = function (event)
|
||||
{
|
||||
db = event.target.result;
|
||||
is_ready = true;
|
||||
if (onsuccess)
|
||||
onsuccess();
|
||||
};
|
||||
|
||||
req.onupgradeneeded = function (event)
|
||||
{
|
||||
console.log ("DB: upgrade needed: oldVersion = "+ event.oldVersion);
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = onerror;
|
||||
|
||||
switch (event.oldVersion)
|
||||
{
|
||||
case 0: // DB does not exist yet
|
||||
{
|
||||
let example = {};
|
||||
|
||||
let mints = db.createObjectStore("mints", { keyPath: "mint_pub" });
|
||||
mints.createIndex("name", "name", { unique: true });
|
||||
|
||||
example.mint = {
|
||||
mint_pub: "<mint's master pub key>", // length: 32
|
||||
name: "Mint One",
|
||||
url: "https://mint.one/",
|
||||
};
|
||||
|
||||
let denoms = db.createObjectStore("denoms", { keyPath: "denom_pub" });
|
||||
|
||||
example.denom = {
|
||||
denom_pub: "<denom pub key>", // length: 32
|
||||
mint_pub: "<mint's master pub key>", // length: 32
|
||||
mint_sig: "<mint's sig>", // length: 64
|
||||
withdraw_expiry_time: 1234567890,
|
||||
deposit_expiry_time: 1234567890,
|
||||
start_time: 1234567890,
|
||||
value: {
|
||||
value: 1,
|
||||
fraction: 230000, // 0..999999
|
||||
currency: "EUR",
|
||||
},
|
||||
fee: {
|
||||
withdraw: {
|
||||
value: 0,
|
||||
fraction: 100000,
|
||||
currency: "EUR",
|
||||
},
|
||||
deposit: {
|
||||
value: 0,
|
||||
fraction: 100000,
|
||||
currency: "EUR",
|
||||
},
|
||||
refresh: {
|
||||
value: 0,
|
||||
fraction: 100000,
|
||||
currency: "EUR",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let reserves = db.createObjectStore("reserves", { keyPath: "reserve_pub"});
|
||||
example.reserve = {
|
||||
reserve_pub: "<pub key>",
|
||||
reserve_priv: "<priv key>",
|
||||
mint_pub: "<mint's master pub key>",
|
||||
initial: {
|
||||
value: 1,
|
||||
fraction: 230000,
|
||||
currency: "EUR",
|
||||
},
|
||||
current: {
|
||||
value: 1,
|
||||
fraction: 230000,
|
||||
currency: "EUR",
|
||||
blind_session_pub: "<pub key>",
|
||||
status_sig: "<sig>",
|
||||
},
|
||||
};
|
||||
|
||||
let withdrawals = db.createObjectStore("withdrawals", { keyPath: "id", autoIncrement: true });
|
||||
example.withdrawal = {
|
||||
id: 1, // generated
|
||||
reserve_pub: "<pub key>",
|
||||
reserve_sig: "<sig>",
|
||||
denom_pub: "<pub key",
|
||||
blind_session_pub: "<pub key>",
|
||||
blind_priv: "<priv key>",
|
||||
coin_pub: "<pub key>",
|
||||
coin_priv: "<priv key>",
|
||||
coin_ev: "",
|
||||
};
|
||||
|
||||
let coins = db.createObjectStore("coins", { keyPath: "coin_pub" });
|
||||
example.coin = {
|
||||
// coin either has a withdraw_id or refresh_id
|
||||
// or it is imported in which case both are null
|
||||
withdraw_id: 1, // can be null
|
||||
refresh_id: null, // can be null
|
||||
is_refreshed: false,
|
||||
denom_pub: "<pub key>",
|
||||
coin_pub: "<pub key>",
|
||||
coin_priv: "<priv key>",
|
||||
denom_sig: "<sig>",
|
||||
spent: {
|
||||
value: 1,
|
||||
fraction: 230000,
|
||||
},
|
||||
transactions: [ 123, 456 ], // list of transaction IDs where this coin was used
|
||||
};
|
||||
|
||||
let transactions = db.createObjectStore("transactions", { keyPath: "id", autoIncrement: true });
|
||||
example.transaction = {
|
||||
id: 1, // generated
|
||||
wire_hash: "<hash>",
|
||||
value: {
|
||||
value: 1,
|
||||
fraction: 230000,
|
||||
currency: "EUR",
|
||||
},
|
||||
contract: "<JSON>",
|
||||
is_checkout_done: true,
|
||||
is_confirmed: true,
|
||||
fulfillment_url: "https://some.shop/transaction/completed",
|
||||
};
|
||||
|
||||
let refresh = db.createObjectStore("refresh");
|
||||
example.refresh = {
|
||||
// TODO
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
is_ready = true;
|
||||
if (onsuccess)
|
||||
onsuccess();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DB.close = function ()
|
||||
{
|
||||
db.close();
|
||||
};
|
||||
|
||||
|
||||
DB.wallet_get = function (onresult, onerror)
|
||||
{
|
||||
let wallet = { };
|
||||
|
||||
let tr = db.transaction([ "coins", "denoms" ], "readonly");
|
||||
let coins = tr.objectStore("coins");
|
||||
let denoms = tr.objectStore("denoms");
|
||||
|
||||
let coins_cur = coins.openCursor();
|
||||
coins_cur.onerror = onerror;
|
||||
coins_cur.onsuccess = function ()
|
||||
{
|
||||
let cur = event.target.result;
|
||||
if (cur) {
|
||||
let denom_get = denoms.get(cur.valcue.denom_pub);
|
||||
denom_get.onerror = onerror;
|
||||
denom_get.onsuccess = function (event)
|
||||
{
|
||||
let denom = event.target.result;
|
||||
if (denom.currency in wallet)
|
||||
{
|
||||
let w = wallet[denom.currency];
|
||||
w.value += denom.value;
|
||||
w.fraction = (w.fraction + denom.fraction) % 1000000;
|
||||
if (1000000 <= w.fraction + denom.fraction)
|
||||
w.value++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wallet[denom.currency] = denom;
|
||||
}
|
||||
cur.continue();
|
||||
}
|
||||
}
|
||||
else // no more entries
|
||||
{
|
||||
onresult(wallet);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
DB.transaction_list = function (onresult, onerror)
|
||||
{
|
||||
// TODO
|
||||
};
|
||||
|
||||
|
||||
DB.reserve_list = function (onresult, onerror)
|
||||
{
|
||||
// TODO
|
||||
};
|
||||
|
||||
return DB;
|
||||
}();
|
||||
/**
|
||||
* Declarations and helpers for
|
||||
* things that are stored in the wallet's
|
||||
* database.
|
||||
*/
|
||||
|
@ -284,6 +284,13 @@ class RsaBlindingKey extends ArenaObject {
|
||||
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
||||
return o;
|
||||
}
|
||||
static fromCrock(s, a) {
|
||||
let obj = new this(a);
|
||||
let buf = ByteArray.fromCrock(s);
|
||||
obj.setNative(emscAlloc.rsa_blinding_key_decode(buf.getNative(), buf.size()));
|
||||
buf.destroy();
|
||||
return obj;
|
||||
}
|
||||
toCrock() {
|
||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
||||
let size = emscAlloc.rsa_blinding_key_encode(this.nativePtr, ptr);
|
||||
|
@ -416,12 +416,20 @@ class EddsaPublicKey extends PackedArenaObject {
|
||||
}
|
||||
|
||||
|
||||
|
||||
class RsaBlindingKey extends ArenaObject {
|
||||
static create(len: number, a?: Arena) {
|
||||
let o = new RsaBlindingKey(a);
|
||||
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
||||
return o;
|
||||
}
|
||||
static fromCrock(s: string, a?: Arena): RsaBlindingKey {
|
||||
let obj = new this(a);
|
||||
let buf = ByteArray.fromCrock(s);
|
||||
obj.setNative(emscAlloc.rsa_blinding_key_decode(buf.getNative(), buf.size()));
|
||||
buf.destroy();
|
||||
return obj;
|
||||
}
|
||||
|
||||
toCrock(): string {
|
||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
||||
|
@ -1,3 +1,10 @@
|
||||
/**
|
||||
* This file should be used as a WebWorker.
|
||||
* Background pages in the WebExtensions model do
|
||||
* not allow to schedule callbacks that should be called
|
||||
* after a timeout. We can emulate this with WebWorkers.
|
||||
*/
|
||||
|
||||
onmessage = function(e) {
|
||||
self.setInterval(() => postMessage(true), e.data.interval);
|
||||
}
|
||||
|
@ -24,15 +24,18 @@ function openTalerDb() {
|
||||
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
||||
db.createObjectStore("reserves", { keyPath: "reserve_pub" });
|
||||
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
||||
db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||
db.createObjectStore("withdrawals", { keyPath: "id", autoIncrement: true });
|
||||
db.createObjectStore("transactions", { keyPath: "id", autoIncrement: true });
|
||||
let coins = db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||
db.createObjectStore("transactions", { keyPath: "contractHash" });
|
||||
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
||||
break;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* See http://api.taler.net/wallet.html#general
|
||||
*/
|
||||
function canonicalizeBaseUrl(url) {
|
||||
let x = new URI(url);
|
||||
if (!x.protocol()) {
|
||||
@ -43,8 +46,24 @@ function canonicalizeBaseUrl(url) {
|
||||
x.query();
|
||||
return x.href();
|
||||
}
|
||||
function grantCoins(db, feeThreshold, paymentAmount, mintBaseUrl) {
|
||||
throw "not implemented";
|
||||
}
|
||||
function confirmPay(db, detail, sendResponse) {
|
||||
console.log("confirmPay", JSON.stringify(detail));
|
||||
let tx = db.transaction(['transactions'], 'readwrite');
|
||||
let trans = {
|
||||
contractHash: detail.offer.H_contract,
|
||||
contract: detail.offer.contract,
|
||||
sig: detail.offer
|
||||
};
|
||||
let contract = detail.offer.contract;
|
||||
//let chosenCoinPromise = chooseCoins(db, contract.max_fee, contract.amount)
|
||||
// .then(x => generateDepositPermissions(db, x))
|
||||
// .then(executePayment);
|
||||
return true;
|
||||
}
|
||||
function confirmReserve(db, detail, sendResponse) {
|
||||
console.log('detail: ' + JSON.stringify(detail));
|
||||
let reservePriv = EddsaPrivateKey.create();
|
||||
let reservePub = reservePriv.getPublicKey();
|
||||
let form = new FormData();
|
||||
@ -114,11 +133,8 @@ function rankDenom(denom1, denom2) {
|
||||
return (-1) * v1.cmp(v2);
|
||||
}
|
||||
function withdrawPrepare(db, denom, reserve) {
|
||||
console.log("in withdraw prepare");
|
||||
let reservePriv = new EddsaPrivateKey();
|
||||
console.log("loading reserve priv", reserve.reserve_priv);
|
||||
reservePriv.loadCrock(reserve.reserve_priv);
|
||||
console.log("reserve priv is", reservePriv.toCrock());
|
||||
let reservePub = new EddsaPublicKey();
|
||||
reservePub.loadCrock(reserve.reserve_pub);
|
||||
let denomPub = RsaPublicKey.fromCrock(denom.denom_pub);
|
||||
@ -126,9 +142,7 @@ function withdrawPrepare(db, denom, reserve) {
|
||||
let coinPub = coinPriv.getPublicKey();
|
||||
let blindingFactor = RsaBlindingKey.create(1024);
|
||||
let pubHash = coinPub.hash();
|
||||
console.log("about to blind");
|
||||
let ev = rsaBlind(pubHash, blindingFactor, denomPub);
|
||||
console.log("blinded");
|
||||
if (!denom.fee_withdraw) {
|
||||
throw Error("Field fee_withdraw missing");
|
||||
}
|
||||
@ -153,8 +167,10 @@ function withdrawPrepare(db, denom, reserve) {
|
||||
coinPub: coinPub.toCrock(),
|
||||
coinPriv: coinPriv.toCrock(),
|
||||
denomPub: denomPub.encode().toCrock(),
|
||||
mintBaseUrl: reserve.mintBaseUrl,
|
||||
withdrawSig: sig.toCrock(),
|
||||
coinEv: ev.toCrock()
|
||||
coinEv: ev.toCrock(),
|
||||
coinValue: denom.value
|
||||
};
|
||||
console.log("storing precoin", JSON.stringify(preCoin));
|
||||
let tx = db.transaction(['precoins'], 'readwrite');
|
||||
@ -197,15 +213,13 @@ function withdrawExecute(db, pc) {
|
||||
console.log("Withdrawal successful");
|
||||
console.log(myRequest.responseText);
|
||||
let resp = JSON.parse(myRequest.responseText);
|
||||
//let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
||||
// RsaBlindingKey.fromCrock(pc.blindingKey),
|
||||
// RsaPublicKey.fromCrock(pc.denomPub));
|
||||
let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev), RsaBlindingKey.fromCrock(pc.blindingKey), RsaPublicKey.fromCrock(pc.denomPub));
|
||||
let coin = {
|
||||
coinPub: pc.coinPub,
|
||||
coinPriv: pc.coinPriv,
|
||||
denomPub: pc.denomPub,
|
||||
reservePub: pc.reservePub,
|
||||
denomSig: "foo" //denomSig.encode().toCrock()
|
||||
denomSig: denomSig.encode().toCrock(),
|
||||
currentAmount: pc.coinValue
|
||||
};
|
||||
console.log("unblinded coin");
|
||||
resolve(coin);
|
||||
@ -442,6 +456,7 @@ openTalerDb().then((db) => {
|
||||
chrome.runtime.onMessage.addListener(function (req, sender, onresponse) {
|
||||
let dispatch = {
|
||||
"confirm-reserve": confirmReserve,
|
||||
"confirm-pay": confirmPay,
|
||||
"dump-db": dumpDb,
|
||||
"balances": balances,
|
||||
"reset": reset
|
||||
@ -449,7 +464,7 @@ openTalerDb().then((db) => {
|
||||
if (req.type in dispatch) {
|
||||
return dispatch[req.type](db, req.detail, onresponse);
|
||||
}
|
||||
console.error(format("Request type unknown, req {0}", JSON.stringify(req)));
|
||||
console.error(format("Request type {1} unknown, req {0}", JSON.stringify(req), req.type));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
@ -27,9 +27,9 @@ function openTalerDb(): Promise<IDBDatabase> {
|
||||
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
||||
db.createObjectStore("reserves", { keyPath: "reserve_pub"});
|
||||
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
||||
db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||
db.createObjectStore("withdrawals", { keyPath: "id", autoIncrement: true });
|
||||
db.createObjectStore("transactions", { keyPath: "id", autoIncrement: true });
|
||||
let coins = db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||
db.createObjectStore("transactions", { keyPath: "contractHash" });
|
||||
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
||||
break;
|
||||
}
|
||||
@ -38,6 +38,9 @@ function openTalerDb(): Promise<IDBDatabase> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See http://api.taler.net/wallet.html#general
|
||||
*/
|
||||
function canonicalizeBaseUrl(url) {
|
||||
let x = new URI(url);
|
||||
if (!x.protocol()) {
|
||||
@ -49,9 +52,39 @@ function canonicalizeBaseUrl(url) {
|
||||
return x.href()
|
||||
}
|
||||
|
||||
interface ConfirmPayRequest {
|
||||
offer: any;
|
||||
selectedMint: any;
|
||||
}
|
||||
|
||||
|
||||
function grantCoins(db: IDBDatabase,
|
||||
feeThreshold: AmountJson,
|
||||
paymentAmount: AmountJson,
|
||||
mintBaseUrl: string): Promise<any> {
|
||||
throw "not implemented";
|
||||
}
|
||||
|
||||
|
||||
function confirmPay(db, detail: ConfirmPayRequest, sendResponse) {
|
||||
console.log("confirmPay", JSON.stringify(detail));
|
||||
let tx = db.transaction(['transactions'], 'readwrite');
|
||||
let trans = {
|
||||
contractHash: detail.offer.H_contract,
|
||||
contract: detail.offer.contract,
|
||||
sig: detail.offer
|
||||
}
|
||||
|
||||
let contract = detail.offer.contract;
|
||||
|
||||
//let chosenCoinPromise = chooseCoins(db, contract.max_fee, contract.amount)
|
||||
// .then(x => generateDepositPermissions(db, x))
|
||||
// .then(executePayment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function confirmReserve(db, detail, sendResponse) {
|
||||
console.log('detail: ' + JSON.stringify(detail));
|
||||
let reservePriv = EddsaPrivateKey.create();
|
||||
let reservePub = reservePriv.getPublicKey();
|
||||
let form = new FormData();
|
||||
@ -126,45 +159,11 @@ function rankDenom(denom1: any, denom2: any) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface AmountJson {
|
||||
value: number;
|
||||
fraction: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
|
||||
interface Denomination {
|
||||
value: AmountJson;
|
||||
denomPub: string;
|
||||
}
|
||||
|
||||
interface PreCoin {
|
||||
coinPub: string;
|
||||
coinPriv: string;
|
||||
reservePub: string;
|
||||
denomPub: string;
|
||||
blindingKey: string;
|
||||
withdrawSig: string;
|
||||
coinEv: string;
|
||||
}
|
||||
|
||||
|
||||
interface Coin {
|
||||
coinPub: string;
|
||||
coinPriv: string;
|
||||
reservePub: string;
|
||||
denomPub: string;
|
||||
denomSig: string;
|
||||
}
|
||||
|
||||
|
||||
function withdrawPrepare(db: IDBDatabase, denom, reserve): Promise<PreCoin> {
|
||||
console.log("in withdraw prepare");
|
||||
function withdrawPrepare(db: IDBDatabase,
|
||||
denom: Denomination,
|
||||
reserve): Promise<PreCoin> {
|
||||
let reservePriv = new EddsaPrivateKey();
|
||||
console.log("loading reserve priv", reserve.reserve_priv);
|
||||
reservePriv.loadCrock(reserve.reserve_priv);
|
||||
console.log("reserve priv is", reservePriv.toCrock());
|
||||
let reservePub = new EddsaPublicKey();
|
||||
reservePub.loadCrock(reserve.reserve_pub);
|
||||
let denomPub = RsaPublicKey.fromCrock(denom.denom_pub);
|
||||
@ -172,9 +171,7 @@ function withdrawPrepare(db: IDBDatabase, denom, reserve): Promise<PreCoin> {
|
||||
let coinPub = coinPriv.getPublicKey();
|
||||
let blindingFactor = RsaBlindingKey.create(1024);
|
||||
let pubHash: HashCode = coinPub.hash();
|
||||
console.log("about to blind");
|
||||
let ev: ByteArray = rsaBlind(pubHash, blindingFactor, denomPub);
|
||||
console.log("blinded");
|
||||
|
||||
if (!denom.fee_withdraw) {
|
||||
throw Error("Field fee_withdraw missing");
|
||||
@ -205,8 +202,10 @@ function withdrawPrepare(db: IDBDatabase, denom, reserve): Promise<PreCoin> {
|
||||
coinPub: coinPub.toCrock(),
|
||||
coinPriv: coinPriv.toCrock(),
|
||||
denomPub: denomPub.encode().toCrock(),
|
||||
mintBaseUrl: reserve.mintBaseUrl,
|
||||
withdrawSig: sig.toCrock(),
|
||||
coinEv: ev.toCrock()
|
||||
coinEv: ev.toCrock(),
|
||||
coinValue: denom.value
|
||||
};
|
||||
|
||||
console.log("storing precoin", JSON.stringify(preCoin));
|
||||
@ -254,15 +253,15 @@ function withdrawExecute(db, pc: PreCoin): Promise<Coin> {
|
||||
console.log("Withdrawal successful");
|
||||
console.log(myRequest.responseText);
|
||||
let resp = JSON.parse(myRequest.responseText);
|
||||
//let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
||||
// RsaBlindingKey.fromCrock(pc.blindingKey),
|
||||
// RsaPublicKey.fromCrock(pc.denomPub));
|
||||
let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
||||
RsaBlindingKey.fromCrock(pc.blindingKey),
|
||||
RsaPublicKey.fromCrock(pc.denomPub));
|
||||
let coin: Coin = {
|
||||
coinPub: pc.coinPub,
|
||||
coinPriv: pc.coinPriv,
|
||||
denomPub: pc.denomPub,
|
||||
reservePub: pc.reservePub,
|
||||
denomSig: "foo" //denomSig.encode().toCrock()
|
||||
denomSig: denomSig.encode().toCrock(),
|
||||
currentAmount: pc.coinValue
|
||||
}
|
||||
console.log("unblinded coin");
|
||||
resolve(coin);
|
||||
@ -505,7 +504,7 @@ function balances(db, detail, sendResponse) {
|
||||
sendResponse(byCurrency);
|
||||
console.log("response", JSON.stringify(byCurrency));
|
||||
}
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -517,15 +516,15 @@ openTalerDb().then((db) => {
|
||||
function (req, sender, onresponse) {
|
||||
let dispatch = {
|
||||
"confirm-reserve": confirmReserve,
|
||||
"confirm-pay": confirmPay,
|
||||
"dump-db": dumpDb,
|
||||
"balances": balances,
|
||||
"reset": reset
|
||||
}
|
||||
};
|
||||
if (req.type in dispatch) {
|
||||
return dispatch[req.type](db, req.detail, onresponse);
|
||||
}
|
||||
console.error(format("Request type unknown, req {0}", JSON.stringify(req)));
|
||||
console.error(format("Request type {1} unknown, req {0}", JSON.stringify(req), req.type));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -44,10 +44,10 @@ document.addEventListener("DOMContentLoaded", function(e) {
|
||||
});
|
||||
document.body.addEventListener('taler-contract', function(e) {
|
||||
// XXX: the merchant should just give us the parsed data ...
|
||||
let contract = JSON.parse(e.detail);
|
||||
let offer = JSON.parse(e.detail);
|
||||
let uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
||||
let params = {
|
||||
contract: JSON.stringify(contract)
|
||||
offer: JSON.stringify(offer)
|
||||
}
|
||||
document.location.href = uri.query(params).href();
|
||||
});
|
||||
|
@ -16,15 +16,15 @@ Handlebars.registerHelper('prettyAmount', function (amount) {
|
||||
return v.toFixed(2) + " " + amount.currency;
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", (e) => {
|
||||
let contract = JSON.parse(query.contract);
|
||||
console.dir(contract);
|
||||
let offer = JSON.parse(query.offer);
|
||||
console.dir(offer);
|
||||
let source = $_("contract-template").innerHTML;
|
||||
let template = Handlebars.compile(source);
|
||||
let html = template(contract.contract);
|
||||
let html = template(offer.contract);
|
||||
$_("render-contract").innerHTML = html;
|
||||
document.getElementById("confirm-purchase").addEventListener("click", (e) => {
|
||||
document.getElementById("confirm-pay").addEventListener("click", (e) => {
|
||||
let d = clone(query);
|
||||
chrome.runtime.sendMessage({ type: 'confirm-purchase', detail: d }, (resp) => {
|
||||
chrome.runtime.sendMessage({ type: 'confirm-pay', detail: d }, (resp) => {
|
||||
if (resp.success === true) {
|
||||
document.location.href = resp.backlink;
|
||||
}
|
||||
|
@ -24,19 +24,18 @@ Handlebars.registerHelper('prettyAmount', function(amount) {
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", (e) => {
|
||||
let contract = JSON.parse(query.contract);
|
||||
console.dir(contract);
|
||||
let offer = JSON.parse(query.offer);
|
||||
console.dir(offer);
|
||||
|
||||
let source = $_("contract-template").innerHTML;
|
||||
let template = Handlebars.compile(source);
|
||||
let html = template(contract.contract);
|
||||
let html = template(offer.contract);
|
||||
|
||||
$_("render-contract").innerHTML = html;
|
||||
|
||||
|
||||
document.getElementById("confirm-purchase").addEventListener("click", (e) => {
|
||||
document.getElementById("confirm-pay").addEventListener("click", (e) => {
|
||||
let d = clone(query);
|
||||
chrome.runtime.sendMessage({type:'confirm-purchase', detail: d}, (resp) => {
|
||||
chrome.runtime.sendMessage({type:'confirm-pay', detail: d}, (resp) => {
|
||||
if (resp.success === true) {
|
||||
document.location.href = resp.backlink;
|
||||
} else {
|
||||
@ -46,7 +45,6 @@ document.addEventListener("DOMContentLoaded", (e) => {
|
||||
<pre>${resp.text}</pre>`;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -10,9 +10,14 @@
|
||||
<script src="balance-overview.js" type="text/javascript"></script>
|
||||
|
||||
<script id="balance-template" type="text/x-handlebars-template">
|
||||
{{#each this}}
|
||||
<p>{{prettyAmountNoCurrency this}} <a>{{@key}}</a></p>
|
||||
{{/each}}
|
||||
{{#if this.length}}
|
||||
{{#each this}}
|
||||
<p>{{prettyAmountNoCurrency this}} <a>{{@key}}</a></p>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<p>Looks like your wallet is empty. Want to get some
|
||||
<a id="link-kudos" href="http://bank.demo.taler.net">KUDOS?</a>
|
||||
{{/if}}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
@ -26,11 +31,6 @@
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div id="balance">
|
||||
<p>Looks like your wallet is empty. Want to get some
|
||||
<a id="link-kudos" href="http://bank.demo.taler.net">KUDOS?</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
@ -17,31 +17,9 @@ let React = {
|
||||
document.addEventListener('DOMContentLoaded', (e) => {
|
||||
console.log("content loaded");
|
||||
chrome.runtime.sendMessage({ type: "balances" }, function (wallet) {
|
||||
console.log("got balance");
|
||||
let n = 0;
|
||||
let table = React.createElement("div", null);
|
||||
let source = document.getElementById("balance-template").innerHTML;
|
||||
console.log("size", Object.keys(wallet).length);
|
||||
if (Object.keys(wallet).length > 0) {
|
||||
let template = Handlebars.compile(source);
|
||||
console.log("wallet ", JSON.stringify(wallet));
|
||||
let html = template(wallet);
|
||||
console.log("Hb generated html", html);
|
||||
table.innerHTML = html;
|
||||
let p = document.getElementById("content");
|
||||
p.replaceChild(table, p.firstElementChild);
|
||||
}
|
||||
/*
|
||||
for (let curr in wallet) {
|
||||
n++;
|
||||
let x = wallet[curr];
|
||||
let num = x.value + x.fraction / 10e6;
|
||||
table.appendChild(<p>{num} <a>{x.currency}</a></p>);
|
||||
}
|
||||
if (n != 0) {
|
||||
let p = document.getElementById("content");
|
||||
p.replaceChild(table, p.firstElementChild);
|
||||
} */
|
||||
let context = document.getElementById("balance-template").innerHTML;
|
||||
let template = Handlebars.compile(context);
|
||||
document.getElementById("content").innerHTML = template(wallet);
|
||||
});
|
||||
document.getElementById("debug").addEventListener("click", (e) => {
|
||||
chrome.tabs.create({
|
||||
|
@ -19,33 +19,9 @@ let React = {
|
||||
document.addEventListener('DOMContentLoaded', (e) => {
|
||||
console.log("content loaded");
|
||||
chrome.runtime.sendMessage({type: "balances"}, function(wallet) {
|
||||
console.log("got balance");
|
||||
let n = 0;
|
||||
let table = <div />;
|
||||
|
||||
let source = document.getElementById("balance-template").innerHTML;
|
||||
console.log("size", Object.keys(wallet).length);
|
||||
if (Object.keys(wallet).length > 0){
|
||||
let template = Handlebars.compile(source);
|
||||
console.log("wallet ", JSON.stringify(wallet));
|
||||
let html = template(wallet);
|
||||
console.log("Hb generated html", html);
|
||||
table.innerHTML = html;
|
||||
let p = document.getElementById("content");
|
||||
p.replaceChild(table, p.firstElementChild);
|
||||
}
|
||||
|
||||
/*
|
||||
for (let curr in wallet) {
|
||||
n++;
|
||||
let x = wallet[curr];
|
||||
let num = x.value + x.fraction / 10e6;
|
||||
table.appendChild(<p>{num} <a>{x.currency}</a></p>);
|
||||
}
|
||||
if (n != 0) {
|
||||
let p = document.getElementById("content");
|
||||
p.replaceChild(table, p.firstElementChild);
|
||||
} */
|
||||
let context = document.getElementById("balance-template").innerHTML;
|
||||
let template = Handlebars.compile(context);
|
||||
document.getElementById("content").innerHTML = template(wallet);
|
||||
});
|
||||
|
||||
document.getElementById("debug").addEventListener("click", (e) => {
|
||||
|
@ -6,6 +6,7 @@
|
||||
"files": [
|
||||
"background/wallet.ts",
|
||||
"background/emscriptif.ts",
|
||||
"background/db.ts",
|
||||
"lib/util.ts",
|
||||
"popup/balance-overview.tsx",
|
||||
"pages/confirm-contract.tsx"
|
||||
|
Loading…
Reference in New Issue
Block a user