aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortg(x) <*@tg-x.net>2015-12-04 22:47:44 +0100
committertg(x) <*@tg-x.net>2015-12-04 22:47:44 +0100
commit1089b40b1c03fa69c0e73dd43e4281aa96388171 (patch)
tree0cdffcbad05041659dc826db9f5dbf1f47de47e1
parent5243a707260af9de820ad02b1972d3280164cf19 (diff)
DB structure, emscripten interface
-rwxr-xr-xMakefile6
-rw-r--r--extension/background/db.js220
-rw-r--r--extension/background/emscriptif.js587
l---------extension/background/libwrapper.js1
-rw-r--r--extension/background/wallet.js38
-rw-r--r--extension/lib/util.js91
-rw-r--r--extension/manifest.json16
-rw-r--r--extension/popup/transactions.html1
-rw-r--r--extension/popup/transactions.js19
-rw-r--r--extension/popup/wallet.html1
-rw-r--r--extension/popup/wallet.js30
11 files changed, 970 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 817dce69a..15028c85b 100755
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-name=taler-wallet
-version=0.1
-xpi=${name}-${version}.xpi
+name = taler-wallet
+version = $(shell grep '"version"' extension/manifest.json | sed 's/.*"\([0-9.]\+\)".*/\1/')
+xpi = ${name}-${version}.xpi
xpi:
cd extension && zip ../${xpi} $$(git ls-files)
diff --git a/extension/background/db.js b/extension/background/db.js
new file mode 100644
index 000000000..9be933d9c
--- /dev/null
+++ b/extension/background/db.js
@@ -0,0 +1,220 @@
+"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;
+}();
diff --git a/extension/background/emscriptif.js b/extension/background/emscriptif.js
new file mode 100644
index 000000000..62b233eda
--- /dev/null
+++ b/extension/background/emscriptif.js
@@ -0,0 +1,587 @@
+/*
+
+ This file is part of TALER
+ Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors)
+
+ 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, see <http://www.gnu.org/licenses/>
+
+
+*/
+
+
+var EXPORTED_SYMBOLS = [
+ 'TWRhelloWorld',
+ 'TWRgetValue',
+ 'TWRgetFraction',
+ 'TWRgetCurrency',
+ 'TamountCmp',
+ 'TWRverifyConfirmation',
+ 'TWRverifySignKey',
+ 'TWRverifyDenom',
+ 'TWRverifyDenoms',
+ 'TWRALLrsaPublicKeyHash',
+ 'TWRALLgetEncodingFromRsaSignature',
+ 'DWRtestStringCmp',
+ 'TWRmultiplyAmount',
+ 'TWRmultiplyAmounts',
+ 'DWRdumpAmount',
+ 'TWRALLgetAmount',
+ 'DWRtestString',
+ 'DWRgetPurpose',
+ 'TWReddsaVerify',
+ 'TamountAdd',
+ 'TamountSubtract',
+ 'TWRALLmakeEddsaSignature',
+ 'TWRALLamountAdd',
+ 'TWRALLeddsaPublicKeyFromPrivate',
+ 'TWRALLeddsaPublicKeyFromPrivString',
+ 'TWRALLeddsaPrivateKeyFromString',
+ 'TWRALLeccEcdh',
+ 'TWRALLhash',
+ 'TWRALLecdhePublicKeyFromPrivateKey',
+ 'TWRALLrsaPublicKeyDecodeFromString',
+ 'GCeddsaSign',
+ 'TWRALLmakeWithdrawBundle',
+ 'GCALLrsaSignatureDecode',
+ 'GCrsaSignatureEncode',
+ 'TWRALLsignDepositPermission',
+ 'GCALLrsaPublicKeyDecode',
+ 'GCALLrsaPublicKeyEncode',
+ 'WRALLeddsaPublicKey',
+ 'GCALLeddsaKeyCreate',
+ 'WRALLecdhePublicKey ',
+ 'GSALLdataToStringAlloc',
+ 'TWRgnunetFree',
+ 'GSstringToData',
+ 'TWRALLgetCurrentTime',
+ 'TWRgetFancyTime',
+ 'GChash',
+ 'getHashedArray',
+ 'TWRALLsignTest',
+ 'GCALLecdheKeyCreate',
+ 'GCecdheKeyGetPublic',
+ 'WRALLecdhePublicKey',
+ 'WRverifyTest',
+ 'GCeccEcdh',
+ 'TWRALLgenSymmetricKey',
+ 'TWRALLgenInitVector',
+ 'GCsymmetricDecrypt',
+ 'GCsymmetricEncrypt',
+ 'TWRALLgenKeyFromBlob',
+ 'GCALLrsaPrivateKeyGetPublic',
+ 'GCALLrsaPrivateKeyCreate',
+ 'GCALLrsaBlindingKeyCreate',
+ 'GCrsaBlindingKeyFree',
+ 'GCrsaPublicKeyFree',
+ 'GCrsaPrivateKeyFree',
+ 'GCALLrsaBlind',
+ 'GCALLrsaUnblind',
+ 'GCALLrsaSign',
+ 'GCrsaVerify',
+ 'GCrsaSignatureFree',
+ 'GCeddsaKeyGetPublic',
+ 'WRALLmakePurpose',
+ 'GChkdf',
+ 'emscMalloc',
+ 'emscFree'
+];
+
+/* The following definition is needed to make emscripted library to remain
+ 'alive' after its loading. Otherwise, the normal behaviour would be:
+ loading -> look for a 'main()' -> if one is found execute it then exit,
+ otherwise just exit. See https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html
+ DO NOTE: this definition MUST precede the importing/loading of the emscripted
+ library */
+
+/* FIXME
+getLastWindow().Module = {
+
+ onRuntimeInitialized: function() {
+
+ }
+
+};
+*/
+
+/* According to emscripten's design, we need our emscripted library to be executed
+ with a 'window' object as its global scope.
+ Note: that holds on emscripten's functions too, that is they need to be *explicitly*
+ run with some 'window' object as their global scope. In practice, given a function
+ 'foo' pointing to some emscripted function, that is accomplished by the mean of 'call()'
+ or 'apply()' methods; so, being 'someWin' a 'window' object, the statements
+
+ foo.call('someWin', arg1, .., argN) or foo.apply('someWin', ['arg1', .., 'argN']) will
+ execute foo(arg1, .., argN) with 'someWin' as its global scope.
+ See http://www.bennadel.com/blog/2265-changing-the-execution-context-of-javascript
+ -functions-using-call-and-apply.htm. */
+
+/* The naming convention is such that:
+ - 'GCfunctionName' takes its code from GNUNET_CRYPTO_function_name
+ - 'GCALLfunctionName' takes its code from GNUNET_CRYPTO_function_name and returns
+ a pointer that must be deallocated using 'WRgnunetFree' (that takes its code from
+ 'GNUNET_free' in the wrapper)
+ - 'GSfunctionName' and 'GSALLfunctionName' comply to the same convention respect to
+ GNUNET_STRINGS_* realm.
+ - 'TWRfunctionName' takes its code from 'TALER_function_name' in the wrapper.
+ - 'TWRALLfunctionName' takes its code from 'TALER_ALL_function_name' in the wrapper
+ and returns a pointer that must be deallocated using 'TWRgnunetFree' (or a function
+ provided by some emscripted routine) (the 'wrapper' is an additional layer written in
+ C that does some struct(s) manipulations where that is uncovenient to do from JavaScript.
+ Currently located at '../../emscripten/testcases/wrap.c')
+ - The same applies to 'TfunctionName' and 'TALLfunctionName', to indicate that the
+ respective functions come from (the emscripted version of) TALER_* realm. */
+
+
+// shortcut to emscr's 'malloc'
+function emscMalloc(size) {
+
+ var ptr = Module._malloc(size);
+ return ptr;
+
+}
+
+/* shortcut to emscr's 'free'. This function is problematic:
+ it randomly stops working giving 'emscFree is not a function'
+ error */
+function emscFree(ptr) {
+
+ Module._free(ptr);
+
+}
+
+var getEmsc = Module.cwrap;
+
+var TWRhelloWorld = getEmsc('TALER_WR_hello_world', 'void', []);
+
+var TWRverifyConfirmation = getEmsc('TALER_WR_verify_confirmation',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+var TWRgetValue = getEmsc('TALER_WR_get_value',
+ 'number',
+ ['number']);
+
+var TWRgetFraction = getEmsc('TALER_WR_get_fraction',
+ 'number',
+ ['number']);
+
+var TWRgetCurrency = getEmsc('TALER_WR_get_currency',
+ 'string',
+ ['number']);
+
+
+var TWRmultiplyAmounts = getEmsc('TALER_WR_multiply_amounts',
+ 'number',
+ ['number',
+ 'number'] );
+
+var TWRmultiplyAmount = getEmsc('TALER_WR_multiply_amount',
+ 'number',
+ ['number',
+ 'number'] );
+
+var TWRALLrsaPublicKeyHash = getEmsc('TALER_WRALL_rsa_public_key_hash',
+ 'number',
+ ['number']);
+
+var TWRverifyDenom = getEmsc('TALER_WR_verify_denom',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var TWRverifyDenoms = getEmsc('TALER_WR_verify_denoms',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var TWRverifySignKey = getEmsc('TALER_WR_verify_sign_key',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+
+var TWRALLgetEncodingFromRsaSignature = getEmsc('TALER_WRALL_get_encoding_from_rsa_signature',
+ 'number',
+ ['number']);
+
+var TamountCmp = getEmsc('TALER_amount_cmp',
+ 'number',
+ ['number',
+ 'number']);
+
+var DWRdumpAmount = getEmsc('DEBUG_WR_dump_amount',
+ 'void'
+ ['number']);
+
+var DWRtestStringCmp = getEmsc('DEBUG_WR_test_string_cmp',
+ 'number',
+ ['number',
+ 'string']);
+
+var TWRALLgetAmount = getEmsc('TALER_WRALL_get_amount',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'string']);
+
+var DWRgetPurpose = getEmsc('DEBUG_WR_get_purpose',
+ 'number',
+ ['number']);
+
+var TWReddsaVerify = getEmsc('TALER_WR_eddsa_verify',
+ 'number',
+ ['string',
+ 'number',
+ 'number',
+ 'number']);
+
+var TWRALLmakeEddsaSignature = getEmsc('TALER_WRALL_make_eddsa_signature',
+ 'number',
+ ['number',
+ 'number']);
+
+var TWRALLamountAdd = getEmsc('TALER_WRALL_amount_add',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'string']);
+
+var TamountSubtract = getEmsc('TALER_amount_subtract',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+var TamountAdd = getEmsc('TALER_amount_add',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+var TWRALLeddsaPublicKeyFromPrivate = getEmsc('TALER_WRALL_eddsa_public_key_from_private',
+ 'number',
+ ['number']);
+
+var TWRALLeddsaPublicKeyFromPrivString = getEmsc('TALER_WRALL_eddsa_public_key_from_priv_string',
+ 'number',
+ ['string']);
+
+var TWRALLsignDepositPermission = getEmsc('TALER_WRALL_sign_deposit_permission',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var TWRALLeddsaPrivateKeyFromString = getEmsc('TALER_WRALL_eddsa_private_key_from_string',
+ 'number',
+ ['string']);
+
+var TWRALLrsaPublicKeyDecodeFromString = getEmsc('TALER_WRALL_rsa_public_key_decode_from_string',
+ 'number',
+ ['string']);
+
+var TWRALLecdhePublicKeyFromPrivateKey = getEmsc('TALER_WRALL_ecdhe_public_key_from_private_key',
+ 'number',
+ ['number']);
+
+var TWRALLeccEcdh = getEmsc('TALER_WRALL_ecc_ecdh',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+var TWRALLmakeWithdrawBundle = getEmsc('TALER_WRALL_make_withdraw_bundle',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var WRALLmakePurpose = getEmsc('WRALL_make_purpose',
+ 'number',
+ ['string',
+ 'number',
+ 'number',
+ 'number']);
+
+var GCALLrsaSignatureDecode = getEmsc('GNUNET_CRYPTO_rsa_signature_decode',
+ 'number',
+ ['number',
+ 'number']);
+
+var GCALLrsaSignatureEncode = getEmsc('GNUNET_CRYPTO_rsa_signature_encode',
+ 'number',
+ ['number',
+ 'number']);
+
+var GCALLrsaPublicKeyEncode = getEmsc('GNUNET_CRYPTO_rsa_public_key_encode',
+ 'number',
+ ['number',
+ 'number']);
+
+var GCALLrsaPublicKeyDecode = getEmsc('GNUNET_CRYPTO_rsa_public_key_decode',
+ 'number',
+ ['number',
+ 'number']);
+
+var GCALLrsaPrivateKeyGetPublic = getEmsc('GNUNET_CRYPTO_rsa_private_key_get_public',
+ 'number',
+ ['number']);
+
+var GCALLrsaPrivateKeyCreate = getEmsc('GNUNET_CRYPTO_rsa_private_key_create',
+ 'number',
+ ['number']);
+
+var GCALLrsaBlindingKeyCreate = getEmsc('GNUNET_CRYPTO_rsa_blinding_key_create',
+ 'number',
+ ['number']);
+
+var GCrsaBlindingKeyFree = getEmsc('GNUNET_CRYPTO_rsa_blinding_key_free',
+ 'void',
+ ['number']);
+
+var GCrsaPublicKeyFree = getEmsc('GNUNET_CRYPTO_rsa_public_key_free',
+ 'void',
+ ['number']);
+
+var GCrsaPrivateKeyFree = getEmsc('GNUNET_CRYPTO_rsa_private_key_free',
+ 'void',
+ ['number']);
+
+var GCALLrsaBlind = getEmsc('GNUNET_CRYPTO_rsa_blind',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number']);
+
+var GCALLrsaUnblind = getEmsc('GNUNET_CRYPTO_rsa_unblind',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+var GCALLrsaSign = getEmsc('GNUNET_CRYPTO_rsa_sign',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+var GCrsaVerify = getEmsc('GNUNET_CRYPTO_rsa_verify',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+var GCrsaSignatureFree = getEmsc('GNUNET_CRYPTO_rsa_signature_free',
+ 'void',
+ ['number']);
+
+var GChkdf = getEmsc('GNUNET_CRYPTO_hkdf',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var TWRALLgenKeyFromBlob = getEmsc('TALER_WRALL_gen_key_from_blob',
+ 'number',
+ ['string',
+ 'number',
+ 'number']);
+
+var DWRtestString = getEmsc('DEBUG_WR_test_string',
+ 'void',
+ ['number',
+ 'number',
+ 'string']);
+
+var GCsymmetricDecrypt = getEmsc('GNUNET_CRYPTO_symmetric_decrypt',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+var GCsymmetricEncrypt = getEmsc('GNUNET_CRYPTO_symmetric_encrypt',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number',
+ 'number']);
+
+/* returns a pointer to a symmetric session key strucure and takes a salt, a
+ (pointer to) binary data used to generate the key, and the length of that
+ data */
+var TWRALLgenSymmetricKey = getEmsc('TALER_WRALL_gen_symmetric_key',
+ 'number',
+ ['string',
+ 'number',
+ 'number']);
+
+/* returns a pointer to a init. vector strucure and takes a salt, a
+ (pointer to) binary data used to generate the key, and the length of that
+ data */
+var TWRALLgenInitVector = getEmsc('TALER_WRALL_gen_init_vector',
+ 'number',
+ ['string',
+ 'number',
+ 'number']);
+
+// return key material from ECC keys
+var GCeccEcdh = getEmsc('GNUNET_CRYPTO_ecc_ecdh',
+ 'number',
+ ['number',
+ 'number',
+ 'number']);
+
+// return a pointer to a freshly allocated EddsaPublicKey structure
+/* var WRALLeddsaPublicKey = getEmsc('WRALL_eddsa_public_key',
+ 'number'); */
+
+// return a pointer to a freshly allocated EcdhePublicKey structure
+/* var WRALLecdhePublicKey = getEmsc('WRALL_ecdhe_public_key',
+ 'number'); */
+
+/* generates a new eddsa private key, returning a pointer to EddsaPrivateKey
+ structure */
+var GCALLeddsaKeyCreate = getEmsc('GNUNET_CRYPTO_eddsa_key_create',
+ 'number');
+
+/* extract eddsa public key from a pointer to a EddsaPrivateKey structure
+ and put it in second argument */
+var GCeddsaKeyGetPublic = getEmsc('GNUNET_CRYPTO_eddsa_key_get_public',
+ 'void',
+ ['number',
+ 'number']);
+
+/* generates a new ecdhe private key, returning a pointer to EcdhePrivateKey
+ structure */
+var GCALLecdheKeyCreate = getEmsc('GNUNET_CRYPTO_ecdhe_key_create',
+ 'number');
+
+/* extract eddsa public key from a pointer to a EddsaPrivateKey structure and
+ put it in second argument */
+var GCecdheKeyGetPublic = getEmsc('GNUNET_CRYPTO_ecdhe_key_get_public',
+ 'void',
+ ['number',
+ 'number']);
+
+// what to sign, the reason to sign, the location to store the signature
+var GCeddsaSign = getEmsc('GNUNET_CRYPTO_eddsa_sign',
+ 'int',
+ ['number',
+ 'number',
+ 'number']);
+
+/* get reference to the emscripted primitive: the first parameter is a
+ pointer (note that it points to the emscripten's heap) to the data being
+ encoded, the second is its length */
+var GSALLdataToStringAlloc = getEmsc('GNUNET_STRINGS_data_to_string_alloc',
+ 'number',
+ ['number',
+ 'number']);
+
+// import GNUnet's memory deallocator
+var TWRgnunetFree = getEmsc('TALER_WR_GNUNET_free',
+ 'void',
+ ['number']);
+
+// GNUnet's base32 decoder
+var GSstringToData = getEmsc('GNUNET_STRINGS_string_to_data',
+ 'number',
+ ['number',
+ 'number',
+ 'number',
+ 'number']);
+
+// get absolute time. Returned value has to be freed by gnunetFree
+var TWRALLgetCurrentTime = getEmsc('TALER_WRALL_get_current_time',
+ 'number');
+
+// prettyfy time
+var TWRgetFancyTime = getEmsc('TALER_WR_get_fancy_time',
+ 'string',
+ ['number']);
+
+var TWRALLhash = getEmsc('TALER_WRALL_hash',
+ 'number',
+ ['number',
+ 'number']);
+
+/* computes the hashcode of the value pointed to by 'val' and sets the
+ pointer to the location holding the hashcode (which has to be previously
+ allocated and is a reflection of GNUNET_HashCode type). The returned
+ pointer has to be freed by gnunetFree.
+ Its interface is hash('val', 'valSize', 'hashedBuf') */
+var GChash = getEmsc('GNUNET_CRYPTO_hash',
+ 'void',
+ ['number',
+ 'number',
+ 'number']);
+
+/* this test just takes the private key to sign a dummy hardcoded
+ message. Return a pointer to the signed message (to be freed) */
+var TWRALLsignTest = getEmsc('TALER_WRALL_sign_test',
+ 'number',
+ ['number']);
+
+/* this test just takes the public key and the signed dummy
+ message. Return GNUNET_OK (=1) if it succeeds, otherwise
+ GNUNET_SYSERR (=-1) */
+var WRverifyTest = getEmsc('WR_verify_test',
+ 'number',
+ ['number']);
diff --git a/extension/background/libwrapper.js b/extension/background/libwrapper.js
new file mode 120000
index 000000000..8a9ac8e9a
--- /dev/null
+++ b/extension/background/libwrapper.js
@@ -0,0 +1 @@
+../../../wallet_button/firefox_src/content/lib/libWrapper.jsm \ No newline at end of file
diff --git a/extension/background/wallet.js b/extension/background/wallet.js
index ec7b3fb40..c6fbb5780 100644
--- a/extension/background/wallet.js
+++ b/extension/background/wallet.js
@@ -1,8 +1,40 @@
-// Nothing here yet.
-// Eventually, the backend for the wallet will be implemented here.
-
'use strict';
//chrome.browserAction.setBadgeBackgroundColor({color: "#000"})
chrome.browserAction.setBadgeText({text: "42"})
chrome.browserAction.setTitle({title: "Taler: 42 EUR"})
+
+function test_emscripten ()
+{
+ var cur_time = TWRALLgetCurrentTime();
+ var fancy_time = TWRgetFancyTime(cur_time);
+ console.log('current time: '+ fancy_time);
+}
+
+test_emscripten();
+
+DB.open(function () {
+ console.log ("DB: ready");
+});
+
+chrome.runtime.onMessage.addListener(
+ function (req, sender, onresponse) {
+ console.log("Message: " + req.type +
+ (sender.tab
+ ? " from a content script: "+ sender.tab.url
+ : " from the extension"));
+ switch (req.type)
+ {
+ case "WALLET_GET":
+ DB.wallet_get (onresponse);
+ break;
+
+ case "TRANSACTION_LIST":
+ DB.transaction_list (onresponse);
+ break;
+
+ case "RESERVE_LIST":
+ DB.reserve_list (onresponse);
+ break;
+ }
+ });
diff --git a/extension/lib/util.js b/extension/lib/util.js
new file mode 100644
index 000000000..9d83f7e74
--- /dev/null
+++ b/extension/lib/util.js
@@ -0,0 +1,91 @@
+'use strict';
+
+/**
+ * Format amount as String.
+ *
+ * @param amount
+ * Amount to be formatted.
+ *
+ * @return String, e.g. "1.23"
+ */
+function amount_format (amount)
+{
+ let separator = "." // FIXME: depends on locale
+ return amount.value + separator + amount.fraction.toString().replace(/0+$/, "");
+}
+
+
+/**
+ * Format amount with currency as String.
+ *
+ * @param amount
+ * Amount to be formatted.
+ *
+ * @return String, e.g. "1.23 EUR"
+ */
+function amount_format_currency (amount)
+{
+ return amount_format(amount) + " " + amount.currency;
+}
+
+
+/**
+ * Convert Date to String.
+ *
+ * Format: YYYY-MM-DD HH:mm
+ *
+ * @param date
+ * Date to be converted.
+ *
+ * @return String
+ */
+function date_format (date)
+{
+ function pad (number) {
+ if (number < 10) {
+ return '0' + number;
+ }
+ return number;
+ }
+
+ return date.getUTCFullYear() +
+ '-' + pad(date.getUTCMonth() + 1) +
+ '-' + pad(date.getUTCDate()) +
+ ' ' + pad(date.getUTCHours()) +
+ ':' + pad(date.getUTCMinutes());
+ //':' + pad(date.getUTCSeconds());
+}
+
+
+/**
+ * Send HTTP request.
+ *
+ * @param method
+ * HTTP method.
+ * @param url
+ * URL to send to.
+ * @param content
+ * Content of request.
+ * @param content_type
+ * Content-Type HTTP header.
+ * @param onsuccess
+ * Function called by XMLHttpRequest on success.
+ * @param onerror
+ * Function called by XMLHttpRequest on error.
+ *
+ */
+function http_req (method, url, content, content_type, onsuccess, onerror) {
+ var req = new XMLHttpRequest();
+
+ req.onload = function(mintEvt) {
+ if (req.readyState == 4)
+ onsuccess(req.status, req.responseText);
+ };
+
+ req.onerror = onerror;
+ req.open(method, url, true);
+ req.setRequestHeader('Content-Type', content_type);
+ req.send(content);
+
+ return req;
+}
diff --git a/extension/manifest.json b/extension/manifest.json
index 1d0ad6d55..b253c2484 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -21,11 +21,6 @@
"default_popup": "popup/wallet.html"
},
- "web_accessible_resources": [
- "popup/reserves.html",
- "popup/wallet.html"
- ],
-
"content_scripts": [
{
"matches": ["*://*/*"],
@@ -35,7 +30,14 @@
],
"background": {
- "scripts": ["background/wallet.js"]
- }
+ "scripts": [
+ "lib/util.js",
+ "background/libwrapper.js",
+ "background/emscriptif.js",
+ "background/db.js",
+ "background/wallet.js"
+ ]
+ },
+ "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}
diff --git a/extension/popup/transactions.html b/extension/popup/transactions.html
index 2dc3fbea0..f51f64cf0 100644
--- a/extension/popup/transactions.html
+++ b/extension/popup/transactions.html
@@ -4,6 +4,7 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="popup.css" type="text/css">
+ <script src="../lib/util.js" type="text/javascript"></script>
<script src="transactions.js" type="text/javascript"></script>
</head>
diff --git a/extension/popup/transactions.js b/extension/popup/transactions.js
index 7d38d3b36..fbd578114 100644
--- a/extension/popup/transactions.js
+++ b/extension/popup/transactions.js
@@ -1,22 +1,5 @@
'use strict';
-function format_date (date)
-{
- function pad (number) {
- if (number < 10) {
- return '0' + number;
- }
- return number;
- }
-
- return date.getUTCFullYear() +
- '-' + pad(date.getUTCMonth() + 1) +
- '-' + pad(date.getUTCDate()) +
- ' ' + pad(date.getUTCHours()) +
- ':' + pad(date.getUTCMinutes());
- //':' + pad(date.getUTCSeconds());
-}
-
function add_transaction (date, currency, amount, status, contract)
{
let table = document.getElementById('transactions-table');
@@ -26,7 +9,7 @@ function add_transaction (date, currency, amount, status, contract)
let td_date = document.createElement('td');
td_date.className = 'date';
- let text_date = document.createTextNode(format_date (date));
+ let text_date = document.createTextNode(date_format (date));
tr.appendChild(td_date).appendChild(text_date);
let td_amount = document.createElement('td');
diff --git a/extension/popup/wallet.html b/extension/popup/wallet.html
index a6864896b..42d72e676 100644
--- a/extension/popup/wallet.html
+++ b/extension/popup/wallet.html
@@ -4,6 +4,7 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="popup.css" type="text/css">
+ <script src="../lib/util.js" type="text/javascript"></script>
<script src="wallet.js" type="text/javascript"></script>
</head>
diff --git a/extension/popup/wallet.js b/extension/popup/wallet.js
index cb7399dac..c148abc85 100644
--- a/extension/popup/wallet.js
+++ b/extension/popup/wallet.js
@@ -28,8 +28,13 @@ function select_currency (checkbox, currency, amount)
function add_currency (currency, amount)
{
+ let empty = document.getElementById('wallet-empty');
+ if (! /\bhidden\b/.test(empty.className))
+ empty.className += ' hidden';
+
let table = document.getElementById('wallet-table');
table.className = table.className.replace(/\bhidden\b/, '');
+
let tr = document.createElement('tr');
tr.id = 'wallet-table-'+ currency;
table.appendChild(tr);
@@ -73,13 +78,20 @@ function update_currency (currency, amount)
checkbox._amount = amount;
}
-document.addEventListener('DOMContentLoaded', function () {
- let empty = document.getElementById('wallet-empty');
+document.addEventListener(
+ 'DOMContentLoaded',
+ function () {
+ chrome.runtime.sendMessage({type: "WALLET_GET"}, function(wallet) {
+ for (let currency in wallet)
+ {
+ let amount = amount_format(wallet[currency]);
+ add_currency(currency, amount);
+ }
+ });
- // FIXME
- empty.className += ' hidden';
- add_currency('EUR', 42);
- add_currency('USD', 17);
- add_currency('KUD', 1337);
- update_currency('USD', 23);
-});
+ // FIXME: remove
+ add_currency('EUR', 42);
+ add_currency('USD', 17);
+ add_currency('KUD', 1337);
+ update_currency('USD', 23);
+ });