WebExtensions Wallet

Introduction

The WebExtensions Wallet (wxwallet) can be used to pay with GNU Taler on web sites from within modern web browsers. The WebExtensions API enables the development of cross-browser extensions. Google Chrome / Chromium, Mozilla Firefox, Opera and Microsoft Edge will all offer support for WebExtensions and thus be able to support Taler.

Currently Chrome hast the best support for WebExtensions (since the API is a superset of Chrome’s extension API).

Development Environment

The wxwallet mainly written in the TypeScript language, which is a statically typed superset of JavaScript.

While the wxwallet is mainly intended to be run from inside a browser, the logic is implemented in browser-independent modules that can also be called from other environments such as nodejs. This is especially useful for automatically running unit tests.

Project Structure

manifest.json               extension configuration
package.json                node.js package configuration
tsconfig.json               TypeScript compiler configuration
gulpfile.js                 Build tasks script
lib/
    vendor/                 3rd party libraries
    wallet/                 actual application logic
    emscripten/             emscripten object file and glue
test/
     run_tests.js           nodejs entry point for tests
     tests/                 test cases
content_scripts/notify.ts   wallet<->website signaling
backgrond/main.ts           backend entry point
img/                        static image resources
style/                      CSS stylesheets
pages/                      pages shown in browser tabs
popup/                      pages shown the extension popup

Building the Wallet

To build the extension for use during development, simply run the TypeScript compiler from the extension directory:

$ cd wallet.git/wallet_webextension/extension/
$ tsc

This will use the tsconfig.json with development options such as source map support.

When TypeScript source files are added or deleted to the project, make sure that the globs in gulpfile.js match them so that they will be compiled. The tsconfig.json is generated by running:

$ gulp tsconfig

Caution

Do not edit the tsconfig.json manually. The source files should be defined in one place, and that is gulpfile.js.

To pack the extension in a format that can be uploaded to the Google Webstore, run:

$ gulp package

This will build the wallet without source maps, copy resource files (which also need to be specified in gulpfile.js) and create an archive.

Emscripten

Emscripten is C/C++ to JavaScript compiler. Emscripten is used in the wxwallet to access low-level cryptography from libgcrypt, and miscellaneous functionality from libgnunetutil and libtalerwallet.

TODO: say things about wrappers

Target Environments and Modularization

Modules in the wallet are declared in TypeScript with the ES6 module syntax. These modules are then compiled to SystemJS register modules.

SystemJS modules can be loaded from the browser as well as from nodejs. However they require special entry points that configure the module system, load modules and execute code. Examples are backgrond/main.ts for the browser and test/run_tests.js for nodejs.

Note that special care has to be taken when loading the Emscript code, as it is not compatible with the SystemJS module, even in the globals compatibility mode.

The TypeScript sources in the wxwallet are compiled down to ES5, both to enable running in node.js without transpilers and to avoid a bug in the TypeScript compiler.

IndexedDB Query Abstractions

The wxwallet uses a fluent-style API for queries on IndexedDB.

TODO: say more about this

Testing

Test cases for the wallet are written in TypeScript and run with mochajs and the better-assert assertion library.

Run the default test suite with npm run test, which will call mocha with the right parameters.

Internationalisation

Strings in the JavaScript code are internationalised using the following functions:

  • i18n: translate string with arbitrary arguments, the result is returned as string.
i18n`You have ${n} coins.`
  • i18n.parts: Interpolate i18nized values with arbitrary objects. Useful for example to include HTML elements.
i18n.parts`Visit ${link} to get more coins.`
  • i18n.pluralize: translate with plural form. The i18n.number() function returns a PluralNumber object that specifies the argument that determines the plural form, if not present the first numeric argument is used.
i18n.pluralize(
  i18n`${i}: you have ${i18n.number(n)} coin.`,
      `${i}: you have ${i18n.number(n)} coins.`);

These functions are defined in lib/i18n.ts. Include lib/vendor/jed.js, lib/i18n.js, lib/i18n-strings.js to use them.

To extract strings from sources and update the .po files, run:

$ make i18n

In static HTML files the lang attribute is used for language-specific strings:

<p lang="en">Hello World!</p>
<p lang="de">Hallo Welt!</p>

lib/i18n.js and style/lang.css needs to be included for this to work.