Merge branch 'master' of ssh://taler.net/var/git/wallet
This commit is contained in:
commit
34b039de45
@ -1,220 +1,5 @@
|
|||||||
"use strict";
|
/**
|
||||||
|
* Declarations and helpers for
|
||||||
var DB = function () {
|
* things that are stored in the wallet's
|
||||||
let DB = {}; // returned object with exported functions
|
* database.
|
||||||
|
*/
|
||||||
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;
|
|
||||||
}();
|
|
||||||
|
@ -284,6 +284,13 @@ class RsaBlindingKey extends ArenaObject {
|
|||||||
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
||||||
return o;
|
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() {
|
toCrock() {
|
||||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
let ptr = emscAlloc.malloc(PTR_SIZE);
|
||||||
let size = emscAlloc.rsa_blinding_key_encode(this.nativePtr, ptr);
|
let size = emscAlloc.rsa_blinding_key_encode(this.nativePtr, ptr);
|
||||||
|
@ -416,12 +416,20 @@ class EddsaPublicKey extends PackedArenaObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RsaBlindingKey extends ArenaObject {
|
class RsaBlindingKey extends ArenaObject {
|
||||||
static create(len: number, a?: Arena) {
|
static create(len: number, a?: Arena) {
|
||||||
let o = new RsaBlindingKey(a);
|
let o = new RsaBlindingKey(a);
|
||||||
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
o.nativePtr = emscAlloc.rsa_blinding_key_create(len);
|
||||||
return o;
|
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 {
|
toCrock(): string {
|
||||||
let ptr = emscAlloc.malloc(PTR_SIZE);
|
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) {
|
onmessage = function(e) {
|
||||||
self.setInterval(() => postMessage(true), e.data.interval);
|
self.setInterval(() => postMessage(true), e.data.interval);
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,18 @@ function openTalerDb() {
|
|||||||
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
||||||
db.createObjectStore("reserves", { keyPath: "reserve_pub" });
|
db.createObjectStore("reserves", { keyPath: "reserve_pub" });
|
||||||
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
||||||
db.createObjectStore("coins", { keyPath: "coinPub" });
|
let coins = db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||||
db.createObjectStore("withdrawals", { keyPath: "id", autoIncrement: true });
|
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||||
db.createObjectStore("transactions", { keyPath: "id", autoIncrement: true });
|
db.createObjectStore("transactions", { keyPath: "contractHash" });
|
||||||
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* See http://api.taler.net/wallet.html#general
|
||||||
|
*/
|
||||||
function canonicalizeBaseUrl(url) {
|
function canonicalizeBaseUrl(url) {
|
||||||
let x = new URI(url);
|
let x = new URI(url);
|
||||||
if (!x.protocol()) {
|
if (!x.protocol()) {
|
||||||
@ -43,8 +46,24 @@ function canonicalizeBaseUrl(url) {
|
|||||||
x.query();
|
x.query();
|
||||||
return x.href();
|
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) {
|
function confirmReserve(db, detail, sendResponse) {
|
||||||
console.log('detail: ' + JSON.stringify(detail));
|
|
||||||
let reservePriv = EddsaPrivateKey.create();
|
let reservePriv = EddsaPrivateKey.create();
|
||||||
let reservePub = reservePriv.getPublicKey();
|
let reservePub = reservePriv.getPublicKey();
|
||||||
let form = new FormData();
|
let form = new FormData();
|
||||||
@ -114,11 +133,8 @@ function rankDenom(denom1, denom2) {
|
|||||||
return (-1) * v1.cmp(v2);
|
return (-1) * v1.cmp(v2);
|
||||||
}
|
}
|
||||||
function withdrawPrepare(db, denom, reserve) {
|
function withdrawPrepare(db, denom, reserve) {
|
||||||
console.log("in withdraw prepare");
|
|
||||||
let reservePriv = new EddsaPrivateKey();
|
let reservePriv = new EddsaPrivateKey();
|
||||||
console.log("loading reserve priv", reserve.reserve_priv);
|
|
||||||
reservePriv.loadCrock(reserve.reserve_priv);
|
reservePriv.loadCrock(reserve.reserve_priv);
|
||||||
console.log("reserve priv is", reservePriv.toCrock());
|
|
||||||
let reservePub = new EddsaPublicKey();
|
let reservePub = new EddsaPublicKey();
|
||||||
reservePub.loadCrock(reserve.reserve_pub);
|
reservePub.loadCrock(reserve.reserve_pub);
|
||||||
let denomPub = RsaPublicKey.fromCrock(denom.denom_pub);
|
let denomPub = RsaPublicKey.fromCrock(denom.denom_pub);
|
||||||
@ -126,9 +142,7 @@ function withdrawPrepare(db, denom, reserve) {
|
|||||||
let coinPub = coinPriv.getPublicKey();
|
let coinPub = coinPriv.getPublicKey();
|
||||||
let blindingFactor = RsaBlindingKey.create(1024);
|
let blindingFactor = RsaBlindingKey.create(1024);
|
||||||
let pubHash = coinPub.hash();
|
let pubHash = coinPub.hash();
|
||||||
console.log("about to blind");
|
|
||||||
let ev = rsaBlind(pubHash, blindingFactor, denomPub);
|
let ev = rsaBlind(pubHash, blindingFactor, denomPub);
|
||||||
console.log("blinded");
|
|
||||||
if (!denom.fee_withdraw) {
|
if (!denom.fee_withdraw) {
|
||||||
throw Error("Field fee_withdraw missing");
|
throw Error("Field fee_withdraw missing");
|
||||||
}
|
}
|
||||||
@ -153,8 +167,10 @@ function withdrawPrepare(db, denom, reserve) {
|
|||||||
coinPub: coinPub.toCrock(),
|
coinPub: coinPub.toCrock(),
|
||||||
coinPriv: coinPriv.toCrock(),
|
coinPriv: coinPriv.toCrock(),
|
||||||
denomPub: denomPub.encode().toCrock(),
|
denomPub: denomPub.encode().toCrock(),
|
||||||
|
mintBaseUrl: reserve.mintBaseUrl,
|
||||||
withdrawSig: sig.toCrock(),
|
withdrawSig: sig.toCrock(),
|
||||||
coinEv: ev.toCrock()
|
coinEv: ev.toCrock(),
|
||||||
|
coinValue: denom.value
|
||||||
};
|
};
|
||||||
console.log("storing precoin", JSON.stringify(preCoin));
|
console.log("storing precoin", JSON.stringify(preCoin));
|
||||||
let tx = db.transaction(['precoins'], 'readwrite');
|
let tx = db.transaction(['precoins'], 'readwrite');
|
||||||
@ -197,15 +213,13 @@ function withdrawExecute(db, pc) {
|
|||||||
console.log("Withdrawal successful");
|
console.log("Withdrawal successful");
|
||||||
console.log(myRequest.responseText);
|
console.log(myRequest.responseText);
|
||||||
let resp = JSON.parse(myRequest.responseText);
|
let resp = JSON.parse(myRequest.responseText);
|
||||||
//let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev), RsaBlindingKey.fromCrock(pc.blindingKey), RsaPublicKey.fromCrock(pc.denomPub));
|
||||||
// RsaBlindingKey.fromCrock(pc.blindingKey),
|
|
||||||
// RsaPublicKey.fromCrock(pc.denomPub));
|
|
||||||
let coin = {
|
let coin = {
|
||||||
coinPub: pc.coinPub,
|
coinPub: pc.coinPub,
|
||||||
coinPriv: pc.coinPriv,
|
coinPriv: pc.coinPriv,
|
||||||
denomPub: pc.denomPub,
|
denomPub: pc.denomPub,
|
||||||
reservePub: pc.reservePub,
|
denomSig: denomSig.encode().toCrock(),
|
||||||
denomSig: "foo" //denomSig.encode().toCrock()
|
currentAmount: pc.coinValue
|
||||||
};
|
};
|
||||||
console.log("unblinded coin");
|
console.log("unblinded coin");
|
||||||
resolve(coin);
|
resolve(coin);
|
||||||
@ -442,6 +456,7 @@ openTalerDb().then((db) => {
|
|||||||
chrome.runtime.onMessage.addListener(function (req, sender, onresponse) {
|
chrome.runtime.onMessage.addListener(function (req, sender, onresponse) {
|
||||||
let dispatch = {
|
let dispatch = {
|
||||||
"confirm-reserve": confirmReserve,
|
"confirm-reserve": confirmReserve,
|
||||||
|
"confirm-pay": confirmPay,
|
||||||
"dump-db": dumpDb,
|
"dump-db": dumpDb,
|
||||||
"balances": balances,
|
"balances": balances,
|
||||||
"reset": reset
|
"reset": reset
|
||||||
@ -449,7 +464,7 @@ openTalerDb().then((db) => {
|
|||||||
if (req.type in dispatch) {
|
if (req.type in dispatch) {
|
||||||
return dispatch[req.type](db, req.detail, onresponse);
|
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;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -27,9 +27,9 @@ function openTalerDb(): Promise<IDBDatabase> {
|
|||||||
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
db.createObjectStore("mints", { keyPath: "baseUrl" });
|
||||||
db.createObjectStore("reserves", { keyPath: "reserve_pub"});
|
db.createObjectStore("reserves", { keyPath: "reserve_pub"});
|
||||||
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
db.createObjectStore("denoms", { keyPath: "denomPub" });
|
||||||
db.createObjectStore("coins", { keyPath: "coinPub" });
|
let coins = db.createObjectStore("coins", { keyPath: "coinPub" });
|
||||||
db.createObjectStore("withdrawals", { keyPath: "id", autoIncrement: true });
|
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||||
db.createObjectStore("transactions", { keyPath: "id", autoIncrement: true });
|
db.createObjectStore("transactions", { keyPath: "contractHash" });
|
||||||
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
db.createObjectStore("precoins", { keyPath: "coinPub", autoIncrement: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -38,6 +38,9 @@ function openTalerDb(): Promise<IDBDatabase> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See http://api.taler.net/wallet.html#general
|
||||||
|
*/
|
||||||
function canonicalizeBaseUrl(url) {
|
function canonicalizeBaseUrl(url) {
|
||||||
let x = new URI(url);
|
let x = new URI(url);
|
||||||
if (!x.protocol()) {
|
if (!x.protocol()) {
|
||||||
@ -49,9 +52,39 @@ function canonicalizeBaseUrl(url) {
|
|||||||
return x.href()
|
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) {
|
function confirmReserve(db, detail, sendResponse) {
|
||||||
console.log('detail: ' + JSON.stringify(detail));
|
|
||||||
let reservePriv = EddsaPrivateKey.create();
|
let reservePriv = EddsaPrivateKey.create();
|
||||||
let reservePub = reservePriv.getPublicKey();
|
let reservePub = reservePriv.getPublicKey();
|
||||||
let form = new FormData();
|
let form = new FormData();
|
||||||
@ -126,45 +159,11 @@ function rankDenom(denom1: any, denom2: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function withdrawPrepare(db: IDBDatabase,
|
||||||
interface AmountJson {
|
denom: Denomination,
|
||||||
value: number;
|
reserve): Promise<PreCoin> {
|
||||||
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");
|
|
||||||
let reservePriv = new EddsaPrivateKey();
|
let reservePriv = new EddsaPrivateKey();
|
||||||
console.log("loading reserve priv", reserve.reserve_priv);
|
|
||||||
reservePriv.loadCrock(reserve.reserve_priv);
|
reservePriv.loadCrock(reserve.reserve_priv);
|
||||||
console.log("reserve priv is", reservePriv.toCrock());
|
|
||||||
let reservePub = new EddsaPublicKey();
|
let reservePub = new EddsaPublicKey();
|
||||||
reservePub.loadCrock(reserve.reserve_pub);
|
reservePub.loadCrock(reserve.reserve_pub);
|
||||||
let denomPub = RsaPublicKey.fromCrock(denom.denom_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 coinPub = coinPriv.getPublicKey();
|
||||||
let blindingFactor = RsaBlindingKey.create(1024);
|
let blindingFactor = RsaBlindingKey.create(1024);
|
||||||
let pubHash: HashCode = coinPub.hash();
|
let pubHash: HashCode = coinPub.hash();
|
||||||
console.log("about to blind");
|
|
||||||
let ev: ByteArray = rsaBlind(pubHash, blindingFactor, denomPub);
|
let ev: ByteArray = rsaBlind(pubHash, blindingFactor, denomPub);
|
||||||
console.log("blinded");
|
|
||||||
|
|
||||||
if (!denom.fee_withdraw) {
|
if (!denom.fee_withdraw) {
|
||||||
throw Error("Field fee_withdraw missing");
|
throw Error("Field fee_withdraw missing");
|
||||||
@ -205,8 +202,10 @@ function withdrawPrepare(db: IDBDatabase, denom, reserve): Promise<PreCoin> {
|
|||||||
coinPub: coinPub.toCrock(),
|
coinPub: coinPub.toCrock(),
|
||||||
coinPriv: coinPriv.toCrock(),
|
coinPriv: coinPriv.toCrock(),
|
||||||
denomPub: denomPub.encode().toCrock(),
|
denomPub: denomPub.encode().toCrock(),
|
||||||
|
mintBaseUrl: reserve.mintBaseUrl,
|
||||||
withdrawSig: sig.toCrock(),
|
withdrawSig: sig.toCrock(),
|
||||||
coinEv: ev.toCrock()
|
coinEv: ev.toCrock(),
|
||||||
|
coinValue: denom.value
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("storing precoin", JSON.stringify(preCoin));
|
console.log("storing precoin", JSON.stringify(preCoin));
|
||||||
@ -254,15 +253,15 @@ function withdrawExecute(db, pc: PreCoin): Promise<Coin> {
|
|||||||
console.log("Withdrawal successful");
|
console.log("Withdrawal successful");
|
||||||
console.log(myRequest.responseText);
|
console.log(myRequest.responseText);
|
||||||
let resp = JSON.parse(myRequest.responseText);
|
let resp = JSON.parse(myRequest.responseText);
|
||||||
//let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
let denomSig = rsaUnblind(RsaSignature.fromCrock(resp.coin_ev),
|
||||||
// RsaBlindingKey.fromCrock(pc.blindingKey),
|
RsaBlindingKey.fromCrock(pc.blindingKey),
|
||||||
// RsaPublicKey.fromCrock(pc.denomPub));
|
RsaPublicKey.fromCrock(pc.denomPub));
|
||||||
let coin: Coin = {
|
let coin: Coin = {
|
||||||
coinPub: pc.coinPub,
|
coinPub: pc.coinPub,
|
||||||
coinPriv: pc.coinPriv,
|
coinPriv: pc.coinPriv,
|
||||||
denomPub: pc.denomPub,
|
denomPub: pc.denomPub,
|
||||||
reservePub: pc.reservePub,
|
denomSig: denomSig.encode().toCrock(),
|
||||||
denomSig: "foo" //denomSig.encode().toCrock()
|
currentAmount: pc.coinValue
|
||||||
}
|
}
|
||||||
console.log("unblinded coin");
|
console.log("unblinded coin");
|
||||||
resolve(coin);
|
resolve(coin);
|
||||||
@ -505,7 +504,7 @@ function balances(db, detail, sendResponse) {
|
|||||||
sendResponse(byCurrency);
|
sendResponse(byCurrency);
|
||||||
console.log("response", JSON.stringify(byCurrency));
|
console.log("response", JSON.stringify(byCurrency));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,15 +516,15 @@ openTalerDb().then((db) => {
|
|||||||
function (req, sender, onresponse) {
|
function (req, sender, onresponse) {
|
||||||
let dispatch = {
|
let dispatch = {
|
||||||
"confirm-reserve": confirmReserve,
|
"confirm-reserve": confirmReserve,
|
||||||
|
"confirm-pay": confirmPay,
|
||||||
"dump-db": dumpDb,
|
"dump-db": dumpDb,
|
||||||
"balances": balances,
|
"balances": balances,
|
||||||
"reset": reset
|
"reset": reset
|
||||||
}
|
};
|
||||||
if (req.type in dispatch) {
|
if (req.type in dispatch) {
|
||||||
return dispatch[req.type](db, req.detail, onresponse);
|
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;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ document.addEventListener("DOMContentLoaded", function(e) {
|
|||||||
});
|
});
|
||||||
document.body.addEventListener('taler-contract', function(e) {
|
document.body.addEventListener('taler-contract', function(e) {
|
||||||
// XXX: the merchant should just give us the parsed data ...
|
// 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 uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
||||||
let params = {
|
let params = {
|
||||||
contract: JSON.stringify(contract)
|
offer: JSON.stringify(offer)
|
||||||
}
|
}
|
||||||
document.location.href = uri.query(params).href();
|
document.location.href = uri.query(params).href();
|
||||||
});
|
});
|
||||||
|
@ -16,15 +16,15 @@ Handlebars.registerHelper('prettyAmount', function (amount) {
|
|||||||
return v.toFixed(2) + " " + amount.currency;
|
return v.toFixed(2) + " " + amount.currency;
|
||||||
});
|
});
|
||||||
document.addEventListener("DOMContentLoaded", (e) => {
|
document.addEventListener("DOMContentLoaded", (e) => {
|
||||||
let contract = JSON.parse(query.contract);
|
let offer = JSON.parse(query.offer);
|
||||||
console.dir(contract);
|
console.dir(offer);
|
||||||
let source = $_("contract-template").innerHTML;
|
let source = $_("contract-template").innerHTML;
|
||||||
let template = Handlebars.compile(source);
|
let template = Handlebars.compile(source);
|
||||||
let html = template(contract.contract);
|
let html = template(offer.contract);
|
||||||
$_("render-contract").innerHTML = html;
|
$_("render-contract").innerHTML = html;
|
||||||
document.getElementById("confirm-purchase").addEventListener("click", (e) => {
|
document.getElementById("confirm-pay").addEventListener("click", (e) => {
|
||||||
let d = clone(query);
|
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) {
|
if (resp.success === true) {
|
||||||
document.location.href = resp.backlink;
|
document.location.href = resp.backlink;
|
||||||
}
|
}
|
||||||
|
@ -24,19 +24,18 @@ Handlebars.registerHelper('prettyAmount', function(amount) {
|
|||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", (e) => {
|
document.addEventListener("DOMContentLoaded", (e) => {
|
||||||
let contract = JSON.parse(query.contract);
|
let offer = JSON.parse(query.offer);
|
||||||
console.dir(contract);
|
console.dir(offer);
|
||||||
|
|
||||||
let source = $_("contract-template").innerHTML;
|
let source = $_("contract-template").innerHTML;
|
||||||
let template = Handlebars.compile(source);
|
let template = Handlebars.compile(source);
|
||||||
let html = template(contract.contract);
|
let html = template(offer.contract);
|
||||||
|
|
||||||
$_("render-contract").innerHTML = html;
|
$_("render-contract").innerHTML = html;
|
||||||
|
|
||||||
|
document.getElementById("confirm-pay").addEventListener("click", (e) => {
|
||||||
document.getElementById("confirm-purchase").addEventListener("click", (e) => {
|
|
||||||
let d = clone(query);
|
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) {
|
if (resp.success === true) {
|
||||||
document.location.href = resp.backlink;
|
document.location.href = resp.backlink;
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +45,6 @@ document.addEventListener("DOMContentLoaded", (e) => {
|
|||||||
<pre>${resp.text}</pre>`;
|
<pre>${resp.text}</pre>`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,9 +10,14 @@
|
|||||||
<script src="balance-overview.js" type="text/javascript"></script>
|
<script src="balance-overview.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script id="balance-template" type="text/x-handlebars-template">
|
<script id="balance-template" type="text/x-handlebars-template">
|
||||||
{{#each this}}
|
{{#if this.length}}
|
||||||
<p>{{prettyAmountNoCurrency this}} <a>{{@key}}</a></p>
|
{{#each this}}
|
||||||
{{/each}}
|
<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>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
@ -26,11 +31,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<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>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -17,31 +17,9 @@ let React = {
|
|||||||
document.addEventListener('DOMContentLoaded', (e) => {
|
document.addEventListener('DOMContentLoaded', (e) => {
|
||||||
console.log("content loaded");
|
console.log("content loaded");
|
||||||
chrome.runtime.sendMessage({ type: "balances" }, function (wallet) {
|
chrome.runtime.sendMessage({ type: "balances" }, function (wallet) {
|
||||||
console.log("got balance");
|
let context = document.getElementById("balance-template").innerHTML;
|
||||||
let n = 0;
|
let template = Handlebars.compile(context);
|
||||||
let table = React.createElement("div", null);
|
document.getElementById("content").innerHTML = template(wallet);
|
||||||
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);
|
|
||||||
} */
|
|
||||||
});
|
});
|
||||||
document.getElementById("debug").addEventListener("click", (e) => {
|
document.getElementById("debug").addEventListener("click", (e) => {
|
||||||
chrome.tabs.create({
|
chrome.tabs.create({
|
||||||
|
@ -19,33 +19,9 @@ let React = {
|
|||||||
document.addEventListener('DOMContentLoaded', (e) => {
|
document.addEventListener('DOMContentLoaded', (e) => {
|
||||||
console.log("content loaded");
|
console.log("content loaded");
|
||||||
chrome.runtime.sendMessage({type: "balances"}, function(wallet) {
|
chrome.runtime.sendMessage({type: "balances"}, function(wallet) {
|
||||||
console.log("got balance");
|
let context = document.getElementById("balance-template").innerHTML;
|
||||||
let n = 0;
|
let template = Handlebars.compile(context);
|
||||||
let table = <div />;
|
document.getElementById("content").innerHTML = template(wallet);
|
||||||
|
|
||||||
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);
|
|
||||||
} */
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("debug").addEventListener("click", (e) => {
|
document.getElementById("debug").addEventListener("click", (e) => {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"background/wallet.ts",
|
"background/wallet.ts",
|
||||||
"background/emscriptif.ts",
|
"background/emscriptif.ts",
|
||||||
|
"background/db.ts",
|
||||||
"lib/util.ts",
|
"lib/util.ts",
|
||||||
"popup/balance-overview.tsx",
|
"popup/balance-overview.tsx",
|
||||||
"pages/confirm-contract.tsx"
|
"pages/confirm-contract.tsx"
|
||||||
|
Loading…
Reference in New Issue
Block a user